David A. Harding
Thursday, 06 Jul 2006
Until Yesterday, I never thought about how init (PID 1) received messages from it's children (everything else on the system, besides the kernel).
My investigation started on LUG/IP's freenode IRC channel,
#lug/ip.
Two different commands were listed on how to get init (PID 1) to reread
it's configuration file. Command one is: kill -SIGHUP 1.
Command two is: (tel)init q. Keen to prove my
unix prowness, I typed the following into my IRC client's buffer: ``init
q just sends a SIGHUP to PID 1.'' But before I hit the send key, I
decided to check my statement with a quick strace:
sudo strace -ofoo init q
What I saw told me I was wrong (edited for length):
open("/dev/initctl", O_WRONLY) = 3
write(3, "i\31\t\3\1\0\0\0q\0\0\0\5\0\0"..., 384) = 384
At this moment, someone else in the IRC chatroom posted the same thought that was in my buffer. I quickly cleared my buffer and took a little (possibly hyprocritical) pleasure in correcting them.
/dev/initctl is a named pipe created, opened, and used
by init (PID 1) for reading messages from it's children proccesses.
One thing I do whenever I make a desktop system for myself is SUID
/sbin/init. This way I can change runlevels without using
sudo. The advantage to not using sudo in this situation is important to
me: I remotely connect to my home server a lot using ssh, and if I use
the same command (sudo init 0) to turn of the server as the
desktops, I inevitably turn off the server.
If init (PID 1) is just reading from a named pipe, I should be able to change the permissons of the pipe and not the programs that write to it. Unfortunately this doesn't work with the sysvinit tools installed on Debian Sarge. Here is a sample permission setup:
harding@callisto:~$ ls -lh /sbin/init /dev/initctl prw--w--w- 1 root root 0 2006-07-06 12:09 /dev/initctl -rwxr-xr-x 1 root root 31K 2005-01-04 17:43 /sbin/init
And here is the result:
harding@callisto:~$ init 0 init: must be superuser
I'm not sure is this is a bug or an aberrant security tradeoff.