PaulHowarth/Blog/2006-04-20

Thursday 20th April 2006

Fedora Extras

  • Built perl-Math-Pari, perl-Crypt-Random, perl-Crypt-Primes, perl-Crypt-RSA, and perl-Net-SSH-Perl for FC4 and FC5

SELinux

Rewrote the SELinux policy module for mock that I did yesterday. Whilst it handled the execmod issue for old distro libraries fairly cleanly, it wasn't able to handle the problem I'd been having building mono applications. It took me a surprisingly long amount of time to twig that this was an SELinux issue. Mono apps normally run in their own domain, mono_t, and have execmem and execheap privileges. This particular problem was caused by running mono in the unconfined_t domain and not being allowed execheap privilege. Domain transitions don't happen in mock because it makes child processes think that SELinux is disabled, so even getting /usr/bin/mono in the buildroot set to mono_exec_t wouldn't help. This left me with two options as I could see:

  1. Allow unconfined_t execheap privilege (equivalent to turning on the allow_execheap boolean)

  2. Run the entire mock process in its own domain, and grant that domain execheap privilege

Clearly the second option made more sense as it only enabled execheap for mock rather than virually every process run by a user. I also took the opportunity of removing mock_root_t as there didn't seem to be much point in differentiating between mock_var_lib_t and mock_root_t.

So here's the new mock policy module, mostly cribbed from the mono policy:

mock.if:

## <summary>Build packages in a chroot environment.</summary>

########################################
## <summary>
##      Execute the mock program in the mock domain.
## </summary>
## <param name="domain">
##      <summary>
##      Domain allowed access.
##      </summary>
## </param>
#
interface(`mock_domtrans',`
        gen_require(`
                type mock_t, mock_exec_t;
        ')

        corecmd_search_bin($1)
        domain_auto_trans($1, mock_exec_t, mock_t)

        allow $1 mock_t:fd use;
        allow mock_t $1:fd use;
        allow mock_t $1:fifo_file rw_file_perms;
        allow mock_t $1:process sigchld;
')

########################################
## <summary>
##      Create objects in the /var/lib/mock directory
## </summary>
## <param name="domain">
##      <summary>
##      Domain allowed access.
##      </summary>
## </param>
## <param name="file_type">
##      <summary>
##      The type of the object to be created
##      </summary>
## </param>
## <param name="object_class">
##      <summary>
##      The object class.
##      </summary>
## </param>
#
interface(`files_var_lib_mock_filetrans',`
        gen_require(`
                type var_t, var_lib_t, mock_var_lib_t;
        ')

        allow $1 var_t:dir search_dir_perms;
        allow $1 var_lib_t:dir search_dir_perms;
        allow $1 mock_var_lib_t:dir rw_dir_perms;
        type_transition $1 mock_var_lib_t:$3 $2;
')

mock.fc:

/usr/bin/mock                   --      gen_context(system_u:object_r:mock_exec_t,s0)

/var/lib/mock(/.*)?                     gen_context(system_u:object_r:mock_var_lib_t,s0)

mock.te:

policy_module(mock, 0.7.1)

########################################
#
# Declarations
#

type mock_t;
domain_type(mock_t)

type mock_exec_t;
domain_entry_file(mock_t,mock_exec_t)

type mock_var_lib_t;
files_type(mock_var_lib_t)

########################################
#
# Local policy
#

ifdef(`targeted_policy',`

        # execheap & execmem are needed to run mono under mock
        # where no transition to mono_t will happen
        allow mock_t self:process { execheap execmem };
        unconfined_domain_noaudit(mock_t)
        role system_r types mock_t;

        # Old libraries may need execmod permission
        allow mock_t mock_var_lib_t:file execmod;

        # Transition to mock_t from unconfined_t
        mock_domtrans(unconfined_t)

')

Building and installing is easy. Copy the three files into an empty directory and do:

# make -f /usr/share/selinux/devel/Makefile
Compliling targeted mock module
/usr/bin/checkmodule:  loading policy configuration from tmp/mock.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 5) to tmp/mock.mod
Creating targeted mock.pp policy package
rm tmp/mock.mod.fc tmp/mock.mod
# semodule -i mock.pp

/!\ The selinux-policy and checkpolicy packages are required

This all seems to work very nicely, provided the module is loaded before mock is installed so that /var/lib/mock gets created as mock_var_lib_t and /usr/bin/mock gets created as mock_exec_t

Otherwise, a restorecon is needed.

{i} This policy would probably work for mach as well, just by adding these lines to mock.fc:

/usr/bin/mach                   --      gen_context(system_u:object_r:mock_exec_t,s0)
/var/lib/mach(/.*)?                     gen_context(system_u:object_r:mock_var_lib_t,s0)


Recent