Section 12.4. Examining a Reference Policy Module


12.4. Examining a Reference Policy Module

To help further understand how the reference policy works, let's examine all aspects of the policy for the ping program as we did with the example policy. Whereas in the example policy the ping program had its own module, in the reference policy ping is included in a module that addresses all administrative network utilities (netutils). We can find this module in policy/modules/admin/netutils.*.

Note

In the reference policy, we try to package policy pieces in ways that make sense for installation with software packages. Reference policy is mostly influenced by the packaging conventions for FC. This allows us to define modules that can be built as loadable modules and installed as part of the package installation (the real benefit of loadable modules). This is the reason that ping is coupled with a number of other network utilities; these utilities are all part of the same software package in FC (specifically the iputils package).


Listing 12-3 shows a partial listing of the netutils.te module file, focusing on those components related to ping. Recall that the .te file is the file that contains the module's private declarations and rules. This is the file in which we would generally expect to find type and attribute declarations. First notice the use of the policy_module() support macro on line 1. All modules must use the policy_module() as their first line in their .te file. This macro requires two arguments: the name of the module and the version of the module. Currently, the policy_module() support macro effects only the build process when the module is being built as a loadable module. Nonetheless, its use is mandatory for all modules, and its function will likely evolve over time (for example, better debugging support).

Listing 12-3. Partial Listing for netutils (ping) Private Module File (netutils.te)

 1 policy_module(netutils,1.0)  2 ########################################  3 # Declarations  4 type ping_t;  5 type ping_exec_t;  6 init_system_domain(ping_t,ping_exec_t)  7 role system_r types ping_t;  8  9 ######################################## 10 # Ping local policy 11 allow ping_t self:capability { setuid net_raw }; 12 dontaudit ping_t self:capability sys_tty_config; 13 14 allow ping_t self:tcp_socket create_socket_perms; 15 allow ping_t self:udp_socket create_socket_perms; 16 allow ping_t self:rawip_socket { create ioctl read write bind    getopt setopt }; 17 18 corenet_tcp_sendrecv_all_if(ping_t) 19 corenet_udp_sendrecv_all_if(ping_t) 20 corenet_raw_sendrecv_all_if(ping_t) 21 corenet_raw_sendrecv_all_nodes(ping_t) 22 corenet_tcp_sendrecv_all_nodes(ping_t) 23 corenet_udp_sendrecv_all_nodes(ping_t) 24 corenet_tcp_sendrecv_all_ports(ping_t) 25 corenet_udp_sendrecv_all_ports(ping_t) 26 corenet_udp_bind_all_nodes(ping_t) 27 corenet_tcp_bind_all_nodes(ping_t) 28 29 fs_dontaudit_getattr_xattr_fs(ping_t) 30 31 domain_use_wide_inherit_fd(ping_t) 32 33 files_read_etc_files(ping_t) 34 files_dontaudit_search_var(ping_t) 35 36 libs_use_ld_so(ping_t) 37 libs_use_shared_libs(ping_t) 38 39 sysnet_read_config(ping_t) 40 sysnet_dns_name_resolve(ping_t) 41 42 logging_send_syslog_msg(ping_t) 43 44 ifdef('hide_broken_symptoms',' 45     init_dontaudit_use_fd(ping_t) 46 ') 47 48 ifdef('targeted_policy',' 49     term_use_unallocated_tty(ping_t) 50     term_use_generic_pty(ping_t) 51     term_use_all_user_ttys(ping_t) 52     term_use_all_user_ptys(ping_t) 53 ',' 54     tunable_policy('user_ping',' 55            term_use_all_user_ttys(ping_t) 56            term_use_all_user_ptys(ping_t) 57     ') 58 ')

On lines 4 through 7, we define our domain type (ping_t) and entrypoint type (ping_exec_t). These two types serve exactly the same purpose as with the example policy. Indeed, the goal of the reference policy implementation of the ping domain type is to be the functional equivalent to the policy rules in the example policy (but implemented in an entirely different manner). Notice on line 6 that we call an interface from the init module that allows the ping domain to be used in system initialization scripts. As a point of comparison, this interface performs nearly the exact same purpose as the macro called on line 9 of the example policy ping module in Listing 11-1.

All the remaining lines in Listing 12-3 implement the rules that allow the ping domain type access necessary to perform its function. For example, the interface calls in lines 18 through 27 provide the necessary network access by using interfaces from the core network (corenetwork) module. Much of the access is provided via interfaces; this is the expected form of a module implementation so that access is defined only in one place and interfaces are called elsewhere to use that access. Again, we can examine the purpose of each of these interfaces by examining their implementation or more easily by reading through the interface documentation that is generated. As you read through this listing, you will also notice uses of the target_policy conditional on line 48 to define targeted-only policy rules.

Now let's look at the interfaces for ping, which will be defined in the netutils interface file (netutils.if), a partial list of which is shown in Listing 12-4. In addition to defining the interfaces themselves, the .if file also contains the XML statements that are used to generate documentation. As you see on line 1 in Listing 12-4, all module interface files must start with a summary statement that provides a concise statement of the module's purpose. Because ping is part of a larger network utilities module, we see a statement that summarizes the whole purpose of the module (although in Listing 12-4 we show only those parts of the module that relate to ping).

Listing 12-4. Partial Listing for netutils (ping) Interface Module File (netutils.if)

 1 ## <summary>Network analysis utilities</summary>  2  3 ########################################  4 ## <summary>  5 ## Execute ping in the ping domain.  6 ## </summary>  7 ## <param name="domain">  8 ## The type of the process performing this action.  9 ## </param> 10 interface('netutils_domtrans_ping',' 11    gen_require(' 12          type ping_t, ping_exec_t; 13          class process sigchld; 14          class fd use; 15          class fifo_file rw_file_perms; 16    ') 17 18    domain_auto_trans($1,ping_exec_t,ping_t) 19 20    allow $1 ping_t:fd use; 21    allow ping_t $1:fd use; 22    allow ping_t $1:fifo_file rw_file_perms; 23    allow ping_t $1:process sigchld; 24 ') 25 26  ######################################## 27  ## <summary> 28  ## Execute ping in the ping domain, and 29  ## allow the specified role the ping domain. 30  ## </summary> 31  ## <param name="domain"> 32  ## The type of the process performing this action. 33  ## </param> 34  ## <param name="role"> 35  ## The role to be allowed the ping domain. 36  ## </param> 37  ## <param name="terminal"> 38  ## The type of the terminal allow the ping domain to use. 39  ## </param> 40  interface('netutils_run_ping',' 41     gen_require(' 42           type ping_t; 43     ') 44 45     netutils_domtrans_ping($1) 46     role $2 types ping_t; 47     allow ping_t $3:chr_file rw_term_perms; 48  ') 49 50  ######################################## 51  ## <summary> 52  ## Conditionally execute ping in the ping domain, and 53  ## allow the specified role the ping domain. 54  ## </summary> 55  ## <param name="domain"> 56  ## The type of the process performing this action. 57  ## </param> 58  ## <param name="role"> 59  ## The role to be allowed the ping domain. 60  ## </param> 61  ## <param name="terminal"> 62  ##  The type of the terminal allow the ping domain to use. 63  ## </param> 64  interface('netutils_run_ping_cond',' 65     gen_require(' 66           type ping_t; 67           bool user_ping; 68     ') 69 70     role $2 types ping_t; 71 72     if ( user_ping ) { 73           netutils_domtrans_ping($1) 74           allow ping_t $3:chr_file rw_term_perms; 75     } 76  ') 77 78  ######################################## 79  ## <summary> 80  ## Execute ping in the caller domain. 81  ## </summary> 82  ## <param name="domain"> 83  ## The type of the process performing this action. 84  ## </param> 85  interface('netutils_exec_ping',' 86     gen_require(' 87         type ping_exec_t; 88    ') 89 90    can_exec($1,ping_exec_t) 91  ')

In lines 11 through 16, 41 and 43, 65 through 68, and 86 through 88, we see the use of another support macro, gen_require(). This macro is key to supporting the loadable module infrastructure and eventually for supporting development tools that need module and interface dependency information. Each module interface file must have a gen_require() macro that lists the policy identifiers (names of types, attributes, roles, Booleans, and so on) that this interface uses. For types and attributes, these identifiers must be types and attributes private to the module (because only private types and attributes may be explicitly named within a module). The gen_require() macro will generate the appropriate dependency information to support various types of policy builds. This allows, for example, the ability to link a loadable module without the entire policy source being available.

The rest of the partial .if file in Listing 12-4 defines four ping-related interfaces in much the same way we already discussed. All these interfaces are access interfaces using the interface() macro. The first interface, netutils_domtrans_ping(), which is defined in lines 3 through 24, supplies all the rules to allow a provided domain type permission to cause a domain transition into the ping domain type. The two interfaces, netutils_run_ping(), defined in lines 26 through 48, and netutils_run_ping_cond(), defined in lines 50 through 76, call the netutils_domtrans_ping() interface but also require a role to ensure that the role is authorized for the ping domain. The latter of these two interfaces support the use of a conditional expression based on the user_ping Boolean (lines 72 through 75) much as we discussed for the example policy in Chapter 11.

The final interface, netutils_exec_ping(), defined in lines 78 through 91, simply allows the provided domain type the ability to execute the ping program without a domain transition. In this case, the provided domain type must have the necessary network access itself, which is the case of some system utilities and daemons.

Finally, let's look at the file labeling policy, which we can find in the netutils.fc file. In that file, there should be a line such as this

/bin/ping.*  --   gen_context(system_u:object_r:ping_exec_t,s0)


This line is similar to ping's file context file we saw in the example policy with one significant difference: The file context is provided within another support macro, gen_context(). This macro contains a full security context, including any optional MLS portion. The gen_context() macro generates security contexts with or without the MLS portion based on the build type. In this way, we can write a policy with or without the optional MLS features without having to change the contents of the file or cause irreversible changes to the sources as with the example policy.




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