Subject: /dev/clock pseudodevice
To: None <firstname.lastname@example.org>
From: Emmanuel Dreyfus <email@example.com>
Date: 07/28/2001 23:47:02
We recently had a security issue with xntpd, the problem led to a root
compromise because xntpd is run as root.
I thought running xntpd as a non root user would be nice, because it
would prevent any new serious problems with it. xntpd needs to be root
to open a <1024 port and to call various time related syscalls
(settimeofday, adjtime). Opening the <1024 port is not a problem, we can
drop privileges just after opening it.
The problem is setting time without running with root privileges. I've
written a small pseudodevice driver to address this problem. It's called
/dev/clock. /dev/clock has an ioctl to do settimeofday without being
root. The principle is that if you can write to /dev/clock, then you can
do settimeofday. The system administrator can hence choose what
user/group is allowed to change time on the system.
I made a modification to libc, so that when a process calls
settimeofday(), /dev/clock is used if possible (it exists and you have
write access to it), and the settimeofday() system call is used if not.
With this, we can have an xntpd running under a non root UID in a chroot
jail. The modification to xntpd are minimal (just add flags to
setuid/setgid/chroot after the ntp port is open), and it's even possible
to do it on an unmodified xntpd (listen on a >1024 port, and redirect
ntp port using ipnat)
If the kernel was build without the pseudodevice, or if /dev/clock was
not created, everything works exactly like it does now, because the libc
revert to calling settimeofday.
Currently, the pseudodevice only implements settimeofday, I'll add
adjtime and setclock.
I also wonder if it could be intersting to mmap the struct timeval into
the process space using /dev/clock. This way, we loose 4kB of memory
(because there should not be other things than struct timeval in the
page), but we can modify gettimeofday so that it has to do a mmap on the
first time, and no system call later. We have some programs that are
calling gettimeofday hundred of times per seconds, and I wonder if we
could get an interesting performance increase there.
Opinions on this later point?
UNIX *is* user friendly. It is just a bit selective about his friends