Friday, January 05, 2007

core files

The issue of core file management has come up for discussion again in the SE Linux list.

I believe that there are two essential security requirements for managing core files, one is that the complete security context of the crashing process is stored (to the greatest possible extent), and the other is that processes with different security contexts be prevented from discovering that a process dumped core (when attacking a daemon it would be helpful to know when you made one of it's processes dump core).

The core file will have the same UID and GID as the process that crashed. It's impossible to maintain the complete security context of the crashing process in this manner as Unix permissions support multiple supplementary groups and Unix filesystems only support one GID. So the supplementary groups are lost.

There is also a sysctl kernel.core_pattern which specifies the name of the core file. This supports a number of modifiers, EG the value "core.%p.%u.%g" would give a file named "core.PID.UID.GID". It would be good to have a modification to the kernel code in question to allow the SE Linux context to be included in this (maybe %z).

To preserve the SE Linux context of the crashing process with current kernel code we need to have a unique type for each process that dumps core, this merely requires that each domain have an automatic transition rule for creating files in the directory chosen for core dumps. In the default configuration we have core files dumped in the current directory of the process. This may be /tmp or some other common location which allows an attacker to discover which process is dumping core (due to the directory being world readable) and in the case of SE Linux there may be multiple domains that are permitted to create files in /tmp with the same context which gets in the way of using such a common directory for core files.

The traditional Unix functionality is to have core files dumped in the current directory. Obviously we can't break this by default. But for systems where security is desired I believe that the correct thing to do is to use a directory such as /var/core for core files, this can be easily achieved by creating the directory as mode 1733 (so that any user can create core files but no-one but the sys-admin can read them) and then setting the core_pattern sysctl to specify that all core files go in that directory. The next improvement is to have a poly-instantiated directory for /var/core such that each login user has their own version. That way the user in question could see the core files created by their own processes while system core files and core files for other users would be in different directories. Poly-instantation is easier to implement for core files than it is for /tmp (and the other directories for which it is desirable) because there is much less access to such a directory. When things operate correctly core files are not generated, and users never need to access each other's core files directly (they are mode 0600 so this isn't possible anyway).

This area will require a moderate amount of coding before it works in the ideal manner. I aim to briefly describe the issues only in this post.

3 comments:

Anonymous said...

If you can write but not read a directory, you can still tell whether a file with a specific name exists in it. So I don't see that the intermediate step of a shared /var/core is a significant improvement.

Anonymous said...

Whatever you do, it would not be a good idea to change the customary behavior in the ordinary case, where the executable has no special SELinux labels. A casual developer whose app drops core shouldn't have to contact the sysadmin to get access to the core.

etbe said...

Ben, you are correct. Of course with a small modification to the kernel code we could include a 64bit number taken from /dev/urandom in the file name, then even if a billion unsucceddful creat() calls could be made per second it would still take hundreds of years to discover it.

Anon, I am not suggesting that the default configuration for main-stream distributions be changed. However for security-hardened sub-distributions or specific configurations it could be a viable default. Generally I think that this should be among a set of options for easily hardening a system. I have been thinking of creating a Debian package which would enable such things when installed, most people would not install it.

Also if the sysadmin decides that core files should be owned by the system then that decision should be easy to implement. It's not difficult for the sysadmin to set a hard ulimit of coresize to zero, and some do.