Next Previous Contents

3. Summary of Linux Security Features

Before discussing guidelines on how to use Linux security features, it's useful to know what those features are from a programmer's viewpoint. This section briefly describes those features; if you already know what those features are, please feel free to skip this section.

Many programming guides skim briefly over the security-relevant portions of Linux and skip important information. In particular, they often discuss ``how to use'' something in general terms but gloss over the security attributes that affect their use. Conversely, there's a great deal of detailed information in the manual pages about individual functions, but the manual pages sometimes obscure the forest with the trees. This section tries to bridge that gap; it gives an overview of the security mechanisms in Linux that are likely to be used by a programmer. This section has more depth than the typical programming guides, focusing specifically on security-related matters, and points to references where you can get more details. Unix programmers will be in familiar territory, but there are several Linux extensions and specifics that may surprise them. This section will try to point out those differences.

First, the basics. Linux is fundamentally divided into two parts: the Linux kernel (along with its kernel modules) and ``user space'' in which various programs execute on top of the kernel. When users log in, their usernames are mapped to integers marking their ``UID'' (for ``user id'') and the ``GID''s (for ``group id'') that they are a member of. UID 0 is a special privileged user (role) traditionally called ``root,'' who can overrule most security checks and is used to administrate the system. Processes are the only ``subjects'' in terms of security (that is, only processes are active objects). Processes can access various data objects, in particular filesystem objects (FSOs), System V Interprocess Communication (IPC) objects, and network ports. The next few sections detail this.

3.1 Processes

In Linux, user-level activities are implemented by running processes. Many systems support separate ``threads''; in Linux, different threads may be implemented by using multiple processes (the Linux kernel then performs optimizations to get thread-level speeds).

Process Attributes

Every process has a set of security-relevant attributes, including the following:

If you really need to know exactly what attributes are associated with each process, examine the Linux source code, in particular include/linux/sched.h's definition of task_struct.

POSIX Capabilities

Linux version 2.2 added internal support for ``POSIX Capabilities.'' POSIX capabilities supports some splitting of the privileges typically held by root into a larger set of more specific privileges. POSIX capabilities are defined by a draft IEEE standard; they're not unique to Linux but they're not universally supported by other Unix-like systems either. When Linux documentation (including this one) says ``requires root privilege'', in nearly all cases it really means ``requires a capability'' as documented in the capability documentation. If you need to know the specific capability required, look it up in the capability documentation.

The eventual intent is to permit capabilities to be attached to files in the filesystem; as of this writing, however, this is not yet supported. There is support for transferring capabilities, but this is disabled by default. Linux version 2.2.11 added a feature that makes capabilities more directly useful, called the ``capability bounding set.'' The capability bounding set is a list of capabilities that are allowed to be held by any process on the system (otherwise, only the special init process can hold it). If a capability does not appear in the bounding set, it may not be exercised by any process, no matter how privileged. This feature can be used to, for example, disable kernel module loading. A sample tool that takes advantage of this is LCAP at http://pweb.netcom.com/~spoon/lcap/.

More information about POSIX capabilities is available at ftp://linux.kernel.org/pub/linux/libs/security/linux-privs.

Process Creation and Manipulation

Processes may be created using fork(2), the non-recommended vfork(2), or the Linux-unique clone(2); all of these system calls duplicate the existing process, creating two processes out of it. A process can execute a different program by calling execve(2), or various front-ends to it (for example, see exec(3), system(3), and popen(3)).

When a program is executed, and its file has its setuid or setgid bit set, the process' EUID or EGID (respectively) is set to the file's. Note that under Linux this does not occur with ordinary scripts such as shell scripts, because there are a number of security dangers when trying to do this with scripts (some other Unix-like systems do support setuid shell scripts). As a special case, Perl includes a special setup to support setuid Perl scripts.

In some cases a process can affect the various UID and GID values; see setuid(2), seteuid(2), setreuid(2), setfsuid(2). In particular the SUID attribute is there to permit trusted programs to temporarily switch UIDs. If the RUID is changed, or the EUID is set to a value not equal to the RUID, the SUID is set to the new EUID. Unprivileged users can set their EUID from their SUID, the RUID to the EUID, and the EUID to the RUID.

The FSUID process attribute is intended to permit programs like the NFS server to limit themselves to only the filesystem rights of some given UID without giving that UID permission to send signals to the process. Whenever the EUID is changed, the FSUID is changed to the new EUID value; the FSUID value can be set separately using setfsuid(2), a Linux-unique call. Note that non-root callers can only set FSUID to the current RUID, EUID, SEUID, or current FSUID values.

3.2 Filesystem

Filesystem objects (FSOs) may be ordinary files, directories, symbolic links, named pipes (FIFOs), sockets, character special (device) files, or block special (device) files (this list is shown in the find(1) command). Filesystem objects are collected on filesystems, which can be mounted and unmounted on directories in the filesystem; filesystems may have slightly different sets of access control attributes and access controls can be affected by options selected at mount time.

Filesystem Object Attributes

Currently ext2 is the most popular filesystem on Linux systems; it supports the following attributes on each filesystem object:

Many of these values can be influenced at mount time, so that, for example, certain bits can be treated as though they had a certain value (regardless of their values on the media). See mount(1) for more information about this. Some filesystems don't support some of these access control values; again, see mount(1) for how these filesystems are handled.

There is ongoing work to add access control lists (ACLs) and POSIX capability values to the filesystem, but these do not exist in stock Linux 2.2.

Creation Time Initial Values

At creation time, the following rules apply. When a filesystem object (FSO) is created (e.g. via creat(2)), the FSO's UID is set to the process' FSUID. The FSO GID is usually set to the process' FSGID, though if the containing directory's setgid bit is set or the filesystem's ``GRPID'' flag is set, the FSO GID is set to the GID of the containing directory. This special case supports ``project'' directories: to make a ``project'' directory, create a special group for the project, create a directory for the project owned by that group, then make the directory setgid: files placed there are automatically owned by the project. Similarly, if a new subdirectory is created inside a directory with the setgid bit set (and the filesystem GRPID isn't set), the new subdirectory will also have its setgid bit set (so that project subdirectories will ``do the right thing.''); in all other cases the setgid is clear for a new file. FSO basic access control values (read, write, execute) are computed from (requested values & ~ umask of process). New files always start with a clear sticky bit and clear setuid bit.

Changing Access Control Attributes

You can set most of these values with chmod(2) or chmod(1), but see also chown(1), chgrp(1), and chattr(1).

Note that in Linux, only root can change the owner of a given file. Some Unix-like systems allow ordinary users to change ownership, but this causes complications. For example, if you're trying to limit disk usage, allowing such operations would allow users to claim that large files actually belonged to some other ``victim.''

Using Access Control Attributes

Under Linux and most Unix-like systems, reading and writing attribute values are only checked when the file is opened; they are not re-checked on every read or write. A large number of calls use these attributes, since the filesystem is so central to Linux. This includes open(2), creat(2), link(2), unlink(2), rename(2), mknod(2), symlink(2), and socket(2).

Filesystem Hierarchy

Over the years conventions have been built on ``what files to place where''; please follow them and use them when placing information in the hierarchy. A summary of this information is in hier(5). More information is available on the Filesystem Hierarchy Standard (FHS), which is an update to the previous Linux Filesystem Structure standard (FSSTND); see http://www.pathname.com/fhs

3.3 System V IPC

Linux supports System V IPC objects, that is, System V message queues, semaphore sets, and shared memory segments. Each such object has the following attributes:

When accessing such objects, the rules are as follows:

Note that root, or a process with the EUID of either the owner or creator, can set the owning UID and owning GID and/or remove the object. More information is available in ipc(5).

3.4 Sockets and Network Connections

Sockets are used for communication, particularly over a network. Socket(2) creates an endpoint for communication and returns a descriptor; see socket(2) for more information and cross-references to other relevant information. Note that binding to TCP and UDP local port numbers less than 1024 requires root privilege in Linux (binding to a remote port number less than 1024 requires no special privilege).

3.5 Quotas and Limits

Linux has mechanisms to support filesystem quotas and process resource limits. Be careful with terminology here, because they both have ``hard'' and ``soft'' limits but the terms mean slightly different things.

You can define storage (filesystem) quota limits on each mountpoint for the number of blocks of storage and/or the number of unique files (inodes) that can be used by a given user or a given group. A ``hard'' quota limit is a never-to-exceed limit, while a ``soft'' quota can be temporarily exceeded. See quota(1), quotactl(2), and quotaon(8).

The rlimit mechanism supports a large number of process quotas, such as file size, number of child processes, number of open files, and so on. There is a ``soft'' limit (also called the current limit) and a ``hard limit'' (also called the upper limit). The soft limit cannot be exceeded at any time, but through calls it can be raised up to the value of the hard limit. See getrlimit(), setrlimit(), and getrusage().

3.6 Audit

Currently the most common ``audit'' mechanism is syslogd(8). You might also want to look at wtmp(5), utmp(5), lastlog(8), and acct(2). Some server programs (such as the Apache web server) also have their own audit trail mechanisms.

3.7 PAM

When authenticating, most Linux systems use Pluggable Authentication Modules (PAM). This permits configuration of authentication (e.g., use of passwords, smart cards, etc.). PAM will be discussed more fully later in this document.


Next Previous Contents