Section 9.2. Boolean Variables


9.2. Boolean Variables

What makes conditional policies "conditional" is the effect of conditional expressions. Conditional expressions are formed by using one or more Boolean variables in conjunction with logical operators and then changing the Boolean values to effect the value of the conditional expression, thereby changing which set of rules in the conditional statement are in effect. Therefore, the first step in writing conditional policies is creating the Boolean variables.

9.2.1. Defining Boolean Variables

We use the bool statement to define Boolean variables. For example, suppose we want to configure the policy such that the ability for ordinary users to use the ping program can be turned on and off. For this example, we need to define a Boolean variable, say user_ping, that we will use in a conditional expression. To define this variable, we write the following statement:

bool user_ping false; # controls whether users may use ping program


The bool statement has two arguments, the name of the Boolean (user_ping) and its default value, which can be true or false. In this case, the default value (false) means that ordinary users, by default, cannot use ping (assuming our conditional statement is written correctly). You can see the full syntax for the bool statement in the sidebar on page 186.

Bool Statement Syntax

The bool statement defines conditional booleans and their default value. The full syntax for the bool statement is as follows:

bool bool_name default_value;


bool_name

An identifier for the Boolean variable. The identifier can be any length and can contain ASCII characters, numbers, or an underscore (_). It must begin with an ASCII character.

default_value

The default Boolean value of the variable, either TRue or false.


The bool statement is valid in monolithic policies, base loadable modules, and non-base loadable modules. It is not valid in conditional statements.


9.2.2. Managing Booleans in a Running System

The ability to change Boolean variable values in a running system is what enables us to vary the value of conditional expressions, and hence gives us conditional policies. Therefore, it is necessary for the SELinux kernel to make Boolean variables available to running processes for changes. This is different from any other component of the policy, which once loaded into the kernel is static until a new entire policy is loaded. Booleans are individually accessible and changeable on the running system.

The kernel exposes the Booleans via the selinux pseudo filesystem. This pseudo filesystem is the primary interface between user space and the SELinux Linux Security Module (LSM) in the kernel. The filesystem is typically mounted on /selinux/. All Boolean variables defined in the current policy will show up as files in the booleans directory of this pseudo filesystem. So, for example, you would be able to see the Boolean defined above as a file with a path name of /selinux/booleans/user_ping.

We use the Boolean files in the selinux filesystem to query and set the current values of Boolean variables. If you view the contents of a Boolean file, you will always see a pair of numbers (either 0 or 1 for false or true), as follows:

# cat /selinux/booleans/user_ping 1 1


This first number indicates the current value of the Boolean variable; in this case, 1 for true. The second number represents the pending value of the Boolean variable. The current value is the actual value being used by the kernel for the Boolean and for determining the value of conditional expressions. The pending is the value to which the Boolean's current value will be changed when Booleans changes are committed.

We change the current value of a Boolean by changing the Boolean's pending value and then committing the changes to the kernel. We change the pending value by writing a 1 or 0 to the Boolean file, as follows:

# cat /selinux/booleans/user_ping   # current & pending values same (1) 1 1 # echo 0 > /selinux/booleans/user_ping # write a '0' to the file # cat /selinux/booleans/user_ping      # pending value is changed (0) 1 0


As you can see, the pending value has now changed to 0, meaning false. The current value remains the same. This means that the value of the Boolean user_ping is still true (1) even though you changed its pending value to false (0). The reason is that changing Booleans requires a two-step commit process. First, you change the pending value for those Booleans you want to change (the default pending value is always the current value), and then you commit the pending values to the current value. This allows you to change more than one Boolean and then commit all changes in one step.

The file /selinux/commit_pending_bools is the interface for committing the pending values of all Booleans as the current values. You cause the commit to occur by writing a 1 to this file, as follows:

# echo 1 > /selinux/commit_pending_bools # commit all pending values # cat /selinux/booleans/user_ping 0 0


The first command writes the commit_pending_bools file, which causes the kernel to change the current value for all Booleans to their pending value. As you can see by examining the user_ping Boolean, the change we made earlier is now committed. The current value of this Boolean is now false (0) as is the pending value. (Recall that the default pending value is always the current value.)

To reset the Boolean back to true, we just do the reverse:

# echo 1 > /selinux/booleans/user_ping    # set pending value true # cat /selinux/booleans/user_ping         # see pending value changed 0 1 # echo 1 > /selinux/commit_pending_bools  # commit pending value # cat /selinux/booleans/user_ping         # see current value changed 1 1


SELinux provides convenient commands for querying and changing Booleans without having to remember their file locations. The getsebool command displays the state of a Boolean as active (TRue) or inactive (false). For example:

# getsebool user_ping user_ping > active


Note

Recent improvements in SELinux, available in Fedora Core 5 (FC5), have changed the displayed values from the command getsebool to the more intuitive on and off rather than active and inactive.


To see all Booleans defined in the running system and their state, you would use the -a option, as follows:

# getsebool -a docked > inactive user_ping > active ...


We can also change the value of Booleans using the setsebool command:

# getsebool user_ping        # show current state user_ping > active # setsebool user_ping false  # change and commit current state # getsebool user_ping        # show changed stated user_ping > inactive


Notice that the setsebool command changes both the pending state and commits the change as the current state. We do not need to run the two separate commands as you saw earlier when using the setsebool command, nor do we need to know the full path name of the Boolean file.

We can also use the setsebool command to change multiple Booleans in a single transaction using an alternative format for the arguments, such as this:

# getsebool user_ping docked        # show current state user_ping > active docked > inactive # setsebool user_ping=0 docked=1    # change state of both # getsebool user_ping docked        # show current state user_ping > inactive docked > active


Warning

The Booleans defined on your system depend on the policy loaded into the running kernel. You will likely see different Booleans than those used here in our contrived examples. Do not be confused by this. If you want, add these Booleans as an exercise, or play with the Booleans defined in your policy.


9.2.3. Persistent Changes to Boolean Values

As previously discussed, Boolean variables are defined in the policy file along with their default state. After the inclusion of Booleans into the SELinux policy language, a problem arose of how to change the default state of a Boolean without having to re-create the policy. (The policy once written should be a fairly static entity.) Thus the idea of a persistent value was introduced. A standard library used by SELinux utilities provides a means for making persistent changes to Booleans by maintaining a file with Boolean persistent values. The init process uses this file to override the policy defaults during system initialization. In this way, we can make changes to the current values of Booleans that persist across a reboot, without having to modify the static SELinux policy.

In Fedora Core 4 (FC4) and Red Hat Enterprise Linux version 4 (RHEL4) systems, loadable SELinux policies are conventionally stored in the directory /etc/selinux/[pol_name/], where pol_name is a the name of a subdirectory containing an SELinux policy and related files. In RHEL4, the file in a policy subdirectory we want to discuss here is named booleans. This file contains names of Booleans and their default override values. The init process reads this file for the active policy after loading the policy into the kernel and then changes the current value for all Booleans listed in the file. If we look inside this file, we would see contents something such as the following, depending on the associated policy:

# cat booleans     # run in policy subdir, for example, /etc/selinux/strict/ ftpd_is_daemon=1 ftp_home_dir=1 ssh_sysadm_login=1 staff_read_sysadm_file=1 user_ping=1


We can see our user_ping Boolean here and other Booleans that require examining the policy to understand their intended use. Therefore, to make a change to a Boolean current value consistent, we would change the current value as previously discussed and edit the booleans file for the active policy. Doing so will ensure that the change to the current value will persist across a reboot, if that is the desired effect.

Note

When the policy is reloaded on a running system, the currently active state of the Booleans is maintained instead of being reset to the default or persistent state. This ensures that nonpersistent Boolean changes are preserved while a system is running.


In FC4, a new file was introduced named booleans.local, which is used in the same way as the booleans file is used on RHEL4. The booleans file remains, but its purpose was changed to store distribution-defined default Boolean values defined as part of the policy package. The booleans.local file contains locally defined override values for Booleans that take precedence over the booleans file. This change allows the default state in the booleans file to be easily changed when upgrading the policy without impacting local customizations.

FC5 includes the loadable module infrastructure, which no longer has user-editable files for storing persistent Boolean values. The tools for managing the policy, including the persistent mode of setsebool (discussed below), interact directly with the module infrastructure to store the persistent Boolean values. Therefore, in FC5, you should always use the setsebool or other system command to change Boolean values.

The setsebool command provides a convenient option, -P, to make Boolean changes persistent. This option works across RHEL4, FC4, and FC5. When this option is used with setsebool, all changes are reflected in the active policy as a local override of the policy default values. (Otherwise, the change affects only the running policy and will be reset to the default value at the next boot.) For example, on an RHEL4 system, we have the following:

# getsebool user_ping              # show current running state user_ping > active # cat booleans | grep user_ping    # and persistent state user_ping=1 # setsebool user_ping false        # change current state # getsebool user_ping              # current stated changed user_ping > inactive # cat booleans | grep user_ping    # but persistent state did not user_ping=1 # setsebool -P user_ping false     # persistent change with -P # getsebool user_ping              # current state still false user_ping > inactive # cat booleans | grep user_ping    # now persistent changed too user_ping=0


Note

You do not necessarily want to make a change to a Boolean current value persistent. It all depends on your use of the Boolean. In some cases, you want to change, or toggle, the Boolean, perhaps several times, on a running system but reset to its default value on a reboot. In this case, you do not want to make the change persistent.





SELinux by Example(c) Using Security Enhanced Linux
SELinux by Example: Using Security Enhanced Linux
ISBN: 0131963694
EAN: 2147483647
Year: 2007
Pages: 154

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net