I suggest the following feature for Linux kernel: We could allow chroot() not only for root (uid==0) processes, but also for any process which has LD_PRELOAD environment variable set to a non-empty string.
The idea is: If LD_PRELOAD variable is set then the security (of a SUID executable is already compromised. (For example, with LD_PRELOAD chroot() can be imitated; and anything other can be done.) That is if somebody (e.g. a hacker) has succeed to set LD_PRELOAD for a SUID executable, he has already brake the system and there are no reason to attempt to protect anymore. (Recent version of Glibc ensure that LD_PRELOAD is reset for SUID executables.)
As such there are no reason to disallow chroot when LD_PRELOAD is set. (Well, we also need to ensure that the system itself (e.g. Glibc) does not set LD_PRELOAD; I do not warrant that some version of Glibc could not set LD_PRELOAD for every process, however deem this almost improbable, need to check for sure...)
For security reasons a non-root process which (or whose ancestor process) has successfully done chroot() should be after this disallowed to execute anything SUID (anything I say here about SUID also apply to SGID executables). Or better, for SUID processes which are descendants of our (non-root) process the root dir should be reset to the real root (or if a chroot() was executed by its root ancestor process, then to that root chrooted root instead!)
So I could probably suggest to add the following Linux kernel compile option: Allow chroot for non-root if LD_PRELOAD is set.
As I have said above, chroot() can be imitated with LD_PRELOAD (e.g. the fakechroot package), so one can argue that there are no reason to add this into Linux kernel, as this anyway can be done with LD_PRELOAD. But:
LD_PRELOAD may miss new syscalls in new kernel versions.) Reliability may be probably important here as chroot() is related with security issues.There are also arguments against implementing kernel side chroot() for non-root users:
LD_PRELOAD is specific for Glibc (and compatible libraries that is probably most libc libraries of most vendors), and adding this to kernel would be a logical dependency of kernel from libc what may be considered as the reverse of the normal things. Moreover using kernel having this feature together with an other dynamic loader than ld.so from Glibc not having LD_PRELOAD feature and software which is not safe in regard of LD_PRELOAD (so being not safe with Glibc but probably safe with some other C library), could be a security compromise. (This security compromise would compromise only such software which can be also compromised by LD_PRELOAD.)LD_PRELOAD value would a little increase the size of the kernel. (This can be done an optionally compiled-in feature however.)Why I at all worry about efficient chroot() for non-root users? Because now user-lever virtual filesystems (e.g. FUSE) enter into our wide usage. chroot together with virtual filesystems is quite useful for users.
Finally, probably chroot() is not the only root-only system call which could be allowed also to non-root processes having set LD_PRELOAD. Which syscalls likewise would be enabled if LD_PRELOAD is set? You can comment here.
No Comments/Trackbacks/Pingbacks for this post yet...
Recently ||