[Rpm-maint] whitelisting/wrapping script execution
walters at verbum.org
Wed Apr 23 13:13:10 UTC 2014
For the rpm-ostree project, I need the ability to whitelist scriptlets.
There are a few reasons for this, but the most critical is that due to
the way OSTree uses hardlinks, and because I can't assume I have
copy-on-write links, I need to know that scriptlets will cleanly break
hardlinks instead of edit-in-place.
For example, suppose I'm layering a package on top of a base tree that
contains a shared library. We need to update /etc/ld.so.cache. In the
traditional RPM model, that package will contain a scriptlet to run
I happen to know that /sbin/ldconfig is safe - it creates
/etc/ld.so.cache~ and rename()s into place, so I can just run it. But
if the package happens to do something I haven't whitelisted as safe, I
need to error out and refuse to install it.
(Note an important side benefit here of moving away from the "whatever
arbitrary code you want that runs as root" aspect of scripts)
Now related to this, I'd like to have rpm-ostree take care of executing
any subprocesses (and even Lua code potentially). The reason for this
is because *every* rpm-ostree install will be in a chroot. In the
OSTree model, you running system is immutable - so to "upgrade" a
package, we make a hardlink farm of the current tree, and re-unpack the
new version of of a package on top, then set it up for the next boot.
If you look at software like mock, it does a complex dance to set up
things like /proc in the target root and then run yum --installroot.
But if we were in control over all subprocesses launched, we could use
systemd to put each scriptlet inside a container, with its own private
/proc and such, inside its own mount namespace. There are a huge
number of advantages to this - systemd is very good at isolation,
logging, etc. For example, we could cut off scriptlets from access to
physical devices using
So, a few ways to accomplish this:
1) Add rpmtsSetScriptCallback() - This would allow me to set a callback
which would be used instead of the fork()/exec() bits in rpmScriptRun.
I could analyze the script content, and exec it myself using something
2) Have rpm-ostree extract the scripts manually *before* the
transaction, analyze them, unpack all of the rpms, then run all of the
scripts as if they were %posttrans anyways
I need to do a bit more evaluation, but the more I think about it the
more I like #2 as it maximizes control. If we go that route though
there's a detail - Lua-based scripts. In order to implement these it's
a bit harder as I'd need to exec a new RPM process inside the root and
run the script inside that process. Maybe I could get away with just
ignoring Lua scripts, I suspect many of them are there to work around
things like "can't replace directory with symlink" problem that OSTree
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Rpm-maint