Question

I know /sbin/init has special protection against SIGKILL and SIGSTOP from kernel for obvious reasons.

I have tried telling kernel I want to receive SIGSTOP with ioctl() (similar to SIGABRT and SIGSEGV reqs in main()):

if (ioctl (0, KDSIGACCEPT, SIGSTOP) == 0) {
    nih_signal_set_handler (SIGSTOP, stop_handler);

but STOP doesn't arrive to the stop_handler() (from all I know, as nih_error() isn't printed in logs).

In stop_handler(), I'm resetting the STOP sighandler to SIG_DFL (otherwise it would come back to our handler anyways), but this probably leads it being ignored by the kernel again.

How do I tell kernel I want to have init STOPPED?

Was it helpful?

Solution

You'd need to take the SIGNAL_UNKILLABLE flag out of its task struct's signal_struct's flags.

By default (i.e. always on unmodified Linux systems) SIGNAL_UNKILLABLE flag is set on init's signal_struct flags.

You could write a kernel module which would poke init's task struct to change it, then you'd be able to send a stop signal to init.

Sending a stop signal to init is a very bad idea though, as zombies would rapidly proliferate if init wasn't reaping them any more.


Clarification: This is an in-kernel struct and not part of init's source, nor is it accessible or visible from userspace. To change it you'd need to write some kernel code or patch the kernel. It would be fairly trivial, I imagine, to write a kernel module which just hacks it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top