14.1 Goals of Protection: 14.3.1 Domain Structure
14.1 Goals of Protection: 14.3.1 Domain Structure
14.1 Goals of Protection: 14.3.1 Domain Structure
1 Goals of Protection
Obviously to prevent malicious misuse of the system by users or programs. See chapter
15 for a more thorough coverage of this goal.
To ensure that each shared resource is used only in accordance with system policies,
which may be set either by system designers or by system administrators.
To ensure that errant programs cause the minimal amount of damage possible.
Note that protection systems only provide the mechanisms for enforcing policies and
ensuring reliable systems. It is up to administrators and users to implement those
mechanisms effectively.
The principle of least privilege dictates that programs, users, and systems be given just
enough privileges to perform their tasks.
This ensures that failures do the least amount of harm and allow the least of harm to be
done.
For example, if a program needs special privileges to perform a task, it is better to make
it a SGID program with group ownership of "network" or "backup" or some other pseudo
group, rather than SUID with root ownership. This limits the amount of damage that can
occur if something goes wrong.
Typically each user is given their own account, and has only enough privilege to modify
their own files.
The root account should not be used for normal day to day activities - The System
Administrator should also have an ordinary account, and reserve use of the root account
for only those tasks which need the root privileges
Rings are numbered from 0 to 7, with outer rings having a subset of the privileges
of the inner rings.
Each file is a memory segment, and each segment description includes an entry
that indicates the ring number associated with that segment, as well as read, write,
and execute privileges.
Each process runs in a ring, according to the current-ring-number, a counter
associated with each process.
A process operating in one ring can only access segments associated with higher
( farther out ) rings, and then only according to the access bits. Processes cannot
access segments associated with lower rings.
Domain switching is achieved by a process in one ring calling upon a process
operating in a lower ring, which is controlled by several factors stored with each
segment descriptor:
o An access bracket, defined by integers b1 <= b2.
o A limit b3 > b2
o A list of gates, identifying the entry points at which the segments may be
called.
If a process operating in ring i calls a segment whose bracket is such that b1 <= i
<= b2, then the call succeeds and the process remains in ring i.
Otherwise a trap to the OS occurs, and is handled as follows:
o If i < b1, then the call is allowed, because we are transferring to a
procedure with fewer privileges. However if any of the parameters being
passed are of segments below b1, then they must be copied to an area
accessible by the called procedure.
o If i > b2, then the call is allowed only if i <= b3 and the call is directed to
one of the entries on the list of gates.
Overall this approach is more complex and less efficient than other protection
schemes.
Access Matrix
The model of protection that we have been discussing can be viewed as an access matrix,
in which columns represent different system resources and rows represent different
protection domains. Entries within the matrix indicate what access that domain has to that
resource.
Domain switching can be easily supported under this model, simply by providing
"switch" access to other domains:
Figure 14.4 - Access matrix of Figure 14.3 with domains as objects.
The ability to copy rights is denoted by an asterisk, indicating that processes in that
domain have the right to copy that access within the same column, i.e. for the same
object. There are two important variations:
o If the asterisk is removed from the original access right, then the right is
transferred, rather than being copied. This may be termed a transfer right as
opposed to a copy right.
o If only the right and not the asterisk is copied, then the access right is added to the
new domain, but it may not be propagated further. That is the new domain does
not also receive the right to copy the access. This may be termed a limited copy
right, as shown in Figure 14.5 below:
Figure 14.5 - Access matrix with copy rights.
The owner right adds the privilege of adding new rights or removing existing ones:
Figure 14.6 - Access matrix with owner rights.
Copy and owner rights only allow the modification of rights within a column. The
addition of control rights, which only apply to domain objects, allow a process operating
in one domain to affect the rights available in other domains. For example in the table
below, a process operating in domain D2 has the right to control any of the rights in
domain D4.
Figure 14.7 - Modified access matrix of Figure 14.4
The simplest approach is one big global table with < domain, object, rights >
entries.
Unfortunately this table is very large ( even if sparse ) and so cannot be kept in
memory ( without invoking virtual memory techniques. )
There is also no good way to specify groupings - If everyone has access to some
resource, then it still needs a separate entry for every domain.
Each column of the table can be kept as a list of the access rights for that
particular object, discarding blank entries.
For efficiency a separate list of default access rights can also be kept, and checked
first.
In a similar fashion, each row of the table can be kept as a list of the capabilities
of that domain.
Capability lists are associated with each domain, but not directly accessible by the
domain or any user process.
Capability lists are themselves protected resources, distinguished from other data
in one of two ways:
o A tag, possibly hardware implemented, distinguishing this special type of
data. ( other types may be floats, pointers, booleans, etc. )
o The address space for a program may be split into multiple segments, at
least one of which is inaccessible by the program itself, and used by the
operating system for maintaining the process's access right capability list.
14.5.5 Comparison
o As systems have developed, protection systems have become more powerful, and
also more specific and specialized.
o To refine protection even further requires putting protection capabilities into the
hands of individual programmers, so that protection policies can be implemented
on the application level, i.e. to protect resources in ways that are known to the
specific applications but not to the more general operating system.
1. Security. Security provided by the kernel offers better protection than that
provided by a compiler. The security of the compiler-based enforcement is
dependent upon the integrity of the compiler itself, as well as requiring
that files not be modified after they are compiled. The kernel is in a better
position to protect itself from modification, as well as protecting access to
specific files. Where hardware support of individual memory accesses is
available, the protection is stronger still.
2. Flexibility. A kernel-based protection system is not as flexible to provide
the specific protection needed by an individual programmer, though it may
provide support which the programmer may make use of. Compilers are
more easily changed and updated when necessary to change the protection
services offered or their implementation.
3. Efficiency. The most efficient protection mechanism is one supported by
hardware and microcode. Insofar as software based protection is
concerned, compiler-based systems have the advantage that many checks
can be made off-line, at compile time, rather that during execution.
o The concept of incorporating protection mechanisms into programming languages
is in its infancy, and still remains to be fully developed. However the general goal
is to provide mechanisms for three functions: