Re: Kernel bug in handling signals (bug 15615281)
Re: Kernel bug in handling signals (bug 15615281)
- Subject: Re: Kernel bug in handling signals (bug 15615281)
- From: Eric Grant <email@hidden>
- Date: Fri, 20 Dec 2013 18:03:37 -0800
Ben,
I agree that your user-space code should not be able to crash the kernel. In that regard, it appears that you've identified a bug.
That said, you *are* misusing the syscall. If you look at the source for sigaction in Libc on 10.9.0, <http://www.opensource.apple.com/source/Libc/Libc-997.1.1/sys/sigaction.c>, you will see that sigaction substitutes "our signal trampoline" for your signal handler before calling through to __sigaction. That routine is a stub found (in 10.7.5 at least) in /usr/lib/system/libsystem_kernel.dylib. It looks like this (again, in 10.7.5):
___sigaction:
00018dd8 movl $0xc002e, êx // 46, but with bits 18-19 set as well
00018ddd calll __sysenter_trap
00018de2 jae 0x18df2
00018de4 calll 0x18de9
00018de9 popl íx
00018dea movl 25139(íx), íx
00018df0 jmpl *íx
00018df2 ret
__sysenter_trap:
0001a49a popl íx
0001a49b movl %esp, ìx
0001a49d sysenter
For what it's worth, you can also look at the kernel's handler for sigaction, <http://www.opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_sig.c>. That might give you a clue as to why the panic depends on the 64-bitness of the forking shell.
Why not use just use Libc? You don't have to call it from C code, so there's no reason you can't call it from your Virgil (pseudo-)assembly.
Just to add one more thing to the mix. You might want to check out "Mach exception handlers." See, e.g., <https://www.mikeash.com/pyblog/friday-qa-2013-01-11-mach-exception-handlers.html>.
Good luck,
Eric
On Dec 19, 2013, at 19:27:31 +0100, "Ben L. Titzer" <email@hidden> wrote:
Well I supposed you passed the of first test of trust :)
Although you might not like the source code--none of it is written in C :)
Checkout the repository here:
https://code.google.com/p/virgil/
The binary in question is generated by my compiler from the test
program in test/execute/rtex_divzero06.v3
% bin/v3c -target=x86-darwin-test -output=/tmp/ test/execute/rtex_divzero06.v3
There is some assembly language linkage that is generated by the
compiler itself that sets up the default signal handlers. That
assembly is generated in
https://code.google.com/p/virgil/source/browse/aeneas/src/x86/X86Darwin.v3
in genSignalHandlerInstall()
That code is basically:
// generate code that installs a signal handler
def genSigHandlerInstall(asm: X86Assembler, signo: int, handler: Addr) {
asm.push_i(0); // sa_flags
asm.push_i(0); // sa_mask
asm.push_i(X86Addrs.ABS_CONST); // sa_handler: handler address
recordPatch(asm, handler);
asm.push_i(2); // TODO: why a nonzero value here?
asm.movd_rm_r(X86Regs.EBX, X86Regs.ESP);
asm.push_i(0); // sigaction *oact
asm.push(X86Regs.EBX); // sigaction *act
asm.push_i(signo); // signal number
asm.push_i(0); // "dummy" value
asm.movd_rm_i(X86Regs.EAX, 46); // sigaction
asm.intK(0x80);
asm.add.rm_i(X86Regs.ESP, 32); // pop params off stack
}
As you can see there is some hackery going on there. I wasn't exactly
sure what I should be passing to the kernel, since it has been a pain
to trace through exactly how all the structs are encoded. This all
works fine on 10.6. I use the signal handlers to catch access
violations (e.g. a null pointer deref by the program generates a
SIGSEGV, by design of my address layout), and then generate a
stacktrace.
Perhaps I am misusing the syscall. But still, I should *not* be able
to crash the kernel, and the behavior certainly shouldn't depend on
the 64-bitness of the forking shell (!). As noted above, when forked
from a 32-bit shell, then it all works as expected.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden