LockerGnomeTech news and nostalgia for today's technology professionals
Subscribe

Search

SecurityLinuxkernelsignals

A developer patched the Linux kernel so ordinary programs can block and handle SIGKILL

The write-up shows the kernel's two untouchable signals are protected by a handful of explicit checks, and that removing them behind a config switch broke nothing.

Against a spinning target board Chris catches a thrown dagger with both hands
Illustration: LockerGnome

Every Unix user eventually learns the nuclear option: kill -9. It sends SIGKILL, and no program can refuse it. Developer lymkwi asked the obvious question in a blog post: what if one could?

SIGKILL ends a process immediately and messily, and SIGSTOP freezes it until a SIGCONT arrives. They are the only two signals a program can’t block, ignore or handle, and the post, written by lymkwi on VulpineCitrus, set out to find what actually enforces that. The answer is a few explicit checks in the kernel’s signal code, mostly in kernel/signal.c.

When a program tries to block signals through rt_sigprocmask, the kernel first strips SIGKILL and SIGSTOP from the request with a call to sigdelsetmask. When it tries to install a handler with rt_sigaction, do_sigaction rejects the attempt with an error if sig_kernel_only says the signal is one of the two. Lymkwi’s patch wraps those exclusions in a new build option, CONFIG_KILL_STOP_HANDLING, tucked under Kernel Hacking. The option’s help text adds a plain “If unsure, say N.”

The change touches the mask path, the handler path (by setting the kernel-only mask to zero), the compatibility version of the mask syscall, a helper called set_current_blocked, and the syscall that waits for signals. The post is clear about its limits: ptrace, strace and signalfd were not examined, so “by all means, my patches are not complete.”

Then came the test. The first boot went wrong; the second, “nothing happened. Nothing dramatically exploded, nothing stopped.” The kernel reported itself as 6.13.0-killstop-dirty. A short C program installed handlers for SIGINT, SIGKILL, SIGSEGV, SIGTERM and SIGSTOP, then printed the commands to try to kill it, leaving SIGUSR1 and SIGHUP as an escape hatch. Its handler answered each attempt with a cutesy message; for SIGKILL it said “you tried to SIGKILL me~ teehee~.” The result, lymkwi writes, was a process “conventional means of killing a program are completely ineffective against” it.

Nothing about this is a new vulnerability. It’s a kernel the author built from source with a switch turned on. The more useful result is the map: lymkwi’s conclusion is that the rules everyone takes for granted “are just set somewhere in code.”

The post’s lesson is for anyone who has assumed a limit was physics. Sometimes a limit is just a few lines somebody wrote and nobody wanted to touch. The next kernel hacker reading kernel/signal.c may find a few more.

Teehee, indeed.

More Security

Every Security story →