Checking policy file/data integrity (Was: Re: [redhat-lspp] LSPP Development Telecon 01/16/2006 Minutes)

Stephen Smalley sds at tycho.nsa.gov
Mon Jan 23 15:10:36 UTC 2006


On Fri, 2006-01-20 at 18:45 -0600, George C. Wilson wrote:
> On Fri, Jan 20, 2006 at 03:10:08PM -0500, Stephen Smalley wrote:
> > 
> > What do you want to checksum?  Options include:
> > 1) The individual policy module files provided by RPM packages like (but
> > not limited to) the selinux-policy-* packages.  rpm -V should handle
> > checking of the package files, but they are not used at runtime.  Those
> > files are then installed into the policy module store via semodule(8),
> > which uses libsemanage to install them.
> > 
> > 2) All of the files in the policy module store, including both policy
> > module files and other configuration files (e.g. boolean settings, port
> > contexts, netif contexts) used in the generation of the final kernel
> > binary policy file.  libsemanage provides a way to specify verification
> > programs as part of its semanage.conf configuration that will be run at
> > certain stages of a commit (before linking the modules together, after
> > linking them together, and after generating the final kernel binary
> > policy file), so you could conceivably leverage that support (but note
> > that ultimately we also want to use that support for running checkers on
> > the policy modules and final policy to check specific properties).
> > 
> > 3) The installed binary policy file.  This is the file that is loaded by
> > init and load_policy; it is created by libsemanage by copying the
> > generated file from the module store to a temporary path in the target
> > directory and then renaming it into place upon a commit, so it should
> > always match the generated file in the store.  Thus, you could simply
> > compare it with that generated file.
> > 
> > 4) The binary policy memory image loaded into the kernel.  This is a
> > mmap'd copy of the installed binary policy file, possibly slightly
> > munged by load_policy to preserve any active boolean settings if they
> > differ from the saved settings.  This is what has been discussed in the
> > past.  The SELinux module could certainly measure this at load time and
> > make the checksum available via selinuxfs, but understand that the
> > checksum only corresponds to the load time memory image, nothing else.
> > Thus, any tool that uses this information and tries to compare checksums
> > would need to take that into account.
> > 
> > 5) The dynamic data structures used at runtime by the SELinux module
> > that were populated from the binary policy image at load time.
> > Measuring these structures and mapping them to anything stable and
> > meaningful would not be trivial.
> > 
> > -- 
> > Stephen Smalley
> > National Security Agency
> 
> Ideally, an admin would be able to verify module integrity from build
> time through load time.  Than a periodic check would verify that the
> in-core policy matches the on-disk policy.  This wouldn't be particularly
> straightforward given the policy is composed from modules, and then
> modified in memory.  I think we can meet RBACPP with something simpler.
> A composite of (1), (3), and perhaps (4) are what we can reasonably
> achieve.  Of course, that leaves the policy store out of the chain.
> (2) is interesting for that reason and deserves consideration.  I don't
> know how we would do (5) in a useful way.

(5) is possible (essentially you would reproduce the libsepol
policydb_write processing in the kernel to generate a flat policy image
from the in-memory data structures and then checksum that image), but
expensive and would require adding that code to the kernel.  I doubt it
is justified, given that you are not otherwise checking the runtime
kernel integrity.

(4) wouldn't take into account any transient policy boolean changes
(e.g. setsebool allow_execmem=1 w/o the -P to save it across reboots),
so you might get "false" positives where there is a mismatch because of
such transient changes.  Or you'd have to exclude the booleans from the
checksum computation, and separately compare boolean values via the
already existing selinuxfs boolean nodes.

The only thing you can compare (3) against is the corresponding kernel
policy file in the active module store, and that would just be a flat
comparison, no checksum involved.  To then bind generated kernel policy
file to the original inputs provided by (1), you could compare the
modules in the module store against the rpm-installed files
under /usr/share/selinux, but you wouldn't have similar checks for the
local customizations created via semanage, setsebool or similar tools
using the libsemanage interfaces directly.

You could create utilities run by libsemanage via its [verify module|
linked|kernel] config entries in semanage.conf to apply some kind of
checking and/or generation of checksums when it rebuilds the kernel
policy for some policy change, but it isn't clear exactly what you would
check or how you would store, protect, and securely update any of those
checksums.

-- 
Stephen Smalley
National Security Agency




More information about the redhat-lspp mailing list