syscalls & mcontext

Christian Kandeler christian.kandeler at hob.de
Wed Apr 23 12:45:44 UTC 2008


Hi,
 
during testing of a FreeBSD/IA64 application I had written I noticed 
that it kept getting a SIGILL signal seemingly out of nowhere. On 
closer inspection, I found out that the following happens:
	- The library calls the kse_switchin syscall.
	- The kernel's kse_switchin() function is called with the second 
argument == address of trapframe + 0xe8, as set up by epc_syscall.
	- The kse_switchin() function calls set_mcontext(), which, among 
other things, sets tf->tf_scratch = mc->mc_scratch. But 
tf->tf_scratch overlaps the second argument of kse_switchin(), so now 
uap->tmbx in kse_switchin() is no longer a pointer to the thread 
mailbox, but some random value (whatever was in mc_scratch.gr16).
	- After set_mcontext() has returned, kse_switchin() sets 
td->td_mailbox = uap->tmbx, i.e. the bogus value is now copied into 
the thread structure.
	- ...
	- The thread_export_context() function tries to copy the thread's 
mailbox contents, chokes on the bogus pointer and calls sigexit(), 
which results in the SIGILL signal being sent to the process.

Any idea of what is going wrong here? My first, uneducated guess would 
be that we shouldn't set tf_scratch (because why does a synchronous 
interruption need to restore the scratch registers), but my insight 
into the syscall mechanism is rather superficial and I assume the 
problem is more complex than that. 

Regards,
Christian Kandeler

PS: Kernel version is 6.1.


More information about the freebsd-ia64 mailing list