.NH 1 Introduction .PP In a .I "multilevel secure operating system all data files have security classification labels. .I "Mandatory controls assure that no combination of computer programs may copy data from a file into another with a lesser label. Thus the normal flow of data is .I up : as data move from place to place, the classification label must not decrease as a result of negligent or unauthorized action. However, certain .I privileged programs are allowed to copy data .I down , that is, to declassify or .I downgrade data. .PP We describe a simple, but thorough, way to add mandatory controls to a .UX operating system without severely impairing the basic nature and usefulness of the system. This paper recounts the modifications to the calling interface to the system kernel. Using this kernel, we have built a multilevel secure system called IX, which includes tools for authentication, administration of privilege, safe networking to untrusted machines, and management of multilevel windowed terminals. Multilevel secure networking should fit well within the model. .PP Higher-level aspects of the IX system are described in the accompanying paper, ``Multilevel security in the .UX tradition.'' Based on the Tenth Edition .UX research system, commonly known as v10, |reference(v10) IX was built to experiment with new security mechanisms. It bears no direct relationship to security features in production systems from AT&T. |reference(SVMLS) |reference(bendet) .PP Section \*(yE covers the ideas, \*(yJ gives details. The reader is expected to be fully familiar with .UX system calls. The technical details are deliberately concise, as they are intended as an implementation reference. Additional expository material is relegated to fine print. .NH 1 The model .XL yE .PP Each file or process has a .I label, shared by all data in it. For technical reasons given in \*(yh and \*(yd, seek pointers and ceilings, which are defined below, also have labels. The labels form a (slightly augmented) mathematical lattice, a structure rich enough to express both multilevel and categorical, or compartmented, classification systems. Whenever a system call causes a transfer of data, the labels are checked to ensure that data only flows up the lattice. .PP The security of data explicitly passed between labeled entities, in particular from process to file and vice versa, is safeguarded. Examples of such data are bytes transmitted by .I read and .I write system calls and bits set by .I chmod . Implicitly set inode data, such as modification times and link counts, are protected as far as possible without making the system unusable. Special consideration is given to external media such as terminals or tape drives, where authentication protocols may be required in order to determine proper labels. To reduce overhead in label checking we cache the results of label checks involved with file descriptors. .PP Other ways of communicating information, including but not limited to error returns from system calls, file change times, the identity of open files, and otherwise inferred knowledge (e.g. the Denning example in \*(yT) we declare to be .I "covert channels. Just which covert channels to leave unplugged we have decided by balancing risk versus utility and compatibility. At worst, covert channels of nontrivial bandwidth provide routes for leaks, not for burglaries. As extremely abnormal behavior is required to exploit them (see notes in \*(yj), systematic use of covert channels should be easy to detect by auditing. .PP In effect we have divided information transfers into ``lawful'' transfers, which honor the Department of Defense ``Orange Book'' criteria,|reference( %type book %title Department of Defense Trusted Computer System Evaluation Criteria %author Department~of~Defense~Computer~Security~Center %publisher US Department of Defense %address Fort Meade, MD %date 15 August 1983) and covert channels. .PP We attempt to minimize label inflation by keeping all processes and files at their minimum allowable labels as long as possible. A program's label may start low and drift up as necessary to a maximum value authorized for its user. The label rises only when needed to allow reading of inputs. When a running program's label rises, the labels of its output files may also rise correspondingly. .PP A few system programs must be exempt from the usual label checking described above. Such programs are trusted with special .I privileges, which give them the ability, for instance, to set the label on a user's terminal at login time, read foreign tapes, perform backups\(emand assign privilege. These privileges are zealously guarded: a program cannot pass its privileges to another and privileged programs cannot be modified. .PP Privileged processes, which have the right to break the rules, must know that they are doing so safely and are not allowing unwashed programs to piggyback on the privilege. For example, the login program, which authenticates a user's identity and then sets security labels accordingly, needs to receive the user's password via a path immune to eavesdropping by untrusted agents. (Security clearance is not at issue; no distinguishing security label to guarantee the user's privacy can be established before the user has been identified.) .PP To obtain a private path, such as that necessary for logging in, a process may assert process exclusive, or .I pex, access to any file or pipe. On a pipe, the processes at both ends are apprised of each other's trustedness. On an external connection, an associated .I "stream identifier may be queried for other assurances, such as whether it is understood to be physically secure. .PP An audit mechanism records security-related events. Audit records are collected mandatorily, to an administratively determined level of detail. Extra audit records may be volunteered, typically by privileged programs, to capture data (e.g. password rejections) that happen outside the kernel. .LP In summary, IX has five major security mechanisms: .IP 1. The usual .UX permission scheme provides discretionary controls. The superuser can override permissions other than write permission. .IP 2. The label scheme provides mandatory controls. Label inequalities are maintained regardless of user- or group-ids. .IP 3. The privilege scheme guards the administration of the label scheme (and of itself). .IP 4. Process exclusive streams allow private transmission of data among privileged processes and files. .IP 5. Detailed auditing allows security surveillance and furnishes post-mortems in case of trouble. .PP Each process has a .I ceiling, a maximum label that it may read or write, first set when the user logs in. Ceilings prevent lowly users from injecting noise into high places. Ceilings also prevent lowly users from raising their processes to high levels where they might use covert channels to pry out secrets. Only with the (possibly unwitting) collusion of a (possibly duped) cleared user can covert channels be used to see above the ceiling. .PP Each system call is identified as a .I "read action, a .I "write action, or both, depending on the direction of data transfer. The destination of a read action is a process; the destination of a write action is a file. A security check is made at each system call. When a check is violated, the violation may sometimes be prevented by changing a label, otherwise the system call aborts. Thus, in the absence of privilege, the system obeys two golden rules, which are elaborated in \*(y5. .IP .B "Upward flow. Only upward data flow is permitted. If possible, the label of the destination of an action is raised to allow the action to proceed. .IP .B "Impenetrable ceilings. A process label must stay under the process ceiling. .ig .LP For efficiency, the results of the checks associated with file descriptors are stored in .I safe-to-read and .I safe-to-write bits: .IP Whenever a file label changes, the safe-to-read bits are cleared in all file descriptors open on that file, forcing fresh security check computations on reads from the file. .IP Whenever a process label changes, the safe-to-write bits are cleared in all file descriptors open in that process, forcing fresh security check computations on writes from the process. .. .PP Each file system has a ceiling label, distinct from the labels of any file in it. No information with a label above the ceiling can be transferred to or from the file system. The ceiling, which may be understood as a process label on a virtual file manager, may be used to prevent import or export of sensitive labels via remote file systems or removable media. In addition, the file system ceiling may be used to deny privilege to executable files obtained from such sources. .PP We understand the system call .I exec to extinguish a process and make in its place a new .I empty process. To keep labels as low as possible, an empty process begins with a bottom label. If an empty process has arguments, its label may have to rise immediately to cover the label of its parent, the source of the arguments. It may have to rise further to cover the label of the initializing text file, and perhaps again to cover data that it reads. .NH 2 Terminology .XL zD .PP A .I file is anything that can have a file descriptor, or equivalently anything that can have an in-core inode: file system entries, pipes, and process images. An inode is deemed to be part of its file. An open file that is not a stream has a .I "seek pointer. A file descriptor $d$ names an association $(p,^s,^f)$ between process, seek pointer, and file. Given $d$, the corresponding process is denoted $p(d)$, the file $f(d)$, and the seek pointer $s(d)$. The file system that file $f$ resides in is denoted $FS(f)$. If $f$ is one end of a pipe, $f sup prime$ is the other end. $L(f,t)$, $L(p,t)$, $L(s,t)$ are the labels of a file, a process, and a seek pointer respectively at time $t$; $C(p,t)$ and $C(FS,t)$ are the ceilings of a process and file system. When only one time is under consideration, $t$ may be elided: $L(f)$, $L(p)$, $C(p)$, etc. .PP A .I "data flow occurs when bits are copied from one place (process, file, seek pointer, uarea) to another. Such flows, caused by system calls, are effectively atomic and are serializable. A nonatomic data transfer in a very long .I read or .I write is considered to be several data flows. The residence of data in an entity (usually a process or file) also constitutes data flow, called a .I "persistent flow, from the entity at one time to the entity at another time. .PP Transfer of information without direct replication of bits is not considered to be data flow. Most such transfers are sensed by error returns from system calls. Others are sensed by reading quantities that the system calculates: link counts, process numbers, resource levels, file access times, clock values, and so on. .PP Data flow from source $x$ to destination $y$ is symbolized $x~->~y$. .PP The symbols := and = mean assignment and the equality predicate respectively. .SP In the more formal parts of the paper fact is distinguished from supporting commentary, which looks like this. .NH 3 Summary of notations .LP .TS center; lll. Notation Meaning Reference $f,^r,^w$ file $d$ file descriptor \*(zD $p$ current process $q$ process $t$ time $s$ seek pointer \*(zD $FS$ file system \*(zD $x,^y$ labelable entity $YES$ label yes \*(zL $NO$ label no \*(zL $L(x,t),~L(x)$ label \*(zL $C(x,t),~C(x)$ ceiling \*(zL $Tk (x,t),~Tk (x)$ capability \*(zC $Uk (x,t),~Uk (x)$ license \*(zC $Tvec (x,t),~Tvec (x)$ capability vector \*(zC $Uvec (x,t),~Uvec (x)$ license vector \*(zC $Uvec sup 0 (x,t),~Uvec sup 0 (x)$ maximum file license \*(zB, \*(zC $Vvec (x,t),~Vvec (x)$ privilege vector \*(zC $H(f)$ pex-holding process \*(zA $APX(f)$ accept pex indicator \*(zA $X(f)$ pexity indicator \*(zA $AM(p)$ process audit mask \*(za $SAM$ system audit mask \*(za $PC(f)$ poison class \*(za $PM[i]$ poison mask \*(za .TE .NH 2 Labels .XL zL .PP A label can be any element of a given finite lattice $LL$, or the special symbol $YES$, or the special symbol $NO$. Let $LLstar ~=~ LL \(cu roman "{" YES , ^ NO roman "}"$ denote this set of possible labels. The lattice $LL$ is a design parameter. We have chosen the lattice of subsets of 480 elements, represented as vectors of 480 bits. .SP The bit vectors $000~<~001~<~011~<~111$ might represent the customary classification levels: unclassified, confidential, secret, top secret. Further bits might represent compartments: 000 100 for Iran, 000 010 for Nicaragua, 000 001 for submarine traffic, etc. Oliver North was cleared at least for 111 110. .PP Let the ordering relation on $LL$ be denoted $<=$, the meet operation $min$, the join operation $max$, bottom element $bottom$ and top element $top$. The only comparison predicates we use are $=$, $<=$, and $!<=$. The predicate $!<=$ means ``not $<=$'' or ``is not dominated by''; it should not be thought of as $>$. .PP A data flow $x~->~y$ is said to be .I up if $L(x) ~<=~ L(y)$. Otherwise the flow is .I down . .SP Up describes a $<=$ relation and down describes $!<=$. By always referring to the direction of flow, we avoid the common, but confusing, phrases ``write up'' and ``read down,'' both of which describe upward flow. .QE We extend the meaning of $<=$ to $LLstar$: for all $x$ in $LLstar$, $x ~ <= ~ YES$, $YES ~ <= ~ x$, $max (x,^YES )~=~min (x,^YES )~=~x$, and $max (x,^NO )~=~min (x,^NO )~=~NO$. For all $x$ in $LL$, $x ~ !<= ~ NO$ and $NO ~ !<= ~ x$. Also $NO~ !<=~ NO$. Note that $( LLstar , <= )$ is not a lattice, and that $<=$ is only partially transitive on $LLstar$ in that $L sub 1~<=~L sub 2$ and $L sub 2~<=~L sub 3$ imply $L sub 1~<=~L sub 3$ only if $L sub 2 ~member~LL$. .SP Label $YES$ (yes) is intended for files such as .CW /dev/null that may always be read or written. A place labeled $YES$ is amnesiac; what comes out is unrelated to what goes in. Label $NO$ (no) is intended for files that may never be read or written except by trusted processes. .NH 2 Privileges and superuser .XL zB .PP File permissions behave as always, except that superuser status does not automatically confer write permission. Historically restricted operations such as mounting a file system or changing userid are still reserved to the superuser. However, most such operations require privilege in addition to superuser status. .PP There are two classes of privileges, called capabilities and licenses. Privileges are stored with labels; system calls that set and retrieve labels handle privileges at the same time. .PP Users may be given .I licenses to perform security-related tasks. Licenses may persist across .I exec and can be given up at any time. To exercise a privilege, a process with a license for that privilege must be running a program marked with a corresponding .I capability. Thus, in general, sensitive actions can only be performed by trusted users using trusted software. .PP Files, too, may have licenses. The licenses of an executable file augment the inherited licenses of processes that execute the file. File licensing is limited by a permanent maximum file license $Uvec sup 0$; the effective set of licenses for file $f$ is $Uvec (f) and Uvec sup 0$. .SP File licensing is much like the classic set-userid mechanism. Any user who can execute a licensed program automatically enjoys the privileges of the program. Unlike the effective userid, however, a license obtained from a file on .I exec is not inherited by child processes. .ig .PP Privilege may be granted to every program through a permanent minimum capability $Tvec sup 0$. In this case any user with licenses $Uvec$ can exercise those privilege in any program, regardless of the trustedness of the program. .SP A highly secure system would best be run with minimum capabilities set to zero. Some maximum licenses, though, would be nonzero: File licensing would be permitted for certain privileges, so that trusted code may perform privileged acts for unprivileged users. But stringent control would be maintained over the most powerful privileges, especially $Tsetpriv$ and $Tsetlic$, which would only be exercisable by licensed users running trusted code. .. .PP Capabilities of a process are computed from the licenses inherited from its parent (ultimately from the initialization process) and from the capabilities and licenses of the program it is executing; see \*(yQ. The capabilities express the powers the process can acutally exercise. .SP For example, to set userid, a superuser process must have capability $Tuarea$ (\*(yQ); to initiate or change accounting, it must have capability $Tlog$; and to mount a file system or make an external medium accessible, it must have capability $Textern$. .NH 2 Ingredients .PP The following notions are added to the usual .UX model. .NH 3 Labels and ceilings .LP Each participant $x$ in data flow has a time-varying $LLstar$-valued label, $L(x,^t)$, written $L(x)$ when $t$ doesn't matter. Labels of processes and seek pointers are restricted to $LL$. .LP Each participant $x$ in data flow has a time-varying $LLstar$-valued ceiling, $C(x,^t)$, sometimes written $C(x)$. By convention all files in file system $FS$ share the same ceiling, called $C(FS)$, i.e. $C(f)~=~C(FS(f))$. By convention, any entity $x$ that lacks a specific ceiling has $C(x)~=~top$. .LP Each file system type has a default ceiling value. .LP Each file or process has a time-varying .I fixity attribute, $F(f)$ or $F(p)$, which governs the mutability of label $L(f)$ or $L(p)$, and takes on values .IP $LOOSE$: Label or fixity may change. .br $FROZEN$: Label may not change; fixity may change. .br $RIGID$: Fixity may not change; label may change only with privilege. .br $CONST$: Neither label nor fixity may change. .LP New system calls, .I setflab , .I fsetflab , .I getflab, .I fgetflab, .I setplab , .I getplab , set and query labels and privileges of files and processes; see \*(zT. .NH 3 Capabilities and licenses .XL zC .LP Each process or file has a set of time-varying boolean capabilities, further described in \*(yQ: $Tsetpriv (x,^t)$, $Tsetlic (x,^t)$, $Tnochk (x,^t)$, $Textern (x,^t)$, $Tuarea (x,^t)$, $Tlog (x,^t)$. The six predicates together constitute a bit vector $Tvec (x,^t)$. Predicates may be written $Tnochk (x)$, $Tvec (x)$, and so on, when time is unimportant. .SP Capabilities $Tvec (p)$ are rights of a process to override security policy. The capabilities of a process are limited by the capabilities $Tvec (f)$ of the currently executing file $f$ and are not inherited. .LP Each process or file has a set of boolean licenses $U k (x)$, subscripted like capabilities and together constituting a bit vector $Uvec (x)$. .LP The set of capabilities and licenses of a file or process are collectively known as privileges and are denoted $Vvec (f)$ or $Vvec (p)$. A .I trusted predicate, $T(x)$, is defined on files as the logical OR of all the privileges, .EQ T(f)~=~{size +2 or}from k^( Tk (f)^or^Uk (f)), .EN and on processes as the OR of the capabilities, .EQ T(p)~=~{size +2 or}from k^Tk (p). .EN .ig .LP Correspondingly subscripted .ig sets of .I "minimum capabilities $Tx sup 0$ with collective vector $Tvec sup 0$ and .. .I "maximum licenses $Ux sup 0$ with collective vector $Uvec sup 0$. .. .LP Each file system has a set of boolean .I "privilege masks $Tk (FS)$ and $Uk (FS)$, subscripted like capabilities, with collective vectors $Tvec (FS)$, $Uvec (FS)$, and $Vvec (FS)$. .LP Each file system type has a default privilege mask. .NH 3 Private paths .XL zA .LP Each open inode $f$ has a .I "pex state, comprising a .I "holding process $H(f)$, a boolean .I "accept pex indicator $APX(f)$, and a .I pexity indicator $X(f)$, which can take on three values: .IP $UNPEXED$: $H(f)$ is irrelevant. .br $PEXED$: Process $H(f)$ has exclusive access to $f$. .br $UNPEXING$: $f$ is unusable by any process until becoming $UNPEXED$. .LP A new family of IO controls manipulates the pex state; see \*(zP. .LP Each stream has a .I "stream identifier, which is an arbitrary string. Stream identifiers are retrieved by an IO control and set by a privileged IO control; see \*(zS. .SP In v10 and IX streams comprise pipes, terminals, and communication ports; pipes may be mounted in the file system. The stream identifier conventionally holds security-related information such as the trustedness and authentication record of a terminal port. .NH 3 Auditing .XL za .LP Each process $p$ has a .I "audit mask, $AM(p)$. A .I "system audit mask, $SAM$, determines the base level of auditing. Each file has a .I "poison class, $PC(f)$, which takes integer values in the range 0 through 3. For each poison class $i$ there is a .I "poison mask, $PM[i]$. .SP Process audit masks control auditing coverage and are inherited across fork and exec. The poison class of a file determines a poison mask that augments the audit mask of each process that deals with the file; see \*(yl. .LP Logging data is collected in a new kind of special file; see \*(yL. .LP A new system call .I syslog controls auditing; see \*(yl. .NH 3 Miscellaneous .LP There are two new file modes: .IP .CW S_IAPPEND forces all writing to occur at the end of the file and prevents truncation by .I creat . .IP .CW S_IBLIND makes a directory unreadable and immune to label checking; see \*(yb. .LP There are two new error return codes: .IP .CW ELAB is returned for security label violations; see \*(yT. .IP .CW EPRIV is returned for lack of privilege; see \*(yU. .LP A new signal, .CW SIGLAB, detects changes in labels of open files; see \*(yS. .LP The old signal .CW SIGPIPE may be triggered in a new way; see \*(yT. .LP Each file descriptor in each process has a .I safe-to-write bit, a .I safe-to-read bit, and an .I exempt bit; see \*(zk. .LP A new system call, .I unsafe, queries and resets safe-to-read and safe-to-write bits; see \*(y8. .LP A new system call, .I nochk, changes exempt bits; see \*(zk and \*(y8. .LP Two old system calls, .I seek and .I tell, have been recalled to active duty; see \*(yH and \*(yI. .NH 2 Formal policy .XL y5 .PP In the policy statements below, variables $t sub 0$ and $t sub 1$ represent times such that $t sub 0~<=~t sub 1$. The entities among which flows occur are not designated; for a complete list of recognized flows, see Table \*(zT. .PP Certain system calls .I renew entities; a renewed entity is actually or nominally bereft of memory of past contents. If an entity $x$ is renewed in the interval $t sub 0$ to $t sub 1$, there is no persistent flow $x~->~x$ across that interval. The following actions are recognized as renewals. .IP Seeking relative to beginning of file renews the seek pointer. .IP Setting a process ceiling renews the ceiling. .IP Setting a file label away from $NO$ renews the file. .SP Files labeled $NO$ are unobservable in the absence of privilege. Thus reclassifying to $NO$ is harmless. .SP .I Exec with no arguments could be considered to be a renewal, but our understanding that .I exec starts a new process makes that unnecessary. .NH 3 Generic policy .PP The policy is to be observed by all untrusted processes. Trusted process may deviate from the policy only in ways recorded as ``exceptions.'' .LP .B "Upward flow. If a flow $x~->~y$ occurs at time $t$, it must be upward. .IP $L(x,^t)~<=~L(y,^t)$ .LP Exception: either $x$ or $y$ is a process $p$ and $Tnochk (p,^t)$ is true. .LP .B "Monotone labels. A persistent flow $x~->~x$ must be upward unless $L(x,^t sub 1 )~=~NO$. so it is harmless to relabel a file $NO$. .IP $L(x,^t sub 0 )~<=~L(x,^t sub 1 )$ .SP A file labeled $NO$ is inaccessible to untrusted processes, .LP .B "Impenetrable Ceilings. If a flow $x~->~y$ occurs at time $t$, it must respect the ceiling of the causative process $p$, and any ceilings of the participating entities. .IP $max ( L(x,^t),~L(y,^t))~<=~min ( C(p,^t),~C(x,^t),~C(y,^t))$ .LP Exception: either $x$ or $y$ is a process $p$ and $Tnochk (p,^t)$ is true. .LP .B "Monotone ceilings. A ceiling can only decrease. .IP $C(x,^t sub 1 )~<=~C(x,^t sub 0 )$ .LP Exception: $x$ is a process $p$ and $Tsetlic (p,^t sub 0 )$ is true. .LP .B "Inherited ceilings. At the time $t sub 0$ of starting, the ceiling of a new process $q$ is dominated by that of the process $p$ that started it. .IP $C(q,^t sub 0 )~<=~C(p,^t sub 0 )$ .PP In the absence of privilege, the generic policy forbids a chain of flows $x sub 0~->~x sub 1~->~...~->~x sub n$, between entities observed at times $t sub 0~<=~t sub 1~<=~...~<=~t sub n$, where $L(x sub 0 ,^t sub 0 )~!<=~L(x sub n ,^t sub n )$. The label policy also forbids such a chain of flows when $L(x sub n ,^t sub 0 )$ is defined and $L(x sub n ,^t sub 0 )~!<=~C(x sub n ,^t sub 0 )$. .SP Correct implementation depends on identifying all entities and flows and then assuring that each flow respects the policy. .NH 3 Privilege policy .XL y9 .PP These rules do not address the initial setting of capabilities in a process; see \*(yQ. .LP .B "Monotone capabilities. The capabilities of a process $p$ can only decrease. .IP $Cap (p,^t sub 1 )~<=~Cap (p,^t sub 0 )$ .LP .B "Monotone licenses. The licenses of a process $p$ can only decrease. .IP $Lic (p,^t sub 1 )~<=~Lic (p,^t sub 0 )$ .LP Exception: $Tsetlic (p,^t sub 0 )$ is true. .LP .B "Inherited licenses. At the time $t sub 0$ of starting, the license of a new process $q$ is dominated by that of the process $p$ that started it. .IP $Lic (q,^t sub 0 )~<=~Lic (p,^t sub 0 )$ .LP .B "Persistent file privilege. The privileges of a file cannot be changed. .IP $Vvec (f,^t sub 1 )~=~Vvec (f,^t sub 0 )$ .LP Exception: process $p$ with capability $Tsetpriv (p,^t)$ causes a change during $t sub 0~<=~t~<=~t sub 1$. .LP .B "Persistent trusted files. A trusted file $f$ cannot be written into. .IP $x~->~f~=>~not T(f)$. .ig .NH 2 Some scenarios .PP These examples show ways to cope with some of the difficulties imposed by security controls. Most of them are discussed in more detail elsewhere. .NH 3 System maintenance .PP System administrators are expected to be entitled to superuser status and enough privileges to install software. In a highly security-conscious installation the power to mark newly installed code trusted would be invested in a separate security administrator. The separation of powers is intended both to prevent possible mischief by single individuals and to provide checks and balances against hasty and mistaken changes to the security environment. .NH 3 Individual users .PP User authentication is done by a trusted .CW login program. Once .CW login has set the userid, groupid, terminal label, process label, process ceiling, and privileges, access is determined solely by permissions, labels, and privileges. .NH 3 Reading process status, .I ps .PP The .I ps command can print the arguments of any process, which it reads from files in the process file system .CW /proc . The files share labels with the processes themselves, so ordinary label checks prevent improper snooping. However, checking the essentially random labels in .CW /proc could have the unpleasant side effect of raising the label of .I ps, perhaps above the label of its terminal, so that no output, even about low-label processes, could get to the terminal at all. This we prevent by freezing the process label before probing the process files. .PP For reasons of common prudence, process files do not have general read permission. Customarily .I ps is made setuid root so it can peek anyway. Hoping to abolish the superuser's universal read privilege, we instead give process files a conventional group number (\-1) and make .I ps setgid to that group. .PP .I Ps has options to print information about open files, which it obtains from .CW /dev/kmem . This information comes from many processes and is not properly labeled; it is instead hidden by the $NO$ label on .CW /dev/kmem and can only be seen by processes with $Tnochk$ privilege. If the security administrator deems it acceptable, .I ps may be given capability $Tnochk$. Then administrators licensed for $Tnochk$ can obtain the information. .NH 3 Mail .PP To send mail to a low user, a high user must effectively log in afresh with a low label. One way to do this is with an analogue of .CW su for temporarily changing the label of a terminal; see \*(yf. .PP Another way is to log in from another terminal, particularly a virtual terminal in the style of v10. A trusted .CW mux communicates with a terminal whose (necessarily trusted) software can not be replaced. The security policy applies to data copied between windows. .PP To receive mail sent without regard to level (assuming that it is below the recipient's ceiling), each user may have a low directory in .CW /usr/spool/mail . The .CW mail program calls on simple trusted programs to move letters into the recipient's directory under randomly generated names and to delete letters. .NH 3 Temporary directory, .CW /tmp .PP The temporary directory will be .I blind. It will be owned by a special administrative account, and perhaps have some administrative label. Files can be freely created in it, but nobody\(emnot even an administrator\(emcan read the directory to find the file names. To clean up .CW /tmp , the administrator must turn blind mode off. While blind mode is off, label checks will be enforced and .CW /tmp will run safely, but not multi-level: cleanup should happen only in single-user mode. .NH 3 Writing magnetic tape .PP Tapes, being external media, the labels of which are beyond the ordinary control of the system, must be opened by trusted processes. Moreover Orange Book standards require tapes to be correctly labeled: no untrusted process may be offered the opportunity to rewrite the label. We are thus compelled to write tapes with a trusted program. .SP An untrusted program could write a tape that a trusted program had opened append-only, an opening mode that is in System V, but not in v10. .PP Trusted programs other than the tape-writer must be proof against being fooled into opening a tape for writing. This requirement is not peculiar to tape-writing; trusted programs must always check authorization before opening arbitrary files. .NH 3 Retrieving classical UNIX .PP We would like to recover the usual .UX system call semantics in an appropriate limiting case. Three approaches follow, none of them as clean as we would like. .PP If no files were trusted, and if a process could run with $L(p)~=~YES$ and $C(p)~=~YES$ it would notice little difference in system calls from their classical behavior. The process label $YES$ would have to be inheritable and some dispensation would have to be given to .CW init in order for it to assume label $YES$ . .PP If we make all labels $bottom$ ordinary users will never see an $ELAB$ error or receive $SIGLAB$. A simple self-licensing trusted program will suffice to mark as trusted occasional programs that have to do special operations such as opening terminals. .PP If we modify the system so that all privileges are always true (by setting all bits in $Tvec sup 0$), then the label apparatus becomes invisible. Notice that treating all processes as trusted does not spoil the existing .UX permissions system: it merely bypasses the new labeling scheme. .PP In no scenario, however, will the superuser regain general write permission. .NH 3 Integrity .PP ``Integrity'' refers to the credibility of data, not its secrecy. Perfectly public programs, such as compilers, must be of the highest integrity if they are to be trusted to manipulate trusted code\(emfor example, to recompile the login command. In controlling integrity we wish to avoid copying low-integrity data into high-integrity places. This goal is opposite to that of security, where we wish to avoid copying high-security data into low-security places. ``Integrity labels'' behave like negative security labels. .PP Simply by setting a default ``floor'' label above $bottom$, we obtain a ``negative'' part of the label lattice, which may be used for integrity. High-integrity data have very negative labels. When such a file is written into by a process with an ordinary label at or above the floor, its label will rise (become less negative), thus revealing the loss of integrity. By convention we may make some bits of a label normally on\(emthese bits serve for integrity control; the rest are still available for security labeling. .NH 2 What isn't covered .PP The proposal does not cover networking. Logically it presupposes a single multi-user system with hard-wired dumb terminals. Nothing in it will .I "per se safeguard information that passes through long communication links or through other computers, even the computers in smart terminals. .PP Like any other security system, ours does not assure the integrity of data against inadvertent or deliberate corruption by authorized agents. Nor can it prevent users from mistakenly entering secret information into nonsecret terminals. Finally, it does not directly preclude old Trojan horse tricks like suckering the superuser into executing the wrong .CW ls command. .PP To us a ``covert channel'' is any channel not covered by the formal policy, which concerns only flows between process and objects. In standard .UX there exist other flows that go directly from object to object or process to process. In the design that follows we have considered such formally covert flows and interdicted them where feasible within our overall intent. Thus the system as implemented is somewhat stronger than is implied by the formal policy. Nevertheless formally covert channels with bandwidths of tens of bits per second\(emconsiderably more than the term normally implies\(emdo remain. .PP Process-to-process flows are exemplified by arguments to .I exec, the security of which is fully accounted for; see \*(y6. Object-to-object flows are exemplified by the interaction of the seek pointer and file contents on .I read and .I write. These flows are also fully checked. .PP Other covert channels are discussed in part \*(yJ. None will help prying solo users to see data they are not cleared for. Nor will programmers ever use them inadvertently. These are moles' channels, through which the beans can be spilled only by corrupt or hoodwinked insiders. Moreover the channels involve abnormal usage: large numbers of open files or pipes and rapid-fire forking of processes. They should draw auditing attention if much used. ..