.NH 1
SECURITY-RELATED PROGRAMS
.XL yk
.PP
This section describes some distinctive and important
programs in the TCB.
.ig
.PP
The
.I "privilege server
provides administrative control over the exercise of
privilege in a structured way.
.PP
The
.I "session supervisor
sets the ceiling, process label, and terminal label
and starts a session shell at a
requested level, but only after authenticating and
checking the rights of the requesting user.
.PP
The
.I "password server
exemplifies the use of private paths
and the sanitizing of multilevel queries to a
secure data base.
.PP
.I Mux,
a multilevel window manager, exemplifies
the handling of multilevel
external media, the use of private paths, and
the transitive extension of private paths through
system emulators.
.PP
The
.I nosh
shell is simple and transparent enough to
be usable with confidence when working on the TCB.
.PP
.I Pcopy
is a paranoid file copy routine, suitable for
copying privileged files.
..
.NH 2
Privilege server
.XL yl
.PP
The privilege server hands
out the exact privilege needed to execute administrative
tasks.
It is guided by a data base of
privileged commands and conditions for their execution.
On request for a particular privileged action, the 
server checks authorization for that action and
invokes the action  under carefully controlled conditions.
The privilege server imposes more structure on authorizations than do
homologous programs in other
.UX
systems.
As a result, IX can enforce
a notion of a well formed edit of the privilege data base.
.PP
Authority may be made delegable, so
suborganizations can edit parts
of the privilege data base controlled by their
superior organizations, without
intervention by an omnipotent system administrator.
In particular,
it is possible to give a particular user complete
administrative control over
a particular bit (or security category)
in the label space.
.PP
The privilege server's data base consists of a tree of authorizations
and a set of action rules.|reference(reeds network)
The nodes in the authorization tree are labeled with
triples of form $( pathname, ~access_predicate , ~rights)$.
The pathname names the tree node and the access predicate
is built with 
.SM AND
and
.SM OR
out of these kinds of atoms:
.DS
A regular expression for the client's login name.
A password demand for the password server to verify.
A regular expression for the stream identifier of the client's standard input.
.DE
Rights are a set of capabilities that access to the node confers.
The simplest rights are plain identifiers.  Other rights
are identifiers that bear limiting values that confine
the right to part of some lattice.  Currently
we support these nontrivial lattices: 
.DS
The lattice of labels.
The lattice of regular languages ordered by inclusion.
The lattice of subsets of privileges.
.DE
In mathematical terms, $rights$ names an element of the Cartesian
product of as many lattices as there are distinct identifiers
(with plain identifiers understood as tops of two-element lattices).
Rights are monotone in the authorization tree: if node $x$ is
above (closer to the root than) node $y$, then the rights
of $x$ dominate those of $y$.
By convention, the root of the tree has all rights.
The root of the authorization tree represents the
undiluted power of the TCB, and the various subnodes represent
various limited ranges of powers, suitable for granting to various users.
.PP
In response to a user's request, which looks like a shell command,
the privilege server searches for nodes
whose access predicates are satisfied.
The user is provisionally granted the set of corresponding rights.
Then the request is compared with the action rules, which
are triples of form $( template, ~need, ~action)$:
.DS
The $template$ is a regular expression describing the request. 
The $need$ defines the minimum rights necessary.
The $action$ tells what to do.
.DE
If some provisional rights dominate the $need$,
then the $action$ is carried out.
Both the need and the action can contain parameters substituted
from substring matches in template.
.PP
Before execution, the proposed action is presented
under cover of pex (\*(yC) for the user's confirmation.
Requests placed from an insecure terminal or from a remote computer
will be rejected because the pex will fail.
However, a request can safely be issued through untrusted
software, in particular the shell, because the user gets to
vet and confirm the action over a private
path to the privilege server.
.PP
Usually the action specifies execution of a particular
program, with process license and ceiling set to particular values.
The action may also specify an edit of a named subtree of the
authorization tree, always preserving the monotonicity of the
authorization tree.
Authority is delegable by granting the
right to edit a subtree.
.PP
When an action has been approved by both the privilege server
and the user, it is executed in a paranoid,
context-independent way.
There are no environment variables.
The invocation is direct, unmediated by a shell.
The current directory is set to a `black hole' labeled $NO$;
thus files can only be referred to by absolute path names.
.PP
For example, suppose the authorization tree has a node 
.DS
.TS
lf2W(1.4i) lf5.
pathname:	/admin/networks/internet
access predicate:	SRC(/dev/console)
rights:	netoper
.TE
.DE
and immediately superior node
.DS
.TS
lf2W(1.4i) lf5.
pathname:	/admin/networks
access predicate:	ID(ches)\^&\^PW(ches)
rights:	netadmin\^|\^netoper
.TE
.DE
(Monotonicity requires at least the right
.CW netoper ,
since access to the superior node must imply access to the
inferior node.)
The first access predicate grants rights to privilege requests
that originate at
.CW /dev/console ;
the second to a user with a certain login name
who can present a password appropriate to that name.
If one of the action rules is
.DS
.TS
lf2W(1.4i) lf5.
template:	tcpgateway
need:	netoper
action:	PRIV(x), EXEC(/lib/tcp/tcpgateway)
.TE
.DE
a request for the privileged action
.CW tcpgateway
will be admitted if the source is
.CW /dev/console
or if the login name
.CW ches
can be confirmed.  Only then will the action be performed,
executing the desired program with external-medium (\f(CWx\fR) privilege.
.PP
The project administrator in the example in \*(yc might be
granted access to a node with right
.CW downgrade(projectbit) ,
where
.CW projectbit
names a part of the lattice of labels assigned
to the project.
The downgrade request would need
$font CW "downgrade($1)"$
privilege, where $font CW "$1"$
refers to the first argument of the request and must name a label.
Then the administrator could use the following command to
declassify a report issued by the project.
.DS
.CW
priv downgrade projectbit report
.DE
.LP
Although the administrator has downgrade privilege, the
privilege is confined to the one project.
.PP
The right to edit the privilege data base must be
carefully controlled, for whoever can edit the root of
the authorization tree holds an ultimate key to the system.
To keep that right from being exercised unilaterally, it
may be protected, for example, by requiring two
or more passwords, which are known by different people.
Beyond the privilege server, there is one more source
of ultimate power\(emsingle-user mode at
the main console (\*(yo), access to
which must be controlled by physical security measures.
.NH 2
Session supervisor
.XL yy
.PP
The session supervisor handles requests for
sessions with a different label, much as
the standard
$su$ command does for sessions with a different userid.
It accepts requests to change the label of the terminal
(standard input) and the process ceiling.
After verifying the
user's clearance and the suitability of the particular
port for traffic at the desired label,
the session supervisor resets the label of the standard input
to the desired level, adjusts the process ceiling, and
invokes a shell.
At the end of the session, the supervisor restores
the label of the standard input and exits.
Label inequalities prevent misuse of the terminal
by processes that survive across either label change.
.NH 2
Password server
.XL ym
.PP
Ordinary 
.UX
passwords are open to compromise from eavesdropping.
As a countermeasure, IX supports cryptographic protocols.
Unfortunately such protocols, unlike classical
.UX
passwords, depend on the system knowing secret keys, which
must be very closely held.
Password checking may have to be done at any
security level, so the password file can't be
protected simply by giving it a high label.
For these reasons IX has a privileged server
that collects passwords from the user and verifies them.
An incidental benefit is that
new authentication algorithms can be adopted easily,
for only the password server needs to know them.
.PP
A client program
(such as
.I login
or
.I su ),
which needs to verify the claimed identity of the party
at the far end of a file descriptor,
establishes a connection
to the password server through a pipe 
mounted in the file system.
|reference(ritchie presotto)
The connection is assured by pex (\*(yC); if pexing fails,
the identity claim is denied.
The client then sends to the server 
the claimed identity and the file descriptor.
.PP
The server attempts to verify the claimed identity by using
one of two authentication algorithms.
The user is asked to provide either a classical
.UX
password or a response from a cryptographic pocket calculator.
If the user's file descriptor cannot be pexed,
meaning that the channel cannot be trusted to keep
passwords secret, only
a cryptographic response is accepted.
After the user's reply is collected and checked,
the server reports success or failure to the client
and drops off the line.
.PP
Because only one program needs access to the password file,
that file could be kept off line for safety.
The password server would then become a stub that observes the
password protocol and maintains exclusive access to the
off-line connection.
.PP
For a system administrator engaged in a spurt of privileged
actions, it would be tedious to reauthenticate for every action.
And it would be dangerous to use a privileged shell, for such 
a blanket grant of privilege raises the possibility that
the privilege may be exercised in unintended ways.
Instead the session supervisor can create
special sessions, wherein the
administrator's I/O stream is tagged (in the
stream identifier, \*(yD) to tell
what authenticating checks have been successfully passed.
The password server uses the information to short-circuit
its authenticating protocols.
(Pex-protected user confirmation is still required, however, to
prevent untrusted software from initiating unintended privileged
actions.)
During such a session, the administrator can invoke the privilege
server without having to present a password at each invocation.
.NH 2
Multilevel windows
.XL yn
.PP
To illustrate the use of private paths, we consider how
multiple asynchronous windows are managed on a bitmapped
terminal, the Teletype 5620.
Since the terminal has no hardware memory protection,
all code in the terminal
must be trusted if it is to 
run as a multilevel device.
Moreover that code must adhere to the label policy on
data transfers (cut and paste) among windows.
.PP
All communication with the terminal passes through a
host multiplexer program,
.I mux.
|reference(blit)
Normally a process group, comprising a shell and
programs that it invokes, has its standard output
connected to
.I mux
by a pipe, one process group and pipe per window.
To the processes the pipe looks like a conventional terminal,
running at some fixed label.
.I Mux
itself must run with privilege
to be able to deal with differently labeled windows.
.PP
Interesting things happen when a privileged process
is invoked in a window.
For example, the
.UX 
super-user command,
.I su ,
demands a password.
(To be precise,
.I su
calls on the password server to demand the password.)
The command pexes the pipe to
.I mux ,
which reciprocates by pexing the other end and extends the
private path to the window code in the terminal.
In turn a characteristic pattern is displayed in the window
to announce the private path.
Thus the user is assured
that the password will be treated safely.
In this respect, the more complex multilevel terminal
offers an advantage over a simple dumb terminal, which
is unable to deliver such out-of-band assurance.
.PP
To work at a different label in a window, one
invokes the session command in the host.
After determining that the user is
properly cleared, the session command sets the label on its input
pipe.
The pipe leads to
.I mux,
which detects the change and passes it on to the window.  
Unless the new label dominates the old, the
contents of the window are erased.
A new shell is spawned for the duration of the session.
Although an old shell and possibly
other processes are also attached to the pipe,
no attempt to access the pipe from these processes
can violate the label policy.
When the new shell exits
at the end of the session, the pipe label is restored,
the label change is propagated to the terminal, and the
window's memory is erased if necessary.
.NH 2
Nosh, a believable shell
.XL yo
.PP
The customary
.UX
shell programs are extremely complex.
Their semantics are incompletely defined and their
behavior depends heavily on the environment.
They can all too easily be made to do
the unexpected, and hence are dangerous instruments for
system administration.
.PP
For critical uses in IX we have written
.I nosh,
a no-surprise shell.
.I Nosh
is invoked for the single-user maintenance shell that
comes up with all privileges at system boot and for
the customary boot script (\fIrc\fP).
It is also used in sessions labeled below the system
floor, where system updating is done.
By all measures 
.I nosh 
is less than 6% the size of the classical Bourne shell; and
its 400 lines of source are coded in a direct, understandable style.
It is most easily characterized by the features it lacks.
.I Nosh
has
.IP "" .5i
.nf
no path search; all commands begin with \f(CW/\fP or \f(CW.\^/\fP
no variables
no environment
no user profile
no aliases or defined functions
no redirection of I/O other than standard output
no pipelines (\f(CW|\fP)
no compound commands (\f(CWif, for, case, &&, ...\fP)
no background commands (\f(CW&\fP) or job control
no manipulation of signals
no file name generation (\f(CW*\fP or \f(CW?\fP)
no command substitution (\f(CW`...`\fP)
no history
no mail notification
no arithmetic or test commands
.SP
.PP
When licensed for privileges, as it is in single-user maintenance
mode,
.I nosh 
refrains from passing licenses to other commands
except by specific request on each command.
.I Nosh
retains the customary shell flag
.CW \-e ,
which causes an immediate exit
when any command fails; this feature is important for the
boot-time shell script (\f(CW/etc/rc\fR).
.NH 2
Pcopy, software installation
.XL yA
.PP
A privileged file cannot be changed (\*(yB).
Thus to copy a privileged file, including its
licenses and capabilities, one must first copy it to
an unprivileged place and then mark the copy privileged.
In the meantime, the copy may be open to meddling.
.I Pcopy
does the job `atomically' under cover of pex.
.PP
In a system where powers are strictly separated
between a system administrator
(sysadmin) and a security administrator (secadmin),
the job of replacing a privileged program $P$
might be divided
between them according to the following scenario.
Steps 1 to 5 may take considerable time.
Steps 6 to step 8, however, should be done
quickly, because program $P$ is unavailable
during that interval.
.I Pcopy
is used to assure the integrity of the copy.
Except where noted otherwise, each step is mediated
by the privilege server, whose tables provide
just enough privilege to each administrator.
Neither can do the job alone.
.IP
.SP
1.\ Sysadmin compiles, or receives from some
official source, new code $P sup prime$.  No privilege needed.
.IP
2.\ Sysadmin protects $P sup prime$ from
modification by giving it a dummy license (\*(y8).
Secadmin does not have the right to do this.
.IP
3.\ Sysadmin checks the contents of $P sup prime$, perhaps
by code testing, decompiling, or comparing against a 
reference copy.
No privilege needed.
.IP
4.\ Secadmin adds a dummy license to $P sup prime$.
Sysadmin does not have the right to do this.
.IP
5.\ Secadmin checks the contents of $P sup prime$, perhaps by
cryptographic certification or virus scan.
No privilege needed.
.IP
6.\ Sysadmin removes the privilege from $P$ and uses
.I pcopy
to copy $P sup prime$ and the dummy licenses to $P$.
.IP
7.\ Secadmin compares the freshly written $P$ to 
the original $P sup prime$.
No privilege needed.
.IP
8.\ Secadmin sets the final privilege on $P$ and removes
the dummy licenses.
To enforce the separation of powers, this step should be conditional
on the proper dummy licenses being in place.
.IP
9.\ Either administrator removes the dummy licenses from $P sup prime$.
.ig
.PP
The preceding protocol would be imposed through the privilege
server's data base.
To assure the integrity of the protocol
itself, a similar protocol would control the editing of
the pertinent part of the authorization tree.
..
.NH 1
SYSTEM MATTERS
.XL zx
.NH 2
Efficiency
.XL yp
.PP
The efficiency of IX relative to the underlying 10th Edition
system varies depending on
how frequently label computations must be made.
Listing a directory, which requires a label check
for each file, incurs
a 15% time penalty.
The overhead on creating a file in the
current directory, writing one byte in it, and destroying
it is 20%.
Long path names, which require a
label comparison at every intermediate directory, make things worse.
An inefficiently coded file-tree walk drags miserably.
.PP
For reading and writing, however, where the caching of label
checks comes into play, the efficiency story is different.
The overhead is immeasurably small for typical
file-processing programs working on files more than
a few disk blocks long.
.NH 2
Special 
.UX
considerations
.XL yq
.PP
Most of the security facilities of IX are generic
and reflect the policy, not the system.
A few, however, deal with features peculiar to
.UX .
.PP
.I "Blind directory.
To preserve the portability of
.UX
code, the common temporary directory,
.CW /tmp ,
had to be kept, and somehow be usable
by processes of different labels.
After considering, and even implementing,
various alternatives, we settled on the simple notion
of a blind directory.
A blind directory cannot be read; hence no data
flows can occur through it and its label does not matter.
A blind directory admits covert channels, however.
For example,
a low process can learn via error returns whether the directory
contains files by known names, regardless of the files' labels.
Or a low process can create a collection of links and
watch link counts change as a high process unlinks them.
.PP
A somewhat stronger `doubly blind' technique for concealing
temporary files was also implemented,
but was dropped
because it changed the system interface in a way that affected
every program that created a file in the temporary directory.
In this scheme, the system generated a random
name for each file created in the blind directory and returned
the name to the creator.
.PP
.I "Seek pointer.
Two processes that through inheritance share an open file
also share the seek pointer on that file.
By using the 
.UX
system call
.I lseek
in one process to set the seek pointer and
in another to read it, a remarkably high interprocess bandwidth
can be attained in classic 
.UX
systems.
As a medium of data flow, seek pointers must be labeled.
The labels of seek pointers should not be tied to either
process or file labels, for that would unnecessarily
force identity of labels in many instances.
Hence each seek pointer has a label of its own.
.PP
The standard 
.UX
system call
.I lseek,
by virtue of both writing and reading the seek pointer,
has the side effect of forcing the labels
of the file and the process to be equal in most cases.
For programs that wish to circumvent this unfortunate property,
we resuscitated an ancient pair of system calls,
.I seek
and 
.I tell,
which separate the functions.
.PP
.I "User area.
Associated with each
.UX
process is a collection of descriptive information, which
includes user number, login name, permission mask (\fIumask\fP),
permission group, process ceiling, and other items.
As the listed items can be set and read by system calls
and are inherited by successor processes, they
provide data-flow channels between processes, which
could be exploited in connection with the drop-on-exec
convention (\*(y5).
We have interdicted most of them by
defining a peculiar privilege for setting user-area items.
Most of the items need super-user status anyway;
the need for privilege in connection with the user
area affects only administration, not ordinary usage.
.PP
Different mechanisms are used to protect
two user-area items settable by ordinary users,
the permission mask and the process ceiling (which can
be revised downward).
To prevent downward data flow through the permission mask, it
is set to a default value when drop-on-exec occurs.
To prevent downward flow through the ceiling, the ceiling
itself has a label that is set whenever the ceiling 
changes.
A privileged ceiling change sets the label on the ceiling
to bottom;
other changes set it to the process label.
.PP
Of the three mechanisms
for protecting user-area data (a special privilege,
censoring, and giving each item its own label) the
most straightforward is the last.
But it is not clear what restoring force, analogous to
dropping the item's label when the item is set with privilege,
can be provided for labels on items other than the ceiling.
.NH 2
System changes
.XL yr
.PP
IX is based on the 10th Edition research
.UX 
system.
|reference(v10)
It has the following special system calls over and above those
of the 10th Edition:
.IP "" .5i
.nf
get/set file label and privileges
get/set process label and privileges
get file system ceiling
mount, setting file system ceiling
control auditing
control nocheck privilege on individual open files
identify open files with changed labels
seek and tell (\*(yq)
I/O controls for pexing (\*(yC)
I/O controls for stream identifiers (\*(yD)
.in 0
.SP
.LP
A few rare system calls
have been abolished.
One is
.I chroot,
whose potential for mischief overtaxed our understanding.
The other two,
.I setgroups
and
.I getgroups,
entailed a user-area covert channel
of enormous bandwidth.
.PP
The kernel changes were implemented in about
1300 lines of alterations to normal 10th Edition source,
plus about 2100 lines of new modules.
The total kernel source of under 33,000 lines handles the usual
10th Edition system calls (no
System-V style IPC or shared memory), console, disks,
Datakit networking, and remote file systems.
Further device drivers could be taken over verbatim from the
10th Edition.
.PP
Some extra kernel memory is required for labels,
but sharing (\*(y9) keeps the total
low even though hundreds of 62-byte labels may be
in use at one time.
The data structure for maintaining
coherence of the cached checks (\*(y7) is another matter.
In a system configured for 300 processes, this data structure
occupies about 150K bytes including file descriptors, which 
cannot be swapped with
their processes as had been possible before.
The data structure is coded expansively, with
several fixed-size tables and lots of 32-bit pointers.
Although its storage requirements could be
reduced by a significant factor,
we have not
bothered to optimize it, for it works adequately.
.PP
The layout of file systems was changed to accommodate labels.
.PP
About ten maintenance utilities (e.g.
.I fsck
and
.I mount )
had to be adapted to the new file system
and kernel layouts.
A handful of security-related utilities (e.g.
.I login
and
.I su )
had to be modified to use the new security mechanisms.
.ig
(e.g.
.I ps ).
." autofsck chuck clri dcheck fsck lmount mkbitfs mount ncheck umount
." adb ps pstat showq vmstat
..
.PP
Some new utilities have been written.
Besides those described in \*(yk, there are
programs to set and retrieve labels,
handle multilevel mail, and administer auditing.
The new utilities comprise about 6000 lines of code, of which
the privilege server accounts for nearly half.
