LOMAC - Low Water-Mark Mandatory Access Control User's Manual v1.1.1 11 July 2001 Tim Fraser tfraser@nai.com NAI Labs 3060 Washington Road Glenwood, MD 21738-9745 USA This is a revision of NAI Labs Technical Report Number 0766. Copyright (c) 1999, 2000, 2001 NAI Labs. You may reproduce and distribute this document so long as this copyright statement and disclaimer are retained on all copies. Although we have tried to be complete and correct, this manual is provided with NO WARRANTY. [ Synopsis ] This is the manual for LOMAC: a security enhancement for Linux that used Low Water-Mark Mandatory Access Control to protect the integrity of processes and data from viruses, Trojan horses, malicious remote users, and compromised root daemons. LOMAC is implemented as a Loadable Kernel Module (an LKM, like a driver) - no kernel recompilations or changes to existing applications are required. LOMAC is not complete. Some features and fixes remain to be implemented, including controls on some security-relevant operations (most notably mmap). Still, LOMAC does presently provide some useful integrity protection. For example, LOMAC may halt attacks by "script kiddies" who rely on the operations LOMAC does control, and who are not sufficiently sophisticated to modify their attack strategy to bypass LOMAC. As LOMAC development continues, more controls will be added to more operations. LOMAC is stable enough for everyday use. LOMAC operates on single-CPU machines running Linux 2.2 kernels. Ports are underway to a variety of other platforms. LOMAC is Free software available from http://opensource.nailabs.com/lomac under the three-clause BSD-style license shown in section 12 of this manual. Additional information about LOMAC can also be found at this site. [ Contents ] 1. Introduction 2. Installation 3. A Short Tour 4. De-installation 5. LOMAC and Network Servers 6. LOMAC and Traditional UNIX Access Control 7. Limits to LOMAC's Protection 8. Administrative Loopholes 9. Installing New Software 10. Performance 11. Related Projects 12. The LOMAC License [ 1. Introduction ] Several projects have demonstrated that kernel-resident Mandatory Access Control (MAC) mechanisms can protect the integrity of Free UNIX systems from malicious code and users. However, implementations of these mechanisms have traditionally required invasive kernel modifications, sometimes coupled with supporting modifications of user-space utilities, as well. This requirement has hindered the adoption of MAC mechanisms in the mainstream Free UNIX community. Adoption has been further discouraged by the difficulty of starting small and evolving towards a complete MAC solution - in general, the complete set of extensive modifications must be made before MAC can provide any useful protection. LOMAC is an attempt to make an easily-adoptable form of MAC integrity protection available to the Free UNIX community without the discouraging necessity of kernel modifications. LOMAC implements a simple form of MAC integrity protection based on Biba's Low Water-Mark model in a Linux Loadable Kernel Module (LKM) [BIB77, FRA00, FRA01]. Although it trades off some of the advanced MAC features found in traditional MAC implementations, LOMAC provides useful integrity protection without any modifications to the kernel, applications, or their existing configurations. LOMAC is designed to be compatible with existing software, and ships with a one-size-fits-all default configuration. LOMAC may be used to harden currently-deployed Linux systems simply by loading the LKM into the kernel shortly after boot time. Once loaded, LOMAC divides the system into two conceptual levels of integrity: high and low. The high side contains all process and files that should be protected from malicious code and remote users: the kernel servers (kflushd and friends), the system binaries (bin, lib), the system configuration files (etc), and any mission-critical data (your web pages). The low side contains the processes that interact with remote users (remote login sessions, httpd) and the files they download from the net (mail attachments). Low files may contain viruses or Trojan Horses. Low processes take input from remote users that may cause buffer overflows. During run-time, LOMAC protects high files and processes by preventing low processes from modifying or signalling them. Thanks to is generic default configuration, LOMAC handles the division of the system into high and low parts automatically, without administrative direction. LOMAC does not override the existing Linux protection mechanisms. Instead, its permission checks are done in addition to the existing ones - the kernel permits an operation only if both the existing mechanisms and LOMAC decide it should permit it. Unlike the existing Linux protection mechanisms, LOMAC makes decisions based solely on integrity level, not on user identity. With LOMAC, a low-level root process is just as powerless as a low-level non-root process. Since LOMAC automatically places all network servers in the low part of the system, this fact prevents compromised root-privileged network servers from harming the high-integrity part of the system. This document is the manual for LOMAC. It is intended both for those who wish to understand and improve the LOMAC software, and for those who simply wish to use LOMAC. Other documents concerning LOMAC can be downloaded from http://opensource.nailabs.com/lomac. This site also contains archive information for the lomac-users mailing list. The lomac-users mailing list is the primary public forum for discussing LOMAC, and all persons interested in learning about, using, or improving LOMAC are welcome to join. To join the lomac-users mailing list, send mail to with the following command in the body of the message: subscribe lomac-users [ 2. Installation ] LOMAC is Free software. It is available for download from http://opensource.nailabs.com/lomac under the 3-clause BSD-style license shown in section 12 of this manual. LOMAC operates on single-CPU machines running Linux 2.2 kernels. Since LOMAC does not require the modification of existing software or configuration files, installation is merely a matter of copying files and running insmod to load the LKM. De-installation requires only deleting these files and rebooting. Consequently, potential users may install LOMAC, try it out, and (if they so choose) easily de-install it, leaving their system as it was before. The LOMAC install procedure has not yet been automated. To install LOMAC, you must perform the following steps manually. 1. If you have not done so already, download the latest LOMAC distribution from http://opensource.nailabs.com/lomac. 2. LOMAC needs the header files which come with the Linux kernel source. In RedHat distributions, the kernel source resides in /usr/src/linux. In Debian distributions, the kernel source resides in /usr/src/kernel-source-A.B.C, where A.B.C are the kernel source's version number. If you do not have one of these directories, you must find the kernel-source package with the same version number as your kernel, and install it. Alternately, you can install a kernel-source package with a version number newer than your present kernel, and use it to build and replace your present kernel before proceeding with the LOMAC installation. Note that some distributions, such as Debian, provide a kernel-header package that is much smaller than the kernel-source package, but should (in theory) provide all the header files LOMAC needs. I have attempted to install LOMAC using Debian's kernel-headers-2.2.17 package instead of kernel-source-2.2.17, without success. Any advice in this regard would be appreciated. 3. gunzip and tar -xf the distribution file. This should create a "Lomac" directory. You may wish to browse the contents of this directory and read the README files, as they may be more up-to-date than this manual. You should also read the BUGS file, as this file may describe workarounds for bugs and deficiencies currently in LOMAC. 4. cd Lomac 5. Edit LKM/Core/Makefile and LKM/Arch/Linux2.2/Makefile. Follow the documentation in these Makefiles to choose the value of KERNELHEADERS that is appropriate for your system. The default value works for RedHat distributions - if you run RedHat, you can skip this step. 6. make clean ; make 7. su 8. mkdir -p /opt/lomac/bin 9. cp Utils/level /opt/lomac/bin cp Utils/linfo /opt/lomac/bin cp Utils/lls /opt/lomac/bin cp Utils/lomac.pm /opt/lomac/bin cp Utils/lps /opt/lomac/bin cp Utils/lup /opt/lomac/bin 10. cp LKM/lomac_mod.o /opt/lomac/bin 11. cp Scripts/startLOMAC /opt/lomac/bin 12. Integrate the "lomac" init script into your system's init configuration. Different distributions have different init configurations and use different init configuration management tools. There are several sets of instructions below, each beginning with a init configuration description. Read the descriptions, and follow the instruction set which matches your system best. Set 12A: RedHat Distributions Description: Follow these instruction if your system is a RedHat-based distribution: that is, if you have an /etc/rc.d/init.d directory and an /sbin/chkconfig program. Instructions: cp Scripts/lomac /etc/rc.d/init.d /sbin/chkconfig --add lomac At this point, LOMAC should be set to run. Try: > /sbin/chkconfig --list | grep lomac You should see: lomac 0:off 1:off 2:on 3:on 4:on 5:on 6:off Set 12B: Debian Distributions Description: Follow these instructions if your system is a Debian-based distribution: that is, if you have an /etc/init.d directory and a /usr/sbin/update-rc.d program. Instructions: cp Scripts/lomac /etc/init.d chown root /etc/init.d/lomac chgrp root /etc/init.d/lomac chmod 755 /etc/init.d/lomac update-rc.d lomac defaults 03 97 Set 12C: Distributions with BSD-style Init Configurations If your system uses a BSD-style init (that is, if you have one big rc script instead of separate directories for different "runlevels"), you may simply add a line to execute /opt/lomac/bin/startLomac from your rc script. You should start LOMAC after the filesystems have been mounted, but before the network comes up. 13. Sanity check. At this point, /opt/lomac/bin should look something like this: > ls -l /opt/lomac/bin/ total 100 -rwxr-xr-x 1 root root 1968 Jul 11 19:48 level -rwxr-xr-x 1 root root 2238 Jul 11 19:48 linfo -rwxr-xr-x 1 root root 4272 Jul 11 19:48 lls -rw-r--r-- 1 root root 7503 Jul 11 19:48 lomac.pm -rw------- 1 root root 53623 Jul 11 18:12 lomac_mod.o -rwxr-xr-x 1 root root 3964 Jul 11 19:48 lps -rwxr-xr-x 1 root root 7307 Jul 11 19:48 lup -rwxr-xr-x 1 root root 1981 Jun 15 03:25 startLOMAC LOMAC is not set to run in single-user mode. If LOMAC gives you trouble, you can always reboot to single user mode ("linux single" at the bootloader prompt), turn LOMAC off, and proceed to a higher runlevel ("/sbin/init 3" or "/sbin/init 5" if you run XDM). 16. Optionally, you may also install the suite of test scripts included in the distribution: mkdir /root/Test cp Test/Lomac/* /root/Test These scripts test many of LOMAC's major features. 17. Reboot and log in via a text-based virtual console. Do not log in via X using XDM. LOMAC does not yet handle X-based logins correctly. If your system is configured to allow X-based logins by default, you can still log in via a text-based virtual console by ignoring the X-based login screen and hitting CTRL-ALT-F1 to switch to a text-based virtual console. If your system is configured to allow X-based logins by default, and you wish to change this default to allow text-based virtual console logins instead, you may do so as follows: For RedHat distributions: Edit /etc/inittab. Change the line: id:5:initdefault: to: id:3:initdefault: You can reverse the change by restoring the original line. For Debian distributions: run update-rc.d -f xdm remove Later, you can turn X-based logins back on by running: update-rc.d xdm defaults 18. Read the "vi, emacs" entry in the BUGS file for an important workaround when using these editors for administration. [ 3. A Short Tour ] This section introduces LOMAC's major features. You may follow these steps the first time you boot with LOMAC running to ensure that your installation is correct. LOMAC is sensitive to the location of certain files. Since different Linux distributions sometimes place certain files in different locations, LOMAC may not have installed correctly on your system even though you followed the above installation instructions exactly. These problems have not proven difficult to fix in the past. If you experience trouble, please join the lomac-users mailing list (see the introduction) and describe your symptoms. 1. Log in as root, from the system console (not from X). 2. Check to make sure that the LOMAC LKM is loaded: # /sbin/lsmod | grep lomac lomac_mod 30984 0 (unused) 3. Look at the levels of your processes: # /opt/lomac/bin/lps PID LVL TTY TIME CMD 842 2 tty1 00:00:00 login 854 2 tty1 00:00:00 tcsh 873 2 tty1 00:00:00 lps 875 2 tty1 00:00:00 ps Note that all your processes are running at level 2 - LOMAC's highest level of privilege. 4. Look at the levels of your files: # /opt/lomac/bin/lls drwxr-x--- root root 2 . drwxr-xr-x root root 2 .. -rw-r--r-- root root 2 .bash_history -rw-r--r-- root root 2 .bash_logout -rw-r--r-- root root 2 .bash_profile -rw-r--r-- root root 2 .bashrc drwxr-xr-x root root 2 Test Note that all your files are also at level 2. Level-2 files are high-integrity - LOMAC assumes that they contain no viruses or Trojan horses at boot time, and limits the behavior of processes during run-time to keep them that way. 5. Look at the levels of a normal user's files. I'll use the user tfraser in the example; you'll have to use one of your own users. # /opt/lomac/bin/lls /home/tfraser drwx------ tfraser tfraser 1 . drwxr-xr-x root root 2 .. -rw-r--r-- tfraser tfraser 1 .cshrc -rw-r--r-- tfraser tfraser 1 .login drwx------ tfraser tfraser 1 .netscape drwxrwxr-x tfraser tfraser 1 Hunt drwxrwxr-x tfraser tfraser 1 Projects drwxrwxr-x tfraser tfraser 1 Satan Note that while /home is level 2 (high integrity), all of the user's files are level 1 (low integrity). LOMAC assumes that any of the user's files may be Trojan horses or contain viruses. This includes files downloaded from the Internet - note the level-1 .netscape directory. 6. Examine one of the user's files with less, and put less in the background with ctrl-Z. Then run lps to look at your processes. # less /home/tfraser/.cshrc ^Z Suspended # /opt/lomac/bin/lps PID LVL TTY TIME CMD 1200 2 tty1 00:00:00 login 1217 2 tty1 00:00:00 tcsh 1417 1 tty1 00:00:00 less 1431 2 tty1 00:00:00 lps 1433 2 tty1 00:00:00 ps Note that, although your shell (tcsh in my case) is still at level 2, the process running less is at level 1. Here's why: Processes generally inherit the level of their parent. So, any process you start with your level-2 shell will initially execute at level 2. The less process was no exception - it began running at level 2. However, the less process went on to read the user's .cshrc file. This file is a level-1 file - it contains low-integrity data. Whenever LOMAC sees a level-2 process read a level-1 file, LOMAC "demotes" the process. That is, it reduces the process to level 1. Level-2 processes have maximum privileges (like "root" in standard UNIX). Level-1 processes have greatly reduced privileges. For example, they cannot write to level-2 files, or signal level-2 processes. When a level-2 process reads a level-1 file, it puts itself at risk. The file may be a Trojan horse or may contain data designed to cause buffer overflows. Because of this risk, LOMAC demotes level-2 processes that read level-1 files to level 1. Once at level 1, these processes have insufficient privilege to harm level-2 processes and files. Many cautious UNIX administrators avoid putting "." in their PATH environment variable, in order to avoid executing some Trojan horses. In standard UNIX, a malicious user might give an attack program the same name as a commonly-used command like "ls". If the administrator, running as root, were to cd to the malicious user's directory and type "ls", if the "." preceded "/bin" in their path, they would accidentally execute the malicious ls rather than /bin/ls. This act would effectively execute the malicious user's Trojan horse program with root privileges, perhaps to modify the login program or the passwd file. This precaution is not required in a system running LOMAC. LOMAC considers the execution of a program to be equivalent to a read (since the process reads the program file in order to execute it). Since all non-root user's files are at level 1, LOMAC would demote the process executing the Trojan ls, just as it demoted less in our example, above. Once at level 1, LOMAC would prevent the Trojan ls from modifying level-2 files such as the login program or the passwd file. Demotion is a key part of the LOMAC's integrity protection scheme. Now that we've demonstrated how it works, we're now done with less. Quit the less program. # fg q 6. Create a test file. We'll use this test file to demonstrate LOMAC's integrity protection later on. # cat > /root/foo This file contains test data. ^D 7. tail -f /var/log/messages Leave this running while you continue the tour. It's output will contain LOMAC log messages as we proceed. 8. Switch to another virtual console (perhaps by hitting ALT-F2) and log in as a normal user. Once logged in, examine the levels of your processes: [dyn65:~ ] /opt/lomac/bin/lps PID LVL TTY TIME CMD 1452 1 tty2 00:00:00 tcsh 1472 1 tty2 00:00:00 lps 1474 1 tty2 00:00:00 ps Note that as a normal user, all of your processes are at level 1. Why? Switch back to the virtual console where you are logged in as root (perhaps by hitting ALT-F1). You should see a log message similar to: Dec 20 13:23:35 (none) kernel: LOMAC: level-2 subject p1452g1452u500:tcsh demoted to level 1 after reading /home/tfraser/.cshrc All the getty programs that handle logins run at level 2. When a user attempts to log in, they run the login program, which also runs at level 2. Upon supplying the proper password, the login program starts a shell for the user (tcsh in this case). The shell starts at level 2, but LOMAC demotes it to level 1 when it reads the user's .cshrc file, just as it demoted the less program, above. Once the user's shell is running at level 1, all of the programs subsequently executed by the user will run at level 1, also. Our root shell from the start of the tour remains at level-2 because LOMAC has set all of root's files at level 2. A level-2 process may read level-2 files without being demoted. The user's shell is demoted because it reads the user's level-1 files. LOMAC does not assign levels to processes based on the user's root/non-root identity. LOMAC assigns levels to files by starting the first process (/sbin/init) at level 2, allowing child processes to inherit their parent's level, and by demoting processes that read level-1 files. LOMAC does not pay any attention to user identity. Consequently, LOMAC is not vulnerable to any of the traditional attacks on UNIX security that involve obtaining root identity. 9. Test the above assertion that LOMAC does not give any extra privileges to processes with root identity. Switch back to the normal user's shell and become root. [dyn65:~] su Password: [tfraser@dyn65 tfraser]# lps PID LVL TTY TIME CMD 1486 1 pts/1 00:00:00 login 1498 1 pts/1 00:00:00 su 1500 1 pts/1 00:00:00 tcsh 1703 1 pts/1 00:00:00 lps 1705 1 pts/1 00:00:00 ps Note that, despite the su, your shell is still at level 1. LOMAC never increases the level of a process. Now attempt to delete the /root/foo file you created earlier. [tfraser@dyn65 tfraser]# /opt/lomac/bin/lls /root drwxr-x--- root root 2 . drwxr-xr-x root root 2 .. -rw-r--r-- root root 2 .bash_history -rw-r--r-- root root 2 .bash_logout -rw-r--r-- root root 2 .bash_profile -rw-r--r-- root root 2 .bashrc drwxr-xr-x root root 2 Tmp -rw-r--r-- root root 2 foo [tfraser@dyn65 tfraser]# rm /root/foo rm: remove `/root/foo'? y rm: cannot unlink `/root/foo': Operation not permitted Even though you are root, LOMAC will not allow a level-1 process (rm in this case) to delete a level-2 file. You should see a log message similar to this one in on the root virtual console that is tailing /var/log/messages: Dec 20 13:41:22 (none) kernel: LOMAC: p1716g1716u0:rm level 1 denied creat/trunc of /root/foo level 2 This concludes your tour of LOMAC! Congratulations, you are now a LOMAC user. Please join the lomac-users mailing list. [ 4. De-installation ] The following steps will de-install LOMAC, leaving the system as it was before installation. 1. Log in as root on a virtual console (no X). 2. Verify that you have a level-2 shell using lps, as described in the tour, above. If you cannot get a level-2 root shell, you can also perform the following steps after rebooting to single-user mode. 3. /sbin/chkconfig --del lomac This will remove all of the S and K symbolic links to the lomac script in init.d. If your system does not have chkconfig, you will have to remove these links manually. If your system uses a BSD-style init, remove the call to /opt/lomac/bin/startLOMAC from your rc script. 4. rm /etc/init.d/lomac rm -rf /opt/lomac 5. If you installed the optional test programs, rm -rf /root/Test 6. reboot. You must reboot to remove the LOMAC LKM from the running kernel. The LOMAC LKM cannot be removed by rmmod. [ 5. LOMAC and Network Servers ] This section explains how LOMAC uses its demotion behavior to ensure that all remote users and servers that serve remote users (httpd, ftpd, etc.) run at level 1. At this level, malicious remote users and compromised network servers can do little harm to the level-2 part of the system, even if they have root privilege. It also discusses a few of the finer points concerning LOMAC's protection scheme not already covered in the "Short Tour" section, above. The basic elements of LOMAC's integrity protection scheme are summarized here: 1. LOMAC assigns every process, or named filesystem object (file, named pipe, or bound UNIX-domain socket) a level: either 1 (low integrity) or 2 (high integrity). 2. LOMAC assigns levels to filesystem objects based on their location in the filesystem namespace. The mapping between names and levels constitutes most of LOMAC's "default policy", and is presently hard-coded into the LKM. Once assigned, the levels of filesystem objects never change. 3. The first process (/sbin/init) starts at level 2. All child processes inherit the level of their parent. Only when a level-2 process reads from a level-1 object does LOMAC demote the process to level 1. 4. Level-1 processes have insufficient privilege to write to level-2 objects or signal level-2 processes. This protects the level-2 part of the system from malicious interference. 5. The combination of LOMAC's demotion behavior and its restrictions on the privileges of level-1 processes prevent malicious level-1 users from harming the level-2 part of the system, even in cases where level-2 administrators accidentally execute malicious user's Trojan horses. In UNIX, network servers are generally started automatically by the init process, or by one of its children. With LOMAC, this arrangement guarantees that network servers inherit the init process's level of 2. In addition to demoting level-2 processes upon reading level-1 files, LOMAC also demotes level-2 processes when they read from a network interface. Consequently, LOMAC demotes network server as soon as they read their first client request from the network. Just as LOMAC assigns appropriate levels to user shells based on their file-reading behavior, not their user's identity, this scheme allows LOMAC to demote network servers without initially knowing which programs are network servers: LOMAC simply allows the init program to start all of its servers at level 2, and subsequently demotes those servers which read from a network interface. LOMAC uses the same strategy to ensure that remote users run at level 1: it demotes the remote login (TELNET, rlogind) servers when they receive their first login request, as described above. LOMAC's ability to automatically determine the proper levels for users and servers during run-time is the feature which allows it to avoid site-specific configuration and ship with a one-size-fits-all default policy. Here is an example of an httpd server before it reads its first request. Note that the httpd server is comprised of 11 processes, all at level 2. # /opt/lomac/bin/lps ajx | grep 'PGID\|httpd' PPID PID LVL PGID SID TTY TPGID STAT UID TIME COMMAND 1 355 2 355 355 ? -1 S 0 0:00 httpd 355 371 2 355 355 ? -1 S 99 0:00 httpd 355 372 2 355 355 ? -1 S 99 0:00 httpd 355 373 2 355 355 ? -1 S 99 0:00 httpd 355 374 2 355 355 ? -1 S 99 0:00 httpd 355 375 2 355 355 ? -1 S 99 0:00 httpd 355 376 2 355 355 ? -1 S 99 0:00 httpd 355 377 2 355 355 ? -1 S 99 0:00 httpd 355 378 2 355 355 ? -1 S 99 0:00 httpd 355 379 2 355 355 ? -1 S 99 0:00 httpd 355 380 2 355 355 ? -1 S 99 0:00 httpd 447 532 2 531 439 tty1 531 S 0 0:00 grep PGID\|httpd After httpd reads its first request from the network, you should see a message similar to this one in /var/log/messages: Dec 30 15:38:22 (none) kernel: LOMAC: level-2 subject p371g355u99:httpd demoted to level 1 after reading from the network And running lps again will produce: # /opt/lomac/bin/lps ajx | grep 'PGID\|httpd' PPID PID LVL PGID SID TTY TPGID STAT UID TIME COMMAND 1 355 1 355 355 ? -1 S 0 0:00 httpd 355 371 1 355 355 ? -1 S 99 0:00 httpd 355 372 1 355 355 ? -1 S 99 0:00 httpd 355 373 1 355 355 ? -1 S 99 0:00 httpd 355 374 1 355 355 ? -1 S 99 0:00 httpd 355 375 1 355 355 ? -1 S 99 0:00 httpd 355 376 1 355 355 ? -1 S 99 0:00 httpd 355 377 1 355 355 ? -1 S 99 0:00 httpd 355 378 1 355 355 ? -1 S 99 0:00 httpd 355 379 1 355 355 ? -1 S 99 0:00 httpd 355 380 1 355 355 ? -1 S 99 0:00 httpd 447 610 2 609 439 tty1 609 S 0 0:00 grep PGID\|httpd Note that LOMAC has demoted all 11 httpd server processes to level 1. LOMAC considers all of the processes in a given process group (or "job") to be a unit. It keeps them at the same level at all times. When one process in a process group triggers a demotion, LOMAC demotes all of the processes in the group. All 11 processes are in process group number 355, so LOMAC has demoted them all. The v0.2 version of the LOMAC prototype required this process group behavior in order to properly control the use of unnamed pipes (as described in [FRA00]). Although the v0.3 and later prototypes' unnamed pipe controls no longer require LOMAC to treat process groups as a unit, LOMAC still retains this behavior. [ 6. LOMAC and Traditional UNIX Access Control ] LOMAC does not override the existing Linux protection mechanisms. Instead, its permission checks are done in addition to the existing ones - the kernel permits an operation only if both the existing mechanisms and LOMAC decide the kernel should permit it. There are three main differences between the integrity protection scheme implemented by LOMAC and traditional UNIX security mechanisms: 1. Traditional UNIX provides mechanisms by which processes can increase their privileges by changing their effective identities. Although UNIX systems can be configured to prevent malicious users from exploiting these mechanisms in most cases, they can also be misconfigured, and good configurations can be foiled by bugs in user-space application programs. LOMAC provides no mechanism to allow a process to increase its level. 2. Traditional UNIX access control mechanisms are not designed to prevent the flow of potentially dangerous data from low-integrity objects to high-integrity objects. That is, from files owned by one user to those owned by another - even to those owned by root. The Trojan ls scenario in the "Short Tour" section describes one well-known example of this vulnerability, and how LOMAC counters it. 3. Although many enhancements now exist, in its most basic form traditional UNIX depends on easily defeated authentication mechanisms to establish appropriate initial privilege levels. LOMAC assigns privilege levels to processes based on their reading behavior. As described above, the effect of LOMAC's policy is to give the highest level of privilege only local administrative users, and the lowest level of privilege to all others, regardless of identity. LOMAC does not consider user identity; consequently, it does not depend on authentication. [ 7. Limits to LOMAC's Protection ] LOMAC embodies a trade-off between quality of MAC protection and compatibility. LOMAC's primary goal is to remain compatible with existing software while providing some useful MAC integrity protection. The Low Water-Mark MAC model supports this compatibility-first requirement. However, it the quality of protection it provides is not as great as that provided by more modern, less compatible, models. This issue is discussed at length in [FRA00]. This section presents the two well-known primary quality-of-protection drawbacks of the Low Water-Mark model: its enforcement of the principle of least privilege, and its reliance on trusted applications. The first drawback of the Low Water-Mark MAC scheme concerns the Principle of Least Privilege, which holds that a *good* MAC scheme should grant a subject the minimum set of privileges needed to do its job [SAL75]. Constraining a subject in this way minimizes the amount of damage the subject can cause should it become compromised. Low Water-Mark provides weaker constraints than some more modern models. The "LOMAC and Network Servers" section describes how LOMAC protects the level-2 part of the system by demoting network servers to level 1. Although LOMAC will prevent a compromised level-1 network server from harming the level-2 part of the system, LOMAC will not prevent such a server from doing harm in the level-1 remainder of the system. A compromised root-privileged network server could, for example, send kill signals to another level-1 server. The second drawback of the Low Water-Mark MAC scheme is its reliance on trusted applications. This reliance is a feature of hierarchical models like Low Water-Mark [BOE85]. It can be best demonstrated by a concrete example: Linux has a system log file, /var/log/messages, maintained by a system log daemon, syslogd, that reads log requests from a system log socket, /dev/log. Level-1 processes must be allowed to write to /dev/log, in order to provide an audit trail of their (possibly malicious) activities. Consequently, LOMAC's default policy assigns level 1 to /dev/log. Given the description of LOMAC's behavior presented so far, it would be reasonable to expect LOMAC to demote syslogd to level 1 upon reading its first log request from the level-1 /dev/log socket. If syslogd is running at level 1, then the /var/log/messages must also be at level 1 in order to allow syslogd to deposit its log messages. However, this scenario presents a practical problem. Malicious users often seek to erase incriminating audit trails from the system log object in order to cover their tracks. In order to prevent this erasure, LOMAC must assign level 2 to /var/log/messages. But this would raise its own problem: a level-1 syslogd cannot write to a level-2 /var/log/messages. The conflicting requirements for a log /dev/log and a high /var/log/messages seem irreconcilable. LOMAC solves this problem by adding the system log daemon, syslogd, to its list of "trusted" programs. A process that runs a trusted program gains no extra privileges, except that LOMAC will never demote it, regardless of what it reads. This exception allows a level-2 syslogd to read a level-1 /dev/log without being demoted, thereby enabling it to subsequently write to a level-2 /var/log/messages. The word "trusted" is meant to describe programs that have been formally verified, providing some assurance that they will not abuse their additional privileges. Unfortunately, no such argument exists for Linux's syslogd. If a malicious user found some way to compromise syslogd, perhaps by exploiting a buffer overflow or some other bug, they might gain control of a level-2 process - the LOMAC equivalent of gaining "root" privilege in a traditional UNIX system. Because of this danger, and the difficulty of producing formally verified trusted programs, it is important to minimize the use of trusted programs. LOMAC's default policy considers the following programs to be trusted: syslogd /* the main system log daemon */ minilogd /* a log daemon for early runlevels */ mount /* so we can mount NFS despite the required net read */ sshd /* allow administrators to log in to level-2 sessions remotely */ cardmgr /* avoid tmp-related demotion for pump */ pump /* pump is client-side DHCP agent, must read net and write /etc */ lup /* LOMAC's trusted upgrade program */ The security of a LOMAC system can be improved by running as few of these programs as possible. The latest list of trusted programs can be found in lomac_tpl.c . More information on LOMAC's use of trusted programs to allow administration can be found in the next section. [ 8. Administrative Loopholes ] Sections 3 and 5 describe how LOMAC ensures that all processes which read from the network wind up at level 1, where they are unable to modify level-2 files or signal level-2 processes. LOMAC also ensures that files created by these level-1 processes must also be at level 1. By confining these processes to level 1, LOMAC protects the integrity of the level-2 part of the system. However, this confinement also prevents two kinds of useful activities: remote administration and the installation of downloaded software. These two activities are inherently dangerous - there is a fine line between remote administration and remote compromise, and between the installation of downloaded software and the installation of backdoors and Trojan horses. Allowing these activities involves some risk. However, preventing these activities makes system running LOMAC difficult to use. LOMAC implements a compromise between the elimination risk and ease-of-use using trusted programs that provide a controlled way to perform remote administration and the installation of downloaded software. Administrators can use LOMAC's "lup" program to help them install downloaded software. The lup program is LOMAC's trusted file upgrader. It permits a level-2 user to "upgrade" a level-1 file, that is, to copy the data contained in a level-1 file into /root/, which is a level-2 file. Administrators can download and build software in the level-1 part of the system, and then use lup to move the resulting binaries to the level-2 part, where they are to be installed. (This is, in fact, how the author develops and tests new versions of LOMAC.) Note that there is some risk to using lup to upgrade downloaded software: If the downloaded software contains a Trojan horse, moving it to the level-2 part of the system with lup effectively bypasses LOMAC's defenses. Level-1 users cannot use lup to upgrade files. When lup is executed by a level-2 user, LOMAC's trust mechanism enables lup to read level-1 files without being demoted to level 1. There is nothing special about the lup program itself - it is essentially a simplified version of cp that logs its every use to /var/log/secure. When executed by a level-1 user, lup will be unable to write to level-2 files, regardless of LOMAC's trust. Note that software installation does not always require lup. See the next section for more information. Administrators can use ssh to log in remotely as root on a system running LOMAC and still get a level-2 session. LOMAC implements this exception to its "all network services run at level-1" rule by trusting sshd. Note that allowing sshd to serve level-2 remote login sessions involves some risk - administrators must guard their keys and passwords carefully. Note also that non-root users cannot use sshd to gain a level-2 session under LOMAC's default configuration. As with local logins, non-root ssh sessions are demoted to level-1 as soon as the user's shell reads a level-1 resource file, such as .cshrc . [ 9. Installing New Software ] In some cases, LOMAC's integrity protection mechanism will require you to use the lup program before installing new software packages. LOMAC does not interfere with the installation of new software packages from CD-ROM, because the directory /mnt/cdrom is at level 2, as will be any software package collections mounted under it. However, LOMAC will force you to save software packages downloaded from the network to level-1 files. Installing level-1 software packages may or may not require the use of the lup program, depending on where you ultimately want to install the binaries. There are two cases: 1. LOMAC will not interfere if you want to install under /usr/local, /home, or in some other level-1 area of the filesystem; you will not need to use lup in those cases. 2. However, if you ultimately want to install the binaries in a level-2 area of the filesystem (/bin, /sbin, /lib, all of /usr except for /usr/local), you will need to lup the software package to a level-2 file before installing. The level of any file in the filesystem can be determined by consulting the following table. Given a target pathname, search through the table, from top to bottom. When you find a table entry with a pathname that is a prefix of your target pathname, the level of a file named by your target pathname is that table entry's level. There is one exception to this rule: if your target pathname matches an entry pathname exactly, and the entry has a "children of" modifier, ignore the match and move on to the next table entry. Modifier Pathname level ---------- --------------------- ----- /var/run/ftp.pids-all 1 /var/log/messages 2 /var/log/lastlog 2 /var/log/secure 2 /dev/printer 1 /var/lib/nfs 2 /var/lib/rpm 2 /home/httpd 2 /home/samba 2 /mnt/cdrom 2 children of /usr/local 1 /home/ftp 2 /dev/log 1 children of /usr/src 1 children of /usr/tmp 1 children of /var/lib 1 /var/lib 2 children of /var/log 1 /var/log 2 /var/run 2 children of /home 1 children of /mnt 1 children of /tmp 1 children of /var 1 / 2 For example, /home/tfraser is level 1, due to the table entry for /home. /home, however, is level 2, due to the entry for /. Of course, if you have a running LOMAC-enhanced kernel, you can use the "lls" program to determine the levels of files directly. This mapping between filenames and levels, coupled with the list of trusted programs, effectively describes LOMAC's default policy. The latest mapping of filenames to levels is encoded in lomac_plm.c . [ 10. Performance ] This section discusses the results of two performance benchmarks run on LOMAC v0.3 with the path "/usr/src" added to its path-level map in lomac_plm.c. (The v0.3 LKM lacked this path, and /usr/local. Other than its version number, it is otherwise identical to the v1.0 LKM.) The first benchmark involved measuring the time taken to complete a "make" of the Linux kernel source on a system running the Linux 2.2.12 kernel as configured by the RedHat 6.1 distribution. During the tests, crond and atd were disabled, the network was physically disconnected, and the mouse was overturned. The hardware was an Intel Pentium II 450MHz with 256 MB of RAM. At no point during testing did the CPU utilization exceed 63%. "make clean" was executed between runs of "make" timed with /usr/bin/time. The results of the first run in each configuration (LOMAC, non-LOMAC) were discarded to avoid inconsistencies introduced by the filesystem cache. Kernel build (make only) WITHOUT LOMAC WITH LOMAC trial elapsed time (s) trial elapsed time (s) 1 442.16 1 444.35 2 442.21 2 444.35 3 442.15 3 444.42 4 442.18 4 444.36 5 442.19 5 444.38 average: 442.18 average: 444.37 stddev: 0.02 stddev: 0.03 The percentage difference is near one-half of a percent in favor of WITHOUT LOMAC - a good result. However, building the kernel requires a considerable amount of computation and a relatively small amount of I/O. Since LOMAC slows the I/O and not the computation, any performance penalty introduced by LOMAC is heavily de-emphasized by this benchmark. The second benchmark involved measuring the maximum rate at which an HTTP server could reply to requests for its root page running WITH and WITHOUT LOMAC. The HTTP client machine had hardware identical to the test machine in the previous benchmark, and was running a Linux 2.2.5 as configured by the RedHat 6.0 distribution. It used httpef-0.8 to generate HTTP requests. The server machine had an Intel Pentium 100MHz with 64MB RAM running Linux 2.2.12 as configured by the default "server" install of the RedHat 6.1 distribution. The HTTP server was Apache/1.3.9 (Unix) (Red Hat/Linux). It served the small default root web page provided with the distribution. The client and server machines were directly connected via a crossover Ethernet cable. Both machines had 10BaseT Ethernet cards. For each trial, httperf made 100000 requests with timeouts of 5 seconds. Trials were made at various request rates until the rate which produced the maximum average (that is, average over the duration of the trial) server reply rate was found. average average client server request/s replies/s sttdev timeouts --------- --------- ------ -------- WITHOUT LOMAC 133 133.0 1.7 0 134 134.0 1.6 0 << maximum 134 server replies/s 135 89.2 18.6 33733 WITH LOMAC 126 126.0 2.4 0 127 127.0 1.9 0 << maximum 127 server replies/s 128 95.6 18.9 24811 This resulted in an approximately 5% advantage for WITHOUT LOMAC. This is a much more difficult benchmark that the first, since the trials are almost entirely small I/O requests without computation - read a request from the network, read the file from the filesystem, write the file to the network. Consequently, this benchmark might be close to a worst-case analysis of LOMAC's performance penalty on realistic workloads. A more recent set of benchmark results exists for the v1.1.0 version of LOMAC, showing a roughly 3% penalty on a kernel-building macrobenchmark, no measurable penalty on a WebStone httpd latency and throughput macrobenchmark, and penalties ranging from 0.2-16.4% on a series of UNIXBench microbenchmarks. The full results of these benchmarks will appear in this manual once they are published in June, 2001 [FRA01]. [ 11. Related Projects ] This section compares LOMAC with a number of other projects that are concerned (at least in part) with adding MAC to open-source UNIX-like operating systems. The comparisons focus on each project's ability to support MAC-based integrity protection, and the cost of this protection in terms of compatibility with existing software, configurations, and operational practices. The projects discussed below demonstrate two strategies for providing integrity protection with MAC. LOMAC provides an example of the first strategy by conceptually dividing the entire system into a series of integrity levels and enforcing rules to ensure that potentially corrupting data cannot move from low-integrity levels to high-integrity levels. As described in section 3, this "ordered-levels" strategy provides a strong defense against Trojan horses. The second strategy takes a different approach that focuses on individual application programs - particularly root-privileged network servers. Projects based on the second strategy enforce rules that limit the resources available to application programs to the absolute minimum set required for them to function properly. Although this "least privilege" strategy does not necessarily prevent the spread of Trojan horses as described in section 3, it does severely limit the ability of compromised network servers to do harm. As described in section 7, LOMAC's ordered-levels approach does not perform well in this regard - a compromised level-1 network server is free to corrupt other level-1 processes and files. A protection mechanism based on the least-privilege strategy would limit the harm caused by compromised servers to a much smaller set of resources. Both the ordered-level and least-privilege strategies provide some useful integrity protection. An optimal solution might use both strategies simultaneously. In fact, mechanisms based on Type Enforcement (TE) model [BOE85] or its derivative Domain and Type Enforcement (DTE) [BAD95] can enforce policies that make use of both strategies. However, doing so raises compatibility issues: In order to implement an ordered-level scheme, the protection mechanism must not allow privileged high-integrity processes to read low-integrity files without demoting them, as LOMAC does. However, TE does not provide a mechanism for demoting processes on read operations. Consequently, TE-based ordered-level policies are forced to prevent privileged high-integrity processes from reading low-integrity files at all. As a result, the privileged high-integrity administrative users on such systems must be blind to all low-integrity files, such as low-integrity user directories, downloads, or email - an arrangement that is very unusual from a traditional UNIX perspective. Because of this compatibility cost, all of the TE-based projects listed below focus on providing protection according to the least-privilege strategy, and do not provide examples of the ordered-level strategy, even though their mechanisms may be capable of doing so. A list of short project descriptions follows. Each entry in the list describes a project's theoretical capabilities without consideration for the completeness and quality of the actual source code. After the list, there is a table which summarizes the comparisons between LOMAC and these related projects. I encourage readers to send me corrections for any errors and omissions they find in this section. 1. Beattie MAC http://users.ox.ac.uk/~mbeattie/linux Beattie MAC implements an integrity-oriented form of MAC in a kernel patch and a filesystem module. 2. FreeDTE FreeDTE is NAI Lab's implementation of DTE in the FreeBSD kernel, along with some supporting modified user-space applications. FreeDTE has not, to date, been publicly released. 3. Generic Software Wrappers Toolkit ftp://ftp.tislabs.com/pub/wrappers NAI Labs' Generic Software Wrappers project has produced a toolkit for constructing abstract security enhancements called Wrappers, which are similar in purpose to SCC's Kernel Hypervisors, also listed here. The toolkit provides a life-cycle abstraction for managing the relationships between Wrappers and processes, and a language for writing Wrappers with the potential for cross-platform portability. The toolkit currently supports Linux, FreeBSD, Solaris, and (to some extent) Windows NT. Like LOMAC, it uses an LKM to ensure compatibility. Unlike LOMAC, the toolkit is a general tool for constructing security enhancements, rather than an implementation of a particular MAC scheme. I imagine that something like LOMAC could be implemented with Generic Software Wrappers. 4. Janus http://www.cs.berkeley.edu/~daw/janus/ Janus is a tool for confining potentially dangerous processes, such as privileged servers and web-browser helper applications. It was originally developed on Solaris using that operating system's user-space process debugging support. There is now a Linux port, as well. 5. Kernel Hypervisors http://www.securecomputing.com/khyper/index.html Secure Computing Corporation's Kernel Hypervisors are LKMs which "wrap" applications by replacing a subset of the kernel's system call interface with their own augmented interface. The augmented interface may filter calls in order to perform access control, or may augment calls with new functionality, such as auditing. Since it relies on LKMs, this project has a compatibility advantage similar to LOMAC's. Furthermore, Kernel Hypervisors are a general tool that can be used to implement a wide variety of security-related functionality. I imagine that Kernel Hypervisors could be used to implement something like LOMAC. A Linux prototype is available. 6. Linux Intrusion Detection/Defense System (LIDS) http://www.lids.org LIDS is a kernel patch that provides some access control and intrusion detection functionality. 7. Medusa DS9 http://medusa.fornax.sk Medusa DS9 provides a mechanism for implementing general security functionality, including MAC. It is implemented as a small Linux kernel patch that provides a service interface to a user-space security daemon. This security daemon implements the majority of the desired security functionality, keeping these details out of the kernel. Currently, a security daemon called "constable" has been implemented that acts as an authorization server. I presume that it would be possible to implement a security daemon with functionality similar to LOMAC. 8. Pitbull LX http://www.argus-systems.com/products/white_paper/lx/ Pitbull LX implements a form of TE similar to the one found in SubDomain (also listed here). Like SubDomain, it uses of a small kernel patch to support its otherwise LKM-based implementation. Pitbull LX uses PAM to avoid TE's usual requirement user-space application modification. 9. Remus Like LOMAC, the Remus LKM uses interposition at the system call interface to implement its access control functionality, and can be applied to unmodified Linux kernels. Remus is designed to confine root-privileged and setuid processes by mediating their use of security-relevant system calls. Administrators can configure Remus to allow confined processes to make only certain calls with certain parameters. 10. Rule Set Based Access Control (RSBAC) for Linux http://www.compuniverse.com/rsbac Unlike LOMAC's focus on its single Low Water-Mark scheme, RSBAC is a Linux kernel patch that provides generalized support for many MAC policy models, where the decision-making functions for each model are implemented in a separate module. Modules already exist for several models, including the Bell-La Padula (MULTICS) model and a Role Compatibility model similar to TE. 11. SAIC DTE http://research-cistw.saic.com/cace/dte.html SAIC is implementing DTE in Linux by modifying the kernel source. 12. Security-Enhanced Linux (selinux) http://www.nsa.gov/selinux The National Security Agency's Security-Enhanced Linux implements TE by modifying the kernel source, and the source of some supporting applications. 13. SubDomain http://immunix.org SubDomain implements a form of MAC similar to DTE; its configuration retains the notion of domain, but does not make use of types. SubDomain makes use of a small kernel patch to support its otherwise LKM-based implementation. 14. VXE http://www.intes.odessa.ua/vxe VXE enforces the principle of least privilege by confining processes (such as root-privileged network servers) to virtual environments in which only the minimum set of resources required for normal operation are available. VXE virtual environments are implemented in LKMs and operate with the help of a Linux kernel patch. Since these virtual environments may be tailored specifically to the resource needs of a particular application, VXE provides fine-grained support for restricting applications to least privilege. 15. William & Mary DTE http://www.cs.wm.edu/~hallyn/dte/ This is an implementation of DTE accomplished by modifying the kernel source from the college of William & Mary. The following compares these projects according to several criteria: general wrappers: projects that provide general kernel extension support that can be used to implement a wide variety of security functionality, including access control and intrusion detection. access control: projects that provide access control functionality. intrusion detection: projects that provide additional functionality, such as intrusion detection. patch: projects that are implemented with kernel patches. module: projects that are implemented in LKMs. general access intrusion project wrappers control detection patch module ------------------------- ---------- --------- ---------- ------- ------ Beattie MAC x x Generic Software Wrappers x x Immunix/SubDomain x x x x Janus (Linux) x x Kernel Hypervisors x x LIDS x x x LOMAC x x Medusa DS9 x x x Pitbull LX x x x Remus x x RSBAC x x SAIC DTE x x SELinux x x VXE x x William&Mary DTE x x The frameworks provided by the "general wrappers" projects could conceivably be used to implement LOMAC-like functionality. However a comparison of Generic Software Wrappers and LOMAC performance benchmarks suggests that a direct implementation may be more efficient [FRA99,FRA01]. Projects that, like LOMAC, avoid the use of kernel patches have the potential to be highly-compatible with existing systems. [ 12. The LOMAC License ] LOMAC is Free software available under a the following license from http://opensource.nailabs.com/lomac. Copyright (c) 2001 NAI Labs, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of NAI Labs, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [ References ] [BAD95] L. Badger, et. al., "A Domain and Type Enforcement UNIX Prototype," Proceedings of the 5th USENIX UNIX Security Symposium, June, 1995. Also USENIX Computing Systems, Vol. 9, No. 1, Winter 1996. [BIB77] K. J. Biba, "Integrity Considerations for Secure Computer Systems," Electronic Systems Division, Hanscom Air Force Base, Bedford, MA, April 1977, pages 27-31. [BOE85] W. E. Boebert and R. Y. Kain, "A Practical Alternative to Hierarchical Integrity Policies," Proceedings of the 8th National Computer Security Conference, 1985. LWM and Trust: pages 19-20. Assured Pipelines: pages 20-25. [FRA99] Fraser, Badger, and Feldman, "Hardening COTS Software with Generic Software Wrappers," Proceedings of the 1999 IEEE Symposium on Security and Privacy, May, 1999. [FRA00] T. Fraser "LOMAC: Low Water-Mark Integrity Protection for COTS Environments", Proceedings of the 2000 IEEE Symposium on Security and Privacy, 2000. [FRA01] T. Fraser, "LOMAC: MAC You Can Live With", Proceedings of the FREENIX Track: USENIX Annual Technical Conference, Boston, Massachusetts, June, 2001. [SAL75] J. H. Saltzer and M. D. Schroeder, "The Protection of Information in Computer Systems," Proceedings of the IEEE Vol. 63(9), September 1975, pages 1278-1308. Also summarized in Dorothy E. Denning, "Cryptography and Data Security," Addison-Wesley, 1982, page 206. BSD is a trademark of the University of California, Berkeley, California. FreeBSD is a Registered Trade Mark of FreeBSD, Inc. and Walnut Creek CDROM. Pentium and Pentium II are Registered Trade Marks of the Intel Corporation. Pitbull LX is a Registered Trade Mark of Argus Systems Group, Inc. Red Hat is a Registered Trade Mark of Red Hat, Inc. Solaris is a Registered Trade Mark of Sun Microsystems, Inc. System V is a trademark of the American Telephone and Telegraph Company. UNIX is a Registered Trade Mark of The Open Group. Windows NT is a Registered Trade Mark of the Microsoft Corporation.