Knowledge Base:Inserting base module in module store fails with duplicate declaration

From Gentoo Wiki
Jump to:navigation Jump to:search

Synopsis

When installing the sec-policy/selinux-base-policy package, the postinstall phase fails with the following error:

root #emerge sec-policy/selinux-base-policy
...
>>> Original instance of package unmerged safely.
 * Inserting base module into strict module store.
libsepol.scope_copy_callback: screen: Duplicate declaration in module: type/attribute sysadm_screen_t (No such file or directory).
libsemanage.semanage_link_sandbox: Link packages failed (No such file or directory).
semodule:  Failed!
 * ERROR: sec-policy/selinux-base-policy-2.20110726-r9 failed (postinst phase):
 *   Could not load in new base policy

The package however is installed correctly.

Environment

This article applies to Gentoo Linux installations with a SELinux profile:

root #eselect profile show
Current /etc/make.profile symlink:
  hardened/linux/amd64/selinux

Analysis

The error itself means that the new policy cannot be inserted because an already running, but different, module provides the same type or attribute. For instance, suppose that sysadm_screen_t is declared by the screen.pp SELinux module, then a definition of sysadm_screen_t in the base policy will hold back the installation of this module as long as the screen module is still loaded.

Sadly, there is no method available (yet) to look into modules and see what they offer, which means it is sometimes a trial and error. Luckily, we can extract some information from the modules that helps this trail and error method to be sufficiently fast.

Note
The ebuild itself does not fail (installation-wise) because the loading of modules is done in the postinstall phase as we are modifying entries on the system beyond Portage control. Failures in postinstall phase do not get trapped by Portage as a package failure.

Resolution

First find the culprit module that is also defining the offending type (in the example, this is sysadm_screen_t). One method is to find any occurrence of the string "sysadm_screen_t" in the available modules:

root #cd /etc/selinux/strict/modules/active/modules
root #for MOD in *.pp; do grep -H sysadm_screen_t ${MOD}; done
Binary file screen.pp matches
Binary file fixscreen.pp matches

In the above example, there are two modules that have some reference to sysadm_screen_t; one is the "official" screen module (screen.pp), the second one is a module created by the user to update the policy (here called fixscreen.pp but can be anything). Assuming the latter is the offending module, unload it:

root #semodule -r fixscreen

After this, try to reload the base policy:

root #semodule -b /usr/share/selinux/strict/base.pp

If inserting the base module still fails, unload the other module as well (screen.pp in our example) and retry.

Afterwards, rebuild the offending modules (through sec-policy/selinux-screen so that the updated policy is back in place.