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