[radvd-devel-l] [RFC] Add privilege separation capability on
jim at jtan.com
Thu Jan 24 11:33:24 EST 2008
Pekka Savola wrote:
>> - The communication with the pipe is one-way to keep things simple.
>> There's therefore no error indication if the writes fail. Maybe
>> another pipe could be set up in the reverse direction (deadlocks
>> could be an issue), or the unprivileged code could wait a second and
>> read-back the /proc file to see if it's changed. Or the priviliged
>> code could log it, but I wanted to keep that loop as straightforward
>> as possible.
> Syslog seems to work, but some other mechanisms (e.g. stderr with debugging
> mode, or file logging) may or may not work as well.
Stderr should probably work if privsep_init is changed to not close it
when debugging. But it's a question of how much complexity we want in
the root process anyway (even just the dlog/vlog/syslog path is a
pretty big increase on how much code is running as root).
> - it would be great if the master root process could be more confined as
> it currently basically needs to just write to proc and log if there are
> errors. But I'm not sure if there is an easy way to do that. I was
> thinking of Linux kernel capabilities (used e.g. by ntpd to allow adjusting
> the clock) but the controls are likely too coarse for this. (On second
> thought, if kernel capabilities would have been sufficient, we probably
> wouldn't even have needed the privsep to begin with.)
I agree, and I looked into capabilities a bit, but I think even if we
could reduce it to a set that says "this process can write root-owned
files", we're not gaining much in terms of security.
Another idea that I had would be to just open a filehandle to each of
the files we might need to modify, drop privs, then use
fprintf(fd, "%d\n", new-value);
every time we want to change them. For /proc/sys/net, that seems to
work fine in my tests. However, because the ifname is part of the
filename, we don't know prior to radvd.conf changes what to open.
So the support would be limited to only interfaces that were either
present in radvd.conf initially, or maybe all interfaces present at
startup. And we also lose the ability to sanity check the values.
But maybe the benefits (no second process, no privileges) are worth it?
> - due to code duplication, I removed privsep_set and replaced it with an
> improved version of set_interface_var. I'm not completely happy with code
> structure as it is (two different codepaths in two different files, when
> privsep is on/off, two different error messages; variable max/min checking
> only happens with privsep), but it's probably good enough.
It looks like you didn't get rid of privsep_set, uncommitted changes
maybe? I agree that the code structure is a bit messy, part of my
reasoning for duplicating rather than calling into existing code was
so that all of the priviliged stuff would be in one place and easy to
audit. With calls to dlog(), set_interface_var(), that's no longer
the case, and we'll have to remember that those are security-related
when editing them in the future.
More information about the radvd-devel-l