The problem is annoying, the fix is trivial.
I am not subscribed to the list, so PLEASE CC ME when replying.
Summary:
Magic SysRq behaves improperly with tErm and kIll in regards to how it
deals with init. killalL is fine (ignoring the 0x8000 "Ugly hack" :)
Description:
When you use these features of SysRq, the kernel is supposed to send a
signal to all processes except init. Well in reality the kernel sends a
signal to "all" processes including init. The reason nobody has ever
noticed this is that sysvinit doesn't do anything on SIGTERM, and the
kernel won't kill pid 1.
Affected kernels:
All current. This is present in both 2.2.19 and 2.4.6-pre1 kernels. I
didn't check 2.0.x, but i believe 2.0.x lacked the magic sysrq hack
anyway.
$Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $
Solution:
drivers/char/sysrq.c
send_sig_all()
line 47 in 2.4.6-pre1
// -- Evil code --
for_each_task(p) {
if (p->mm) { /* Not swapper nor kernel thread */
if (p->pid == 1 && even_init) /* Ugly hack to kill init */
p->pid = 0x8000;
force_sig(sig, p);
}
}
// --end--
So what happens is if send_sig_all is supposed to kill init then p->pid is
set to 0x8000. This is bad, but it works fine so who really cares. Now,
if even_init is 0 (like with tErm and kIll), p->pid is still 1 when
force_sig() is called. If p->pid is 1 and even_init is 0, nothing should
be done.
// -- Fixed code --
for_each_task(p) {
if (p->mm) { /* Not swapper nor kernel thread */
if (p->pid == 1 && even_init) /* Ugly hack to kill init */
p->pid = 0x8000;
if (p->pid != 1)
force_sig(sig, p);
}
}
// --end--
Amazing what 1 line of code fixes, isn't it?
How the problem was found:
The busybox (busybox.lineo.com) init reboots when it sees SIGTERM :).
Since this is a 1 line fix I'd like to see it go into the kernel soon,
maybe even for the 2.4.6-pre2 kernel. I don't want to sound
like a jerk, but it would be cool if I was listed at the top of
sysrq.c for submitting a bugfix or something =].
Remember to cc me when replying.
Thanks,
Adam Slattery
Sunrise Linux Development Team
aslattery@sunriselinux.com
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/