[Rpm-maint] [RFC PATCH] install selinux policies from package header

Mark Hatle mark.hatle at windriver.com
Tue Jul 7 13:18:53 UTC 2009

I believe that calling out is the better solution, at least for me.  I need to 
be able to install software into chroots and other "non-host" environments for 
other machines to run.

If we call out, then I can intercept that and perform setup actions [or ignore 
actions] based on my configuration.

Direct API calls also limit it to the running system environment.

As for the "initial install" situation, I don't believe SE Linux should be 
configured during an initial install.  This would be setting up contexts and 
such for the installer's kernel and not the end resulting filesystem.  A flag or 
something to disable this type of setup for the initial install might be 
necessary.  [or the script/program run could be passed the install root and know 
what to do, or not to do in a new system install context.  Just has to run 
outside of the chroot...]


Panu Matilainen wrote:
> Hi,
> On Mon, 6 Jul 2009, Stephen Lawrence wrote:
>> RPM currently has support for security policies to be stored in an rpm
>> header but it doesn't currently do anything with the policies. We'd like
>> to get some feedback on a prototype implementation that adds support for
>> using those policies in an SELinux environment.
> First of all thanks for looking into this!
>> First, a bit of background. SELinux policy is currently installed
>> through %post scripts. This presents several problems. First, this means
>> that policy for a given application may not be loaded at the time the
>> files are written to disk, preventing those files from being labeled
>> properly, because the symbols used to label files need to be in the
>> policy loaded into the kernel. Secondly, this means that if multiple
>> packages install policy, each of their %post scripts will reload the
>> policy, which is a very expensive operation. Consequently, policy is
>> generally kept in a single package to avoid this, despite containing
>> many application specific policy modules that would be more suited to be
>> included in their application package.
>> So, what we would like to do is to start including SELinux policy as
>> part of the rpm and have rpm install all policies together before files
>> start to hit the disk. To do this, we would like to use the already
>> supported %policy directive, which stores the policy in the archive
>> header.
>> We would then install the policy before pretrans. This policy load would
>> involve gathering all the policies to be installed from all packages,
>> writing them to a temporary location, and calling out to semodule to
>> install the SELinux policy modules.
>> Obviously I'm glossing over many implementation details that would need
>> to be worked out. The point of this email is strictly to get feedback on
>> our approach. Below is a patch that implements the beginnings of what I
>> describe above. Any and all feedback is appreciated.
> Loading the policies at pre-trans stage is how it needs to be done, but 
> calling out to semodule is a no-go. It'd work for upgrades more or less, 
> but on initial installation (to an empty chroot) the pre-trans stage 
> happens in a complete void, there's just nothing there, not even /bin/sh.
> It needs to be done through API calls, no way around it. On the surface 
> it doesn't look that bad, skipping over details like error handling, 
> rpmtsLoadPolicy() might be something like:
> static int rpmtsLoadPolicies(rpmts ts)
> {
>     int rc;
>     rpmte p;
>     semanage_handle_t *sh = NULL;
>     rpmtsi pi = rpmtsiInit(ts);
>     while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
>         /* If no pre/post-transaction script, then don't bother. */
>         if (!rpmteHavePolicies(p, stag))
>             continue;
>         /* only set up semanage transaction if we have policies */
>         if (sh == NULL) {
>             sh = semanage_handle_create();
>             semanage_connect(sh);
>             semanage_begin_transaction(sh);
>         }
>         if (rpmteOpen(p, ts, 0)) {
>             /* ... fish the policies from te header, b64decode ... */
>             semanage_module_install(sh, ...);
>             rpmteClose(p, ts, 0);
>         }
>     }
>     if (sh) {
>         semanage_commit(sh);
>         semanage_disconnect(sh);
>         semanage_handle_destroy(sh);
>     }
>     pi = rpmtsiFree(pi);
>     return rc;
> }
> ...but I've a feeling there's more than one devil in the details. The 
> "base" policy seems to be a bit special as it even has a separate loader 
> function, which I suppose would have to be loaded first if one is 
> present, but how would rpm know what's a base policy and what's not? Are 
> there other order dependencies in the modules? I guess not but dunno.
> Another open question is upgrade/remove semantics. Maybe it's sufficient 
> just to semanage_module_install() on install+upgrade, and 
> semanage_module_remove() on non-upgrade removal (direct erase or 
> obsoletion), all in the pre-trans stage. I'm just wondering could there 
> be cases where successful removal requires the package's policy to be 
> loaded? If so, the module removals would either have to be done at the 
> middle of transaction individually per package (costly) or do them all 
> at post-trans stage, which would seem more symmetric in a sense. And 
> actually quite similar to how %pre- and %posttrans happen, might even be 
> possible/reasonable to lump their processing to a single function (the 
> actual "do stuff" part obviously differs but the transaction set 
> iteration and header loading is the same)
> And of course it must be possible to disable this functionality. Might 
> be sufficient to just hang it on RPMTRANS_FLAG_NOCONTEXTS, or can you 
> think of a case where one would want to load policies without actually 
> touching the contexts (or the other way around)?
>     - Panu -
> _______________________________________________
> Rpm-maint mailing list
> Rpm-maint at lists.rpm.org
> http://lists.rpm.org/mailman/listinfo/rpm-maint

More information about the Rpm-maint mailing list