Hello,
the Fedora Project will need a buildsystem which features[1]:
Process separation: it MUST be impossible to kill or ptrace processes of other buildroots or of the system. Hiding of foreign processes SHOULD be provided.
Device/kernel protection: Direct hardware access through /dev/* entries or modification of kernel parameters through /proc MUST be impossible. Forbidding the creation of such special files is one way to reach it, access restriction another one.
Unbreakable chroots: it MUST be impossible for a process in a buildroot to have any kind of access on objects of the systems (e.g. ssh-keys), or write-access on other buildroots.
No buildroot-reusing: each build MUST happen in an environment which can not be influenced by previous builds in this environment. This includes both filesystem-objects, and processes.
Resource-restrictions: excessive resource-usage (memory, diskspace,...) of a build SHOULD be prevented. Usage of certain resources (e.g. network) MUST be prohibited
Good performance: the buildsystem SHOULD should have only a small or non-existing impact on the performance.
Working environment: building of common packages MUST succeed. This requires certain /dev entries, and a mounted /proc filesystem at least.
Mature userinterface: the system SHOULD assist the buildmaster and automate the most tasks, so that the spent time will be reduced to a minimum.
The reasons for these items and how they are solved in the current fedora.us buildsystem are described in
http://www.tu-chemnitz.de/~ensc/fedora.us-build/html [HTML], respectively http://www.tu-chemnitz.de/~ensc/fedora.us-build/files/buildsystem.pdf [PDF, 204 KiB]
The described buildsystem is in use for a short time only, but it seems to be secure and to work well (it was used in the rh9* -> fc1 mass-rebuild for the most packages). There were some cases which needed manual intervention (e.g. manual disttags), but these were exceptions.
A core part is a vserver[2] capable kernel. Unfortunately, it is not ported to the kernels which are shipped with Fedora yet, and chances are only low that it comes into the official 2.6 kernel.
Since Red Hat wants a selfhosting buildsystem, alternatives must be investigated. SELinux offers interesting features, but it is new and there are lot of open questions[3]:
1. SELinux can protect foreign processes. But is it possible to hide them in /proc also? 2. Is chroot(2) implemented in a safe manner? Or, can parent directories of build-roots be protected with SELinux policies? Is a safe chroot(2) required at all? 3. What is the performance impact of the policy checking? 4. How can disk/memory usage restricted with SELinux? Would CKRM be an option? 5. Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also? 6. Setup of an SELinux policy seems to be very complicated. How possible are holes in a setup?
It would be nice when an SELinux expert could take a look at this questions and how it can be used in the buildsystem.
UML might be another option, but its status (chances to come into official 2.6) and performance impact is not clear.
Enrico
Footnotes: [1] http://www.tu-chemnitz.de/~ensc/fedora.us-build/html/index.html#id2503177 [2] http://linux-vserver.org [3] http://www.tu-chemnitz.de/~ensc/fedora.us-build/html/ar01s02.html#sec:compon...
On Fri, 2003-11-28 at 00:31, Enrico Scholz wrote:
- SELinux can protect foreign processes. But is it possible to hide them in /proc also?
It is not currently possible to hide them. However, the entries in /proc have the same type as the domain of the running process. So if you don't allow any operations on that type (including getattr), then the only thing one can tell is that a process exists at that PID.
- Is chroot(2) implemented in a safe manner? Or, can parent directories of build-roots be protected with SELinux policies? Is a safe chroot(2) required at all?
Using SELinux, a chroot doesn't provide any additional direct security. However, you may find it convenient to use a chroot in this instance so that different sets of packages can be installed, etc.
- What is the performance impact of the policy checking?
Minimal; IIRC the overhead was something like 1-2% for very system-call intensive tasks, and negligible after that.
- How can disk/memory usage restricted with SELinux? Would CKRM be an option?
SELinux does not deal with resource restrictions.
- Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also?
The mount system call is restricted, yes.
- Setup of an SELinux policy seems to be very complicated. How possible are holes in a setup?
Assuming that there are no bugs in the kernel, it is impossible to reach sysadm_t (essentially equivalent to the SELinux "root") if the policy doesn't very explicitly permit it.
I hope that answers your questions!
walters@verbum.org (Colin Walters) writes:
- Is chroot(2) implemented in a safe manner? Or, can parent directories of build-roots be protected with SELinux policies? Is a safe chroot(2) required at all?
Using SELinux, a chroot doesn't provide any additional direct security. However, you may find it convenient to use a chroot in this instance so that different sets of packages can be installed, etc.
I am asking because of the following situation: there are two, (nearly) equal buildroots A & B in the directory tree like
<basedir> |- A `- B
Can it be prohibited that A modifies files within B?
Would it be possible to forbid any kind of access at <basedir> for buildprocesses?
- Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also?
The mount system call is restricted, yes.
We will have to deal with
mount -t proc none <buildroot>/proc vs. mount --bind trojan /bin/sh
The first command MUST be supported, but the second one (inclusive variants) be forbidden.
Enrico
On Mon, 2003-12-01 at 14:51, Enrico Scholz wrote:
walters@verbum.org (Colin Walters) writes:
- Is chroot(2) implemented in a safe manner? Or, can parent directories of build-roots be protected with SELinux policies? Is a safe chroot(2) required at all?
Using SELinux, a chroot doesn't provide any additional direct security. However, you may find it convenient to use a chroot in this instance so that different sets of packages can be installed, etc.
I am asking because of the following situation: there are two, (nearly) equal buildroots A & B in the directory tree like
<basedir> |- A `- B
Can it be prohibited that A modifies files within B?
Yes. You ensure that the set of types associated with the files and processes of A is disjoint from those of B, and that no interaction between them is allowed by your security policy.
Russell Coker has done work on restricting chroots with SELinux - check out macros/chroot_macros.te in the latest sample policy.
Essentially you say something like this:
chroot(fedora_group1_t, fedora_group1)
Assuming you have defined a user fedora_group1 with role fedora_group1_r and type fedora_group1_t.
Would it be possible to forbid any kind of access at <basedir> for buildprocesses?
That would be very easy, yes - just don't mention the type of <basedir> in your policy relating to the chroot types.
We will have to deal with
mount -t proc none <buildroot>/proc vs. mount --bind trojan /bin/sh
The first command MUST be supported, but the second one (inclusive variants) be forbidden.
AFAIK all these mount types are multiplexed through the one mount system call. SELinux appears to have two checks; first, they need the "mount" permission of the source filesystem type (such as proc_t or device_t). However I believe a mount operation has to pass a secondary check - they need access to the "mounton" operation for the object (file/directory) that is the destination of the mount. So since the type of /bin/sh would be shell_exec_t, your chrooted user presumably wouldn't have permission to bind mount on top of it. I'll try to verify this when I get a chance.
But as Bill said, it seems to me you could just set up the chroot (including /proc mount), and not allow the user permission to mount/unmount anything at all. Why would a build root need to mount/umount proc?
By the way - one general point about SELinux. So far you have generally been asking about access to specific files and whether or not the user execute "mount --blah...". With SELinux, *everything* has a type. This includes files, but also things like file descriptors and ports. Any interaction between two types that is not expressly permitted is denied. So you really want to think in terms of the types of objects and the operations permitted on them, rather than secondary characteristics such as their pathnames (/bin/sh, /var/buildroot).
Enrico Scholz (enrico.scholz@informatik.tu-chemnitz.de) said:
- SELinux can protect foreign processes. But is it possible to hide them in /proc also?
If you cannot access it, why does it matter if it is visible?
- How can disk/memory usage restricted with SELinux? Would CKRM be an option?
SELinux doesn't deal with resource limitations; that would be handled by CKRM or something similar.
- Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also?
Not sure what you're asking here. Mount can be allowed or disallowed based on the policy.
Bill
notting@redhat.com (Bill Nottingham) writes:
- SELinux can protect foreign processes. But is it possible to hide them in /proc also?
If you cannot access it, why does it matter if it is visible?
E.g. 'service xyz stop' in rpm-scriptlets may have an unwanted behavior when it sees 'xyz' processes in other "contexts".
- Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also?
Not sure what you're asking here. Mount can be allowed or disallowed based on the policy.
We have to allow *some* kinds of mount but forbid all other ones.
Enrico
Enrico Scholz (enrico.scholz@informatik.tu-chemnitz.de) said:
- SELinux can protect foreign processes. But is it possible to hide them in /proc also?
If you cannot access it, why does it matter if it is visible?
E.g. 'service xyz stop' in rpm-scriptlets may have an unwanted behavior when it sees 'xyz' processes in other "contexts".
In general, you'll be able to tell that there's a process at pid <foo>, but not what process it is.
Note that scriplets in a build root very very very very very rarely need to kick processes, if ever.
- Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also?
Not sure what you're asking here. Mount can be allowed or disallowed based on the policy.
We have to allow *some* kinds of mount but forbid all other ones.
I would think that the buildroot filesystem setup & mounting would be done outside of the chroot process.
Bill
??
Enrico Scholz (enrico.scholz@informatik.tu-chemnitz.de) said:
- SELinux can protect foreign processes. But is it possible to hide them in /proc also?
If you cannot access it, why does it matter if it is visible?
E.g. 'service xyz stop' in rpm-scriptlets may have an unwanted behavior when it sees 'xyz' processes in other "contexts".
In general, you'll be able to tell that there's a process at pid <foo>, but not what process it is.
Note that scriplets in a build root very very very very very rarely need to kick processes, if ever.
One particularly embarassing test run of mach comes to mind where I tried rebuilding and installing the patched openssh rpms and it shut down the sshd process in the main context because the install scriptlet restarts sshd. So it might happen very very very very rarely, but it was also very very very very painful at that particular time.
So I'm down with Enrico, as always.
Thomas
On Fri, 2003-11-28 at 00:31, Enrico Scholz wrote:
- SELinux can protect foreign processes. But is it possible to hide them in /proc also?
It is not currently possible to hide them. However, the entries in /proc have the same type as the domain of the running process. So if you don't allow any operations on that type (including getattr), then the only thing one can tell is that a process exists at that PID.
- Is chroot(2) implemented in a safe manner? Or, can parent directories of build-roots be protected with SELinux policies? Is a safe chroot(2) required at all?
Using SELinux, a chroot doesn't provide any additional direct security. However, you may find it convenient to use a chroot in this instance so that different sets of packages can be installed, etc.
- What is the performance impact of the policy checking?
Minimal; IIRC the overhead was something like 1-2% for very system-call intensive tasks, and negligible after that.
- How can disk/memory usage restricted with SELinux? Would CKRM be an option?
SELinux does not deal with resource restrictions.
- Can special mount-operations (e.g. /proc filesystem) be allowed by the policy, or does this require userspace helper also?
The mount system call is restricted, yes.
- Setup of an SELinux policy seems to be very complicated. How possible are holes in a setup?
Assuming that there are no bugs in the kernel, it is impossible to reach sysadm_t (essentially equivalent to the SELinux "root") if the policy doesn't very explicitly permit it.
I hope that answers your questions!