Trusted Solaris Developer's Guide

Bracketing Effective Privileges

Privilege bracketing involves turning the effective privileges off (they are on and equal the permitted set by default), then turning on (making effective) only those permitted privileges needed for a given interface call, and turning them off when the privileged call completes.

When you analyze which privileges are needed for an interface, look at what the interface does and the purpose of the privileges described on the man page for that interface. Some privileges have broader effects than others and should be treated with greater scrutiny.

For example, it is relatively easy to examine a segment of code to see that it uses a privilege with the mount(1M) system call and tell whether the use of that privilege can be exploited in any way. It is more difficult to tell if the use of a privilege to override the mandatory or discretionary access policy to access a restricted file can be exploited.

It is up to you to perform privilege bracketing in your code and to do it correctly. Always remember that all privileges override some policy that is not allowed to untrusted processes, and handle your use of privileges with the needed care.

Procedure for Bracketing Privileges

The procedure for bracketing the setfpriv(1) system call and the effects it has on the effective set are summarized here. The code is shown in the next headings.

At the start of execution before bracketing, the permitted and effective sets contain these privileges:


Permitted = file_mac_write,file_setpriv,proc_setid
Effective = file_mac_write,file_setpriv,proc_setid
  1. Clear the effective set at the beginning of the application.


    Permitted = file_mac_write,file_setpriv,proc_setid
    Effective = none
  2. Bracket the setfpriv() system call.

    1. Turn the file_setpriv privilege on in the effective set right before you call the setfpriv() system call.


      Permitted = file_mac_write,file_setpriv,proc_setid
      Effective = file_setpriv
    2. Turn off the effective set immediately after the setfpriv() system call.


      Permitted = file_mac_write,file_setpriv,proc_setid
      Effective = none

Clear Effective Set

The example uses set_effective_priv(3TSOL) to clear the effective set at the beginning of the application. The PRIV_SET parameter clears the effective privilege set, and the zero (0) indicates there is no parameter list of privilege IDs.

if (set_effective_priv(PRIV_SET, 0) == -1)
	perror("Cannot clear effective privileges");

Continue Application Code

Turning the entire effective privilege set off is followed by application code until a privilege is needed.

Bracketing the Call

The example uses set_effective_priv(3TSOL) to bracket. The first call turns the file_setpriv privilege on (asserts it) in the effective set; the second call turns it off. The 1 indicates the privilege parameter list has one privilege constant (PRIV_FILE_SETPRIV) in it.

/* Turn file_setpriv on in effective set */
	if (set_effective_priv(PRIV_ON, 1, PRIV_FILE_SETPRIV) == -1)
		perror("Cannot assert PRIV_FILE_SETPRIV");

/* Make interface call */
	retval = setfpriv(execfile, PRIV_SET, PRIV_ALLOWED, &priv_get);

/* Turn the file_setpriv privilege off */
	if (set_effective_priv(PRIV_OFF, 1, PRIV_FILE_SETPRIV) == -1)
		perror("Cannot clear PRIV_FILE_SETPRIV");

/* Continue application code ...*/

Bracketing in Example

This next example shows the body of the example application code with comments indicating the places where setfpriv(1) should be bracketed.

	PRIV_EMPTY(&priv_get);
	PRIV_EMPTY(&priv_set);

/* Turn file_setpriv on in the effective set */
	retval = setfpriv(execfile, PRIV_SET, PRIV_ALLOWED, &priv_get);
/* Turn the file_setpriv privilege off */

	if((string = str_to_priv_set(priv_names, &priv_set, ",")) != NULL)
		printf("string = %s errno = %d\n", string, errno);

/* Turn file_setpriv on in the effective set */
	retval = setfpriv(execfile,PRIV_ON, PRIV_ALLOWED, &priv_set);
/* Turn the file_setpriv privilege off */

	retval = getfpriv(execfile, PRIV_ALLOWED, &priv_get);
	priv_set_to_str(&priv_get, ',', buffer, &length);
	printf("execfile Allowed = %s\n", buffer);

	PRIV_EMPTY(&priv_set);
	PRIV_EMPTY(&priv_get);
	PRIV_ASSERT(&priv_set, PRIV_FILE_MAC_WRITE);

/* Turn file_setpriv on in the effective set */
	retval = setfpriv(execfile, PRIV_ON, PRIV_FORCED, &priv_set);
/* Turn the file_setpriv privilege off */

	retval = getfpriv(execfile, PRIV_FORCED, &priv_get);
	priv_set_to_str(&priv_get, `,', buffer, &length);
	printf("execfile Forced =%s\n", buffer);