Page 4 of 4
Re: Critical sections in userspace without syscalls?
Posted: Mon Jan 07, 2013 5:58 am
by rdos
tjmonk15 wrote:If it wasn't an issue, why did you suddenly update us with how you "fixed" it?
- Monk
It wasn't a fix. Merely a design-idea of how it could be solved in long mode without breaking protected mode.
Re: Critical sections in userspace without syscalls?
Posted: Mon Jan 07, 2013 7:01 am
by Combuster
Feel free to keep dreaming
Re: Critical sections in userspace without syscalls?
Posted: Mon Jan 07, 2013 7:08 am
by rdos
Combuster wrote:Feel free to keep dreaming
OK, go on to find the fix
Reference kernel code:
http://www.rdos.net/svn/trunk/kernel/os/task.asm
Sections using the owner field:
Code: Select all
acquire_take:
push es
mov es,fs:ps_curr_thread
mov ax,es:p_futex_id
pop es
mov es:[esi].fs_owner,ax
mov es:[esi].fs_counter,1
and:
Code: Select all
push es
push esi
lea esi,ds:[ebx].fh_list
call RemoveBlock32
mov es:p_data,0
mov cx,es
mov di,es:p_futex_id
pop esi
pop es
;
mov es:[esi].fs_owner,di
mov es:[esi].fs_counter,1
Does anybody see it being used by kernel?
Re: Critical sections in userspace without syscalls?
Posted: Mon Jan 07, 2013 11:45 pm
by Gigasoft
In my OS, semaphores look like this right now:
Code: Select all
No waiters:
cccc cccc cccc cccm mmmm mmmm mmmm mm01
c = Count
m = Maximum
Waiting (user mode semaphore):
iiii iiii iiii iiit tttt tttt tttt tt00
i = Semaphore index
t = Thread handle
Waiting (kernel mode semaphore):
pppp pppp pppp pppp pppp pppp pppp pp00
p = Pointer to wait block
For a semaphore that has a maximum count of 1 and is normally not held, special cased functions AcquireMutex and ReleaseMutex exist that can be called in user mode. These perform a cmpxchg to change 0x20005 into 5 or vice versa, and call the generic kernel mode WaitEvents and SignalSemaphore functions if this fails. The kernel then takes cares of everything. No hash maps or complicated user mode retry loops are required, and the handle is already created at thread initialization. The downside is that user mode semaphores are only valid within the same process. I'm still not sure of how to extend this to multiple processes, but it might be possible by using system wide thread IDs instead of thread handles, and verifying that the physical address of the semaphore matches up with what it should be when the thread belongs to another process. This should ensure that you can't tamper with the operation of a thread that is not actually waiting for what you're claiming.