10

SE Linux Support in GPG

In May 2002 I had an idea for securing access to GNUPG [1]. What I did was to write SE Linux policy to only permit the gpg program to access the secret key (and other files in ~/.gnupg). This meant that the most trivial ways of stealing the secret key would be prevented. However an attacker could still use gpg to encrypt it’s secret key and write the data to some place that is accessible, for example the command “gpg -c --output /tmp/foo.gpg ~/.gnupg/secring.gpg“. So what we needed was for gpg to either refuse to encrypt such files, or to spawn a child process for accessing such files (which could be granted different access to the filesystem). I filed the Debian bug report 146345 [2] requesting this feature.

In March upstream added this feature, the Debian package is currently not built with --enable-selinux-support so this feature isn’t enabled yet, but hopefully it will be soon. Incidentally the feature as currently implemented is not really SE Linux specific, it seems to me that there are many potential situations where it could be useful without SE Linux. For example if you were using one of the path-name based MAC systems (which I dislike – see what my friend Joshua Brindle wrote about them for an explanation [3]) then you could gain some benefits from this. A situation where there is even smaller potential for benefit is in the case of an automated system which runs gpg which could allow an attacker to pass bogus commands to it. When exploiting a shell script it might be easier to specify the wrong file to encrypt than to perform more sophisticated attacks.

When the feature in question is enabled the command “gpg -c --output /tmp/foo.gpg ~/.gnupg/secring.gpg” will abort with the following error:
gpg: can’t open `/root/.gnupg/secring.gpg’: Operation not permitted
gpg: symmetric encryption of `/root/.gnupg/secring.gpg’ failed: file open error

Of course the command “gpg --export-secret-keys” will abort with the following error:
gpg: exporting secret keys not allowed
gpg: WARNING: nothing exported

Now we need to determine the correct way of exporting secret keys and modifying the GPG configuration. It might be best to allow exporting the secret keys when not running SE Linux (or other supported MAC systems), or when running in permissive mode (as in those situations merely copying the files will work). Although we could have an option in gpg.conf for this for the case where we want to prevent shell-script quoting hacks.

For editing the gpg.conf file and exporting the secret keys we could have a program similar in concept to crontab(1) which has PAM support to determine when it should perform it’s actions. Also it seems to me that crontab(1) could do with PAM support (I’ve filed Debian bug report 484743 [4] requesting this).

Finally one thing that should be noted is that the targeted policy for SE Linux does not restrict GPG (which runs in the unconfined_t domain). Thus most people who use SE Linux at the moment aren’t getting any benefits from such things. This will change eventually.

Trust and My SE Linux Play Machine

Currently my SE Linux Play Machine [1] is running as a Xen DomU. So if someone cracks it they would also have to crack Xen to get access to directly change things on the hardware (EG modifying the boot process). As documented in my last post [2] a user of my Play Machine recently managed to change my password. Of course this was just two days after the vmsplice() kernel security flaw had been discovered [3]. Of course any machine that offers shell access to remote users (or the ability to run CGI-BIN scripts or other programs that users can upload) is immediately vulnerable to such exploits and while SE Linux has blocked local kernel exploits in the past [4] there will always be the possibility of kernel exploits that SE Linux can’t block or which can be re-written to work in a way that is not stopped by the SE Linux policy. So it’s best to assume that SE Linux systems are vulnerable to kernel exploits.

At the time that the vmsplice() exploit was announced there was a claim that it could be used to de-stabilise a Xen Dom0 when run within a DomU. It’s best to assume that any attack which can make some software perform in an unexpected manner can also be used to successfully attack it. So at the time I was working on the assumption that the Dom0 could have been exploited.

Therefore I reinstalled the entire machine, I firstly installed a new Dom0 (on which I decided to run Debian/Unstable) and then I made a fresh install of Etch for the Play Machine. There is a possibility that an attacker could compromise the hardware (changing the BIOS or other similar attacks), but this seems unlikely – I doubt that someone would go to such effort to attach hardware that I use for demonstrating SE Linux and for SE Linux development (it has no data which is secret).

If someone attacks my Play Machine they would have to first get root on the DomU in question and then crack Xen to get access to the hardware. Then the machine is on a separate Ethernet segment which has less access to my internal network than the general Internet does (so they would not gain any real benefit).

One thing an attacker can do is launch a DOS attack on my machine. One summer a Play Machine overheated and died, I suspect that the extra heat produced by a DOS attack contributed to that problem. But losing a low-end machine I bought second-hand is not a big deal.

When discussing the machine there are two common comments I get. One is a suggestion that I am putting myself at risk, I think that the risk of visiting random web sites is significantly greater. Another is a challenge to put the machine on my internal network if I really trust SE Linux, as noted I have made mistakes in the past and there have been Linux kernel bugs – but apart from that it’s always best to have multiple layers of protection.

3

SE Linux Play Machine and Passwords

My SE Linux Play Machine [1] has been online again since the 18th of March.

On Monday the 11th of Feb I took it offline after a user managed to change the password for my own account (their comment was “ohls -lsa! i can change passwordls -lsals -lsa HACKED!“). Part of the problem was the way /bin/passwd determines whether it should change a password.

The previous algorithm (and the one that is currently used in Debian/Etch) is that if the UID of the account that is having it’s password changed doesn’t match the UID of the process that ran /bin/passwd then an additional SE Linux check is performed (to see if it has permission to change other user’s passwords). The problem here is that my Play machine has root (UID==0) as the guest account, and that according to the /bin/passwd program there is no difference between the root account (for unprivileged users) and the bofh account (which I use and which also has UID==0). This means of course that users of the root account could change the password of my account. My solution to this was to run chcon on the /bin/passwd program to give it a context that denied it the ability to change a password. The problem was that I accidentally ran the SE Linux program restorecon (which restores file contexts to their default values) which allowed /bin/passwd to change passwords, and therefore allowed a user to change the password of my account.

The semanage tool that allows changing the default value of a file context does not permit changing the default for a file specification that matches one from the system policy (so the sys-admin can’t override compiled in values).

I have now fixed the problem (the fix is in my Etch SE Linux repository [2] and has been accepted for Debian/Unstable and something based on it will go into the upstream branch of Shadow. See the Debian bug report #472575 [3] for more information.

The summary of the new code is that in any case where a password is not required to change the user’s password then SE Linux access checks will be performed. The long version is below:

The new algorithm (mostly taken from the Red Hat code base which was written by Dan Walsh) is that you can only change a password if you are running as non-root (which means that the pam_unix.so code will have verified the current password) or if you are running as root and the previous SE Linux security context of the process is permitted access to perform the passwd operation in the passwd class (which means it is permitted to change other user’s passwords).

The previous context (the context before one of the exec family of system calls was called) is used for such access checks because we want to determine if the user’s shell (or other program used to launch /bin/passwd) was permitted to change other user’s passwords – executing a privileged program such as /bin/passwd causes a domain transition and the context is different) than the program that was used to execute it. It’s much like a SETUID program calling getuid(2) to get the UID of the process which launched it.

To get the desired functionality for my Play Machine I don’t want a user to change their own password as the account is shared. So I appended password requisite pam_deny.so to the file /etc/pam.d/passwd (as well as the chfn and chsh commands) so that hostile users can’t break things. The new code in /bin/passwd will prevent users from taking over the machine if my PAM configuration ever gets broken, having multiple layers of protection is always a good thing.

The end result is that the Debian package and the upstream code base are improved, and my Debian Etch repository has the code in question.

SE Linux Etch Repository for AMD64

My Etch back-port repository of SE Linux related packages (which I documented in a previous post [1]) now has a complete set of packages for AMD64. From now on I aim to make AMD64 and i386 be my main supported platforms for SE Linux development.

There is a guy who may be able to give me a stack of well configured PowerMacs (2gigs of RAM), if he comes through with that then I may add PPC-32 to the list of architectures I support. If that happens then probably the machines will have their hard drives smashed for security reasons, so I’ll want to swap some G3 PowerMacs for hard drives.

1

Debian SE Linux Status

At the moment I’ve got more time to work on these things than I have had for a while.

I’ve got Etch support going quite well (see my post about my Etch repository [1]), the next step is to back-port some packages for AMD64 to get it working as well as i386.

I’ve got an i386 Xen server for SE Linux development (which is also used for my Play Machine’s [2] DomU – so it’s definitely not for anything secret). I can give accounts and/or DomU’s to people who have a good use for them (the machine has 512M of RAM so could have 4-5 DomU’s).

Currently it seems that the 2.6.24 kernel in Debian doesn’t work for Xen (at least on with an i686 CPU). I have filed bug report #472584 about it not working as a DomU [3]. This combined with the fact that according to bug report #466492 it doesn’t work as a Dom0 (which I have verified in my own tests) [4] makes the package linux-image-2.6.24-1-xen-686 unusable.

Due to the inability to use 2.6.24 Xen I can’t do SE Linux development for Lenny in a DomU (Lenny tools build policy version 21 and the Etch kernel I’m using only supports policy version 20). So I have repurposed one of my servers for Lenny (unstable) development. I can give user accounts on that machine to anyone who has a good reason (and there are some people who I would give root access to if they need it).

The current policy packages in Unstable are built without MCS support. This is a problem as converting between a policy which has MCS or MLS and one which doesn’t is rather painful (purge policy, reinstall policy, and reboot are all required steps). I have filed bug report #473048 with a patch for this – my patch may not actually be much good (I don’t understand some aspects of Manoj’s code) but it does achieve the desired result [5]. I won’t be making Apt repositories for such things as I expect that the changes will get into Debian fast enough.

The next thing I am starting to work on is MLS support for Debian (currently it only supports the Strict and Targeted policies). See the Multilevel Security Wikipedia page for some background information on the technology [6].

I don’t expect that many people will use MLS on Debian in production environments, and it wouldn’t surprise me if no-one used it on a production server (although of course it would be impossible to prove this). But I still believe that it’s worth having for educational purposes. I am sure that there are packages in Debian of a similar size that will get less use so it’s not a waste of disk space on mirror servers!

The only real down-side to adding MLS support is that it will increase the build time for the Debian SE Linux policy packages, currently they take 13 minutes to build on a 1.1GHz Celeron system (the Xen server I mentioned previously) and I expect that the machine in question will have build times greater than 20 minutes with MLS included. I will probably need to set up an Unstable DomU on a dual-core 64bit machine for the sole purpose of building policy packages. I will also have to investigate use of the “-j” option to make when building the policy to take advantage of the dual cores. I often do small tweaks to policy and it’s annoying to have to wait for any length of time for a result.

The version of Coreutils that is currently in Unstable will have ls display a “+” character for every file when running SE Linux (I have filed bug report #472590) about this [7]. It is being actively discussed and at this stage it seems most likely that the functionality from Etch in this regard will be restored (which is using “+” to represent ACLs only not SE Linux contexts). It seems likely to me that I will find a few other issues of a similar nature now that I have started seriously working on Unstable.

For the benefit of Debian and upstream developers who get involved in such discussions, please do not be put off if you join a discussion that is CC’d to the NSA SE Linux mailing list and have your message rejected by the list server. The code of conduct is much the same on most mailing lists, and the SE Linux list is not much different to others. The difference is that before your get your email address white-listed for posting you have to agree to the terms of service for the list. The people who run the list server appear to work more than 40 hours a week so there should not be a great delay. If anyone wants to get a message about Debian SE Linux development sent to the list without delay on a weekend then they can send it to me for forwarding.

I am aware of some discussions about SE Linux and the Debian installer. I have not responded to them yet because I wanted to get some serious coding done first as an approach of “I haven’t done much coding recently but trust me I’ll fix the problems for you” might not be accepted well. I will start investigating these issues as soon as I have my Debian/Unstable server working well in enforcing mode.

Update: I’ve just filed bug report #473067 with a patch to enable MLS policy builds [8].

7

Linux Resource Controls

Using the “ulimit” controls over process resource use it is possible to limit RAM for processes and to limit the number of processes per UID. The problem is that this often is only good for accidental problems not dealing with malicious acts.

For a multi-user machine each user needs to be allowed to have two processes to be able to do anything (IE the shell and a command that they execute). A more practical limit is five processes for a single shell session (one or two background jobs, a foreground job where one process pipes data to another, and the shell). But even five processes is rather small (a single Unix pipe can have more than that). A shell server probably needs a limit of 20 processes per user if each user will have the possibility of running multiple logins. For running the occasional memory intensive process such as GCC the per-process memory limit needs to be at least 20M, if the user was to compile big C++ programs then 100M may be needed (I’ve seen a G++ process use more than 90M of memory when compiling a KDE source file). This means that a single user who can launch 20 processes which can each use 20M of memory could use 400M of memory, if they have each process write to a pages in a random order then 400M of RAM would be essentially occupied by that user.

If a shell server had 512M of RAM (which until quite recently was considered a lot of memory – the first multi-user Linux machine I ran on the net had 4M of RAM) then 400M of that could be consumed by a single hostile user. Leaving 100M for the real users might make the machine unusable. Note that the “hostile user” category also encompasses someone who gets fooled by the “here’s a cool program you should run” trick (which is common in universities).

I put my first SE Linux Play Machine [1] on the net in the middle of 2002 and immediately faced problems with DOS attacks. I think that the machine had 128M of RAM and because the concept was new (and SE Linux itself was new and mysterious) many people wanted to login. Having 20 shell users logged in at one time was not uncommon, so a limit of 50 processes for users was minimal. Given that GCC was a necessary part of the service (users wanted to compile their own programs to test various aspects of SE Linux) the memory limit per process had to be high. The point of the Play Machine was to demonstrate that “root” was restricted by SE Linux such that even if all Unix access control methods failed then SE Linux would still control access (with the caveat that a kernel bug still makes you lose). So as all users logged into the same account (root) the process limit had to be adequate to handle all their needs, 50 processes was effectively the bare minimum. 50 processes with 5M of memory each is more than enough to cause a machine with 128M of RAM to swap to death.

One thing to note is that root owned system processes count towards the ulimit for user processes as SE Linux does not have any resource usage controls. The aim of the SE Linux project is access control not protection against covert channels [2]. This makes it a little harder to restrict things as the number of processes run by daemons such as Postfix varies a little over time so the limits have to be a little higher to compensate, while Postfix is run with no limits the processes that it creates apply to the global limit when determining whether user processes can call fork().

So it was essentially impossible to implement any resource limits on my Play Machine that would prevent a DOS. I changed the MOTD (message of the day – displayed at login time) to inform people that a DOS attack is the wrong thing to do. I implemented some resource limits but didn’t seriously expect them to help much (the machine was DOSed daily).

Recently I had a user of my Play Machine accidentally DOS it and ask whether I should install any resource limits. After considering the issue I realised that I can actually do so in a useful manner nowadays. My latest Play Machine is a Xen DomU which I have now assigned 300M of RAM, I have configured the limit for root processes to be 45, as the system and my login comprise about 30 processes that leaves 15 for unprivileged (user_r) logins. Of recent times my Play Machine hasn’t been getting a lot of interest, having two people logged in at the same time is unusual so 15 processes should be plenty. Each process is limited to 20M of memory so overflowing the 300M of RAM should take a moderate amount of effort.

Recently I intentionally have not used swap space on that machine to save on noise when there’s a DOS attack (on the assumption that the DOS attack would succeed regardless of the amount of swap). Now that I have put resource limits in place I have installed 400M of swap space. A hostile user can easily prevent other unprivileged users from logging in by keeping enough long-running processes active – but they could achieve the same goal by having a program kill users shells as soon as they login (which a few people did in the early days). But it should not be trivial for them to prevent me from logging in via a simple memory or process DOS attack.

Update: It was email discussion with Cam McKenzie that prompted this blog psot.

Suse and LCA

I previously wrote about how I gave a talk about SE Linux at a conference spot when a talk about AppArmor was scheduled. It turned out that the Suse people had notified the LCA people some time in advance about the fact that John would not be attending the conference. The LCA people had removed the entries from their databases and when the conference schedule was printed it had no reference to such a talk.

The problem occurred when another tutorial (which had occupied the slot that was previously assigned to John) was moved to a different part of the schedule. For some reason the CMS that they use did not leave the slot in question empty but instead restored earlier contents (which was the Suse tutorial). No-one at LCA noticed this error and from that time on the web page generated by the CMS was used as the authoritative source of information about the issue by delegates and most of the LCA team.

1

My LCA Talk

Last year at LCA Crispin Cowan suggested to me that I make a joint offer of a combined tutorial on SE Linux and AppArmor as a way of publicly comparing the two technologies. I ended up not accepting the challenge, among other things I had a long-term project going in production in early December that needed some ongoing support.

Crispin’s plan B was to just give a lecture about AppArmor. Recently Crispin joined Microsoft [1] and John Johansen of Suse was going to give the talk in his place. The LCA people made a minor mistake by having the conference web site give the description of the tutorial option [2] (which I don’t believe was ever going to happen as I had not accepted the offer), but it’s easy to understand the webmaster copying the wrong description when the one person makes two offers (which I believe is not a common practice).

So this morning I and about 150 other people were waiting in the main lecture theatre and no-one from Suse turned up.

Being fairly audacious when the announcement was made that the event was officially cancelled I stood up and asked if anyone would like an impromptu talk about SE Linux instead. The audience received that idea quite well.

My talk wasn’t as good as I had hoped, not having had a proper breakfast or any caffeinated drinks reduced my mental stack space. So I could talk well on one topic but when questions diverted me to a side topic I found it difficult to remember the previous point I was making. Fortunately when giving an impromptu talk with no notes or presentation materials the audience expectations for a consistent plan of the talk seem reasonably low. ;)

I started by talking about my SE Linux Play Machines. Some of that material had been covered in previous talks at other conferences (such as at a previous SE Linux Symposium), but some things (such as my use of Xen) I had not previously covered, but none of it had been mentioned in a talk in Australia for a while. Having given an hour-long talk about SE linux yesterday to an audience with many of the same members I wanted to start by talking about something that they hadn’t heard before, and I was also wearing a Play Machine T-shirt (with the root password printed on it) [4]. After I finished talking about my Play Machines and started covering some of the same material as yesterday about a quarter of the audience left (which was fair enough).

I then spoke about general SE Linux issues, largely in response to questions. I covered the differences between the policies (including the history of policy development), the JFFS2 XATTR development (and how SE Linux couldn’t be used on an iPaQ without it), issues of disk space usage for XATTRs for SE Linux labelling on various filesystems and how it drives the use of context mount options, poly-instantiated directories (including some discussion on how the actual storage location for such directories can be on a different filesystem and how this could be convenient when using encrypted filesystems), how Apache/PHP work in a SE Linux environment, and a lot more.

I couldn’t resist mentioning to the audience the irony that I had declined a challenge for a joint presentation and then got a sole presenter spot (and a large audience) due to the Suse guy not showing up.

For future situations I plan to load lecture notes from all my common talks on my iPaQ. Then next time I have such a speaking opportunity I can give a better prepared talk.

Update: It turned out that the LCA people had been informed that the Suse talk was cancelled and had made a mistake, see this link for details.

2

SE Linux in other Distributions

Recently a user has been asking about SE Linux support in MEPIS [1]. He seems to expect that as the distribution is based on Debian it should have the same SE Linux support as is in Debian.

The problem with derived distributions (which potentially applies to all variants of Debian, Fedora, and RHEL) is that the compilation options used may differ from what is required for SE Linux support.

If an application works in Debian then you can expect that it will work in all derived distributions. But SE Linux is not an application, it is a security extension to the OS which includes code in the kernel, login, cron, pam, sshd, logrotate, and others. For any one of these packages a maintainer of a derived distribution might decide to turn off features to save disk space or memory, or because they want to use features which don’t work well with them (due to functional differences or bugs). The maintainer of a derived distribution might even decide that they just don’t like a feature and disable it for that reason alone!

I believe that it is possible to use APT with multiple repositories and specify preferences for each repository. So it should be possible to use a source such as MEPIS for most packages but Debian (or my private repository of SE Linux back-ports [2]) for the packages which need SE Linux support.

That said, I am not sure why someone would want to use MEPIS with SE Linux. Currently the benefits of SE Linux are of most use for a server and MEPIS is a desktop focussed distribution. Debian works reasonably well for a desktop (it has worked well for me for most of the past 11 years), so it seems that Debian for a SE Linux desktop machine is a good choice and Debian is a better choice than MEPIS for a server.

10

Restorecon Equivalent for Unix Permissions

SE Linux has a utility named restorecon to set (or reset) the security context. This is useful for many reasons, corrupted filesystems, users removing files or changing the context in inappropriate ways, and for re-creating files from tar files or backup programs that don’t restore SE Linux contexts. It can also be used to report the files that have different contexts to that which would be set by restorecon to verify the contexts of files.

Restorecon determines the context from two sources of data, one is the policy that came with the system (including any policy modules from other sources which were loaded) and the other is the local file contexts that were created by semanage.

It’s a pity that there doesn’t seem to be an equivalent program for Unix permissions. rpm has a -V option to verify the files from a package and dpkg doesn’t seem to have an option to perform a similar operation (/var/lib/dpkg/info/* doesn’t seem to have the necessary data). But even on an RPM based system this isn’t possible because there is no way to add local files into the list.

I would like to be able to specify that an RPM system should have root:root as the owner and permission mode 0755 for all files matching /usr/local/bin/* and use a single command to check the RPM database as well as this extra data for the permissions of all files.

Does anyone know of any work in this area?

I’m going to file Debian and Fedora bug reports about this, but I would appreciate any comments first.

Update:

Here is an example of how this feature works in rpm:
# rpm -Vv nash
…….. /sbin/nash
…….. d /usr/share/man/man8/nash.8.gz
# chmod 700 /sbin/nash
# rpm -Vv nash
.M…… /sbin/nash
…….. d /usr/share/man/man8/nash.8.gz

The “M” character indicates that the permission mode of the file does not match the RPM. There is no way to automatically correct it (AFAIK) but at least we know that something changed. With Debian AFAIK it’s only possible to verify file checksums not the permission.