Hi,

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 /sbin/ldconfig.

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 https://fedoraproject.org/wiki/Changes/PrivateDevicesAndPrivateNetwork

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 like "systemd-run".

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 itself fixes.

Thoughts?
_______________________________________________
Rpm-maint mailing list
Rpm-maint@lists.rpm.org
http://lists.rpm.org/mailman/listinfo/rpm-maint

Reply via email to