The Trusted Solaris environment uses two types of labels: CMW labels and sensitivity labels (SLs).
This chapter describes the programming interfaces for performing general label operations such as initializing labels, retrieving portions of a CMW label, and comparing labels. It also describes the programming interfaces for accessing CMW labels on processes and file system objects. Chapter 5, Label Code Examples provides code examples for the programming interfaces described in this chapter.
Clearances have the same construction as sensitivity labels, but perform a different function. Because of the similarity, some of the interfaces in this chapter accept clearances as parameters and some families of interfaces include an interface to handle clearances. Because clearances have a different function, however, all interfaces for managing clearances are described in Chapter 6, Process Clearance with code examples that use clearances.
A CMW label is a construct for labeling all processes and objects. It combines a sensitivity label with an information label so the labels can be programmatically translated and manipulated as a combined unit, or accessed individually.
A sensitivity label has an ID field, one hierarchical classification (also called a level), and a set of one or more non-hierarchical compartments (also called categories). The classification represents a single level within a hierarchy, while the compartments represent distinct areas of information in a system. Compartments limit access to only those who need to know the information in a particular area. For example, persons with a Secret classification have access to the secret information specified by the compartment list and no other secret information. The sensitivity label classification and compartments together represent the sensitivity level of a process or object.
Comparing sensitivity labels means that the sensitivity label portion of the process CMW label is compared to the sensitivity label portion of the target CMW label and access is either granted or denied to the process based on whether the sensitivity level of the process dominates the sensitivity level of the target. The relationships of equality and dominance are described in "Test Label Relationships".
CMW labels appear throughout the Trusted Solaris user interface as a single sensitivity label.
Labels are acquired from workspaces and other processes. A user can start a process only at the current sensitivity label of the workspace in which he or she is working.
When a process is started from the workspace, the process CMW label inherits the sensitivity value of the workspace CMW label.
When a new process is created using fork(2), the new process inherits the CMW label values of its calling process.
When a new program is started with exec(1), the exec'ing process must have both discretionary and mandatory access to the new program's file.
The setcmwplabel(2) system call programmatically sets the process CMW label. You would use this call after forking or exec'ing a new process that should operate at another CMW label from the calling process. Privileges may be required. See "Privileged Operations".
When an object is created by a process, the object inherits the CMW label values of its calling process.
When a privileged process writes down to an object, the system changes the sensitivity label of the object to be the same as the sensitivity label of the process. This protects the information written from the process at the higher sensitivity label from being accessed by other processes running at lower sensitivity labels.
The setcmwlabel(2) system call programmatically sets the CMW label on a file system object.
The File Manager lets an authorized user change the sensitivity label on an existing file's CMW label.
The system calls that get and set process and file system object CMW labels require mandatory and discretionary access to the process or file system object and may require privilege if access is denied by the system security policy. See "System Calls" for a list of system calls.
The calling process needs the sys_trans_label privilege in its effective set to translate a label between binary and text if the label being translated is not dominated by the process's sensitivity label. This privilege is also required to check if a label is valid when the process sensitivity label does not dominate the label being checked.
The calling process needs the proc_setsl privilege in its effective set to set its own sensitivity label to another label not equal to the current sensitivity label.
The calling process needs the file_owner privilege in its effective set to downgrade the sensitivity label on a file not owned by the calling process.
A process can set the sensitivity label on a file system object to a new sensitivity label that does not dominate the object's existing sensitivity label with the file_downgrade_sl privilege in its effective set.
A process can set the sensitivity label on a file system object to a new sensitivity label that dominates the object's existing sensitivity label with the file_upgrade_sl privilege in its effective set.
This section provides guidelines for you to follow when your program must use privileges to bypass access controls or change the sensitivity label.
Most applications do not use privileges to bypass access controls because they operate in one of the following ways:
An application is launched by one user or many users at one sensitivity label and accesses data in objects at that same sensitivity label.
An application is launched by one user or many users at one sensitivity label and accesses data in objects at other sensitivity labels, but the mandatory access operations are allowed by the system security policy as described in "Security Policy".
An application is launched by one user or many users at different sensitivity labels and accesses data in objects at that same sensitivity label by way of multilevel directories. Multilevel directories are described in Chapter 7, Multilevel Directories.
If an application accesses data at sensitivity labels other than the sensitivity label of its process and access is denied, the process needs privilege to gain access. Privileges let the application bypass mandatory or discretionary access controls (file_mac_read, file_dac_read, file_mac_write, file_dac_write, file_mac_search or file_dac_search), change the process sensitivity label so mandatory access is granted (proc_setsl), or upgrade or downgrade the sensitivity label of the data (file_upgrade_sl, file_downgrade_sl). No matter how access is obtained, the application design must abide by the guidelines presented here to not compromise the classification of data accessed.
If you use privileges to bypass mandatory access restrictions, be careful your application does not write data out at a lower sensitivity label than the label at which it read the data. Also, your application design should not allow the accidental downgrading of data due to program errors.
Follow these guidelines when your application changes its own sensitivity label or the sensitivity label of another object.
Upgrade a sensitivity label whenever possible.
A program that upgrades a sensitivity label is safer than a program that downgrades a sensitivity label because application errors that cause information leaks upgrade the data, rather than downgrade it. Upgrading data results in the over classification of the data, but is not a security breach. You can use privileges to downgrade a sensitivity label, but use these privileges very carefully.
Never change a process sensitivity label more than once. Changes to the process sensitivity label increase the possibility of accidentally transmitting data between different levels. Any change to the process sensitivity label is an upgrade or downgrade of the information in the process address space.
Close all file descriptors when changing a file or process sensitivity label so sensitive data is not available to other processes.
Instead of changing the process sensitivity label, fork() a new process and change the sensitivity label of the forked process so tasks can be performed at another level separate from the data in the forking process. The forked process should either return information to the forking process or send the information to another process.
Information returned by a forked process at a changed sensitivity label should provide no more information than absolutely necessary. For example, provide the success or failure of a computation, and not the actual data. Returning or passing specific information keeps the data used to make the computation secure and prevents data at one level from mixing with data at another level.
To use the programming interfaces described in this chapter, you need the following header file.
#include <tsol/label.h>
The examples in this chapter compile with the following library:
-ltsol |
The data structure bclabel_t represents a binary CMW label. Interfaces accept and return a binary CMW label in a structure of type bclabel_t.
The setting_flag type definition defines CMW label flag values as follows:
SETCL_SL - Set the sensitivity label portion of the CMW label. SETCL_ALL - Set the entire CMW label.
The bslabel_t type definition represents the sensitivity label portion of a binary CMW label. Interfaces accept as parameters and return binary sensitivity labels in a variable of type bslabel_t. The bslabel_t type definition is compatible with the blevel_t structure.
The blevel_t structure represents a binary level, which is a classification and set of compartments in a sensitivity label or clearance. Interfaces accept and return binary levels in a structure of type blevel_t.
Any variable of type bclear_t or bslabel_t can be passed to a function that accepts a parameter of type blevel_t.
The brange_t data structure represents a range of sensitivity labels. The structure holds a minimum label and a maximum label. The structure fields are referred to as variable.lower_bound and variable.upper_bound.
The set_id data structure currently accepts the following values: SYSTEM_ACCREDITATION_RANGE; USER_ACCREDITATION_RANGE.
The label_info structure contains length specifications of items in the label_encodings file. The structure is returned by labelinfo(3TSOL).
Field |
Description |
---|---|
slabel_len |
Maximum sensitivity label length. |
clabel_len |
Maximum CMW label length. |
clear_len |
Maximum clearance label length. |
vers_len |
Version string length. |
header_len |
Maximum length of the printer banner. |
protect_as_len |
Maximum length of a printer banner page header string returned by bcltobanner(3TSOL). |
caveats_len |
Maximum length of the printer banner page string returned by bcltobanner(3TSOL). |
channels_len |
Maximum length of a printer banner page channels string. |
The banner_fields structure contains the translated text labels and strings for display on printer banner and trailer pages and at the top and bottom of document body page. The structure is returned by bcltobanner(3TSOL). The first five fields consist of pointers to character strings, and the second five consist of short integer lengths of memory preallocated to the corresponding string pointer.
Field |
Description |
---|---|
header |
String appears on top and bottom of the banner and trailer pages. |
protect_as |
String appears in protect as banner page section. |
caveats |
String appears in the caveats banner page section. |
channels |
String appears in the handling channels section. |
header_len |
Preallocated string memory length for header. |
protect_as_len |
Preallocated string memory length for protect as section. |
caveats_len |
Preallocated string memory length for caveats section. |
channels_len |
Preallocated string memory length for channels section. |
The following programming interfaces are available for general label operations and accessing labels on processes and file system objects.
These system calls get and set a file or process CMW label, or get the file system label range.
Every process that sets a label on another process or file system object must set a valid label as defined in the label_encodings file, and must pass the correct binary form of the label. The text to binary translation functions correct the label as much as possible to ensure a correct binary label results from the translation. However, you might still use the bslvalid(3TSOL) routine to check that the label is valid. A correctly constructed binary label can be invalid for a given system or user and should be checked that it falls within the system or user accreditation range with the blinset(3TSOL) routine.
These system calls get and set the file CMW label by the path name or file descriptor. Refer to the setcmwlabel(2) and getcmwlabel(2) man pages.
int setcmwlabel(const char *path, const bclabel_t *label, const setting_flag_t flag); int getcmwlabel(const char *path, const bclabel_t *label); int fsetcmwlabel(const int fd, const bclabel_t *label, const setting_flag_t flag); int fgetcmwlabel(const int fd, bclabel_t *label); int lsetcmwlabel(const int fd, const bclabel_t *label, const setting_flag_t flag); int lgetcmwlabel(const int fd, bclabel_t *label);
These system calls get and set the process CMW label. Refer to the setcmwplabel(2) and getcmwplabel(2) man pages.
int setcmwplabel(const bclabel_t *label, const setting_flag_t flag); int getcmwplabel(const bclabel_t *label);
These system calls get the file system label range. Refer to the getcmwfsrange(2) man page.
int getcmwfsrange(char *path, brange_t *range); int fgetcmwfsrange(int fd, brange_t *range);
These library routines access, initialize, compare, translate, and verify labels. Library routines also obtain information on label_encodings(4).
These routines initialize a CMW label to ADMIN_HIGH, ADMIN_LOW, or undefined (similar to NULL). Refer to the blmanifest(3TSOL) man page.
void bclhigh(bclabel_t *label); void bcllow(bclabel_t *label); void bclundef(bclabel_t *label);
These routines access the sensitivity label portion of a CMW label. Refer to the blportion(3TSOL) man page.
void getcsl(bslabel_t *destination_label, const bclabel_t *source_label); void setcsl(bclabel_t *destination_label, const bslabel_t *source_label); bslabel_t *bcltosl(bclabel_t *label);
These routines initialize a sensitivity label to ADMIN_HIGH, ADMIN_LOW, or undefined. Refer to the blmanifest(3TSOL) man page.
void bslhigh(bslabel_t *label); void bsllow(bslabel_t *label); void bslundef(bslabel_t *label);
These routines compare two levels to see if level1 equals, dominates, or strictly dominates level2. A level is a classification and set of compartments in a sensitivity label or clearance.
A returned non-zero is true and 0 is false. Refer to the blcompare(3TSOL) man page.
int blequal(const blevel_t *level1, const blevel_t *level2); int bldominates(const blevel_t *level1, const blevel_t *level2); int blstrictdom(const blevel_t *level1, const blevel_t *level2); int blinrange(const blevel_t *level, const brange_t *range);
These routines check or set label type. A label can be a defined or undefined CMW label or sensitivity label. Refer to the bltype(3TSOL) man page.
int bltype(const void *label, const unsigned char type); void setbltype(void *label, const unsigned char type);
These routines compare two levels to find the sensitivity level that represents the greatest lower bound (blminimum(3TSOL)) or least upper bound (blmaximum(3TSOL)) of the range bounded by the two levels. A level is a classification and set of compartments in a sensitivity label or clearance. Refer to the blcompare(3TSOL) man page.
void blmaximum(blevel_t *maximum_label, const blevel_t *bounding_label); void blminimum(blevel_t *minimum_label, const blevel_t *bounding_label);
The label_encodings file is a text file maintained by the system administrator that contains site-specific label definitions and constraints. This file is kept in /etc/security/tsol/label_encodings. See Trusted Solaris Label Administration and Compartmented Mode Workstation Labeling: Encodings Format for information on the label_encodings file.
These routines return information specified in the label_encodings file on maximum string lengths, version of label_encodings file in use, and text color name for the specified binary level.
Maximum string lengths. Refer to the labelinfo(3TSOL) man page.
int labelinfo(struct label_info *info);
Version in use. Refer to the labelvers(3TSOL) man page.
int labelvers(char **version, const int length);
Text color name for a binary level. Refer to the bltocolor(3TSOL) man page.
char bltocolor(const blevel_t *label); char bltocolor_t(const blevel_t *label, const int size, char * color_name);
This routine checks whether the specified sensitivity label is valid for the system (is defined in the label_encodings file for the system). Refer to the blvalid(3TSOL) man page.
int bslvalid(const bslabel_t *senslabel);
This routine checks whether the sensitivity label falls within the system accreditation range as set in the label_encodings file for the system. Refer to the blinset(3TSOL) man page.
int blinset(const blevel_t *senslabel, const set_id *id);
These routines translate a binary CMW label or sensitivity label from binary to text and back again. When translating from a string to binary, the string can be text or hexadecimal when flag is NEW_LABEL or NO_CORRECTION. Refer to the bltos(3TSOL) and stobl(3TSOL) man pages.
See Chapter 14, Trusted X Window System for interfaces that translate binary labels to text, clip the final label according to a specified width, and use a font list for display in Motif-based graphical user interfaces (GUIs).
int bcltos(const bclabel_t *label, char **string, const int length, const int flags); int stobcl(const char *string, bclabel_t *label, const int flags, int *error); /* Translate and Clip string to length */ char *sbcltos(const bclabel_t *label, const int length); /* Translate for inclusion on printer banner and header pages */ char *bcltobanner(const bclabel_t *label, struct banner_fields *fields, const int flags);
int bsltos(const bslabel_t *label, char **string, const int length, const int flags); int stobsl(const char *string, bslabel_t *label, const int flags, int *error); /* Translate and clip string to length */ char *sbsltos(const bslabel_t *label, const int length);
These routines translate a binary CMW label or sensitivity label from binary to hexadecimal and back again. Refer to the btohex(3TSOL) and hextob(3TSOL) man pages.
char h_alloc(const unsigned char id); void h_free(char *hex);
char *bcltoh(const bclabel_t *label); char *bcltoh_r(const bclabel_t *label, char *hex); int htobcl(const char *hex, bclabel_t *label);
char *bsltoh(const bslabel_t *label); char *bsltoh_r(const bslabel_t *label, char *hex); int htobsl(const char *hex, bslabel_t *label);