MacPorts and sandboxing [was Re: Current state of trace mode?]

Jordan K. Hubbard jkh at apple.com
Tue Sep 11 22:13:34 PDT 2012


[ Re-subjecting to better reflect the new and current topic of conversation ]

> See, I thought that should be the case, but last time I went looking
> (around the time Lion was released I believe) I couldn't find sufficient
> docs to try anything. The man page for sandbox-exec is fine as far as it
> goes, but where can I read about SBPL and these sandbox SPI calls in detail?

Apple has deliberately avoided documenting all of that since SBPL and its associated SPI was originally conceived as a rapidly evolving implementation detail and still is, but there's also a growing amount of SBPL out there now and it's had at least 3 releases to mature, so as much as I generally try not to advocate leaning on SPI of any sort, it's probably not all that unsafe to do so.  This is also an area where 3rd parties have stepped in to fill the void, to wit:

http://www.semantiscope.com/research/BHDC2011/BHDC2011-Paper.pdf			(as presented at Black Hat)
http://reverse.put.as/wp-content/uploads/2011/09/Apple-Sandbox-Guide-v1.0.pdf	(references the above and is somewhat easier reading)

There are also so many "naked examples" in /usr/share/sandbox and /System/Library/Sandbox/Profiles that you can practically learn everything you need to know to sandbox a MacPort simply by scanning what has been done to sandbox certain daemons and services.

I would also be willing to jump in here and there to offer advice, though I have to be careful not to cross the line and actively aid in the usage of Apple SPI since that might be misconstrued as some sort of official endorsement. :-)

> I don't think it would be terribly difficult to construct a file
> dynamically from registry information. What I don't know is how well it
> will perform, given that there are a *lot* of files covered by some
> dependency lists, and they will be listed individually.

There are some fairly large profiles already in use, and where the individual files are all children of a directory also owned by the port, it will obviously be possible to apply some optimization to this where permission to the directory is granted.  Finally, SBPL allows the liberal use of regexps, so if all of the files have some common property (they all end in .foo for example) then that's an easy pattern to write that will cover all entries.  I think the performance concerns are entirely tractable, in other words.

>> All of which can be done by sandboxing, including the reporting part "(debug deny)".   It would be trivial to prototype this with sandbox-exec in any case, since all the mechanism is already there and it's easy to sandbox-exec a shell for interactive testing of the sandbox parameters.   You would probably need to do a substitution pass over a boilerplate sandbox profile file to expand things like ${workpath} and ${distpath} for that specific port before doing the sandbox-exec on it, but again, that's trivial to do.

Actually, turns out I'm wrong about that anyway - I looked a bit closer and saw that sandbox-exec has a way of passing in named variables (-D key=value) which are available to the SBPL program as named parameters ((param "key-name")) so no pre-processing of the script should be necessary.

> Running a separate process per open portfile is probably OK. Starting up
> and initialising a new process and interpreter for each phase, much less so.

Well, I tried sweeping all of the execution code in the command procedure and all the various other calls to system(3) into a single "choke point" call for invoking commands, just for an experiment, and just judging by the log output I saw, it still missed quite a few invocations.  It's actually a shame that we, as some of the original architects of MacPorts, didn't think about security this comprehensively to begin with and make there be only *one* way of executing sub-processes and/or modifying files (vs having all of the various file munging primitives, some of which I wrote while thinking I was being clever) because this now makes sandboxing a bit harder.  It's not impossible, but it does mean that if the port(1) process itself is not sandboxed then you have to guard against all the file operations done directly in Tcl / C as well as the file operations done by the sub-processes like make and curl.  It might be easier to either just do the sub-process per phase approach and take the performance hit or figure out how to sandbox all the phases more or less equally (sandbox profiles can have conditional expressions, being Scheme, so this doesn't mean you have to have a wide sandbox for every action taken).

> Can the rules be modified by a different process?

No, not once the rules have been applied.

> Perhaps in a similar way to how apps gain access to files chosen with open/save dialogs?

Well, that's done by a helper with entirely different privileges.  Which is not to say you can't have macports broken into helpers with different privs on a per-helper basis, but that would be conceptually no different than having port(1) be unsandboxed and each phase being a sandboxed subprocess.

> If we can't modify access during different phases, we'd have to just allow
> everything that might be needed during any phase. Given that the
> activate phase needs to be able to write new files to just about
> anywhere, that's problematic.

Well, like I said, maybe you can have the "generic sandbox" only switch parts of itself on based on the parameters passed.  See /System/Library/Profiles/application.sb for a really complex sandbox that alters its behavior based on the entitlements the calling process has, for example.

> Sandboxing only the child processes helps, but not as much as we'd
> really like, since many ports do a portion of their work with Tcl calls.

Right.  I think I said the same thing in different words (probably should have responded to this part first :-).

Still, even with security being applied in hindsight, I think there's enough fundamental goodness in the architecture of macports (we were idiots, but we weren't TOTAL idiots in other words ;-) ) and flexibility in the sandbox mechanism that the impedance matching probably won't be as hard as I'm perhaps making it sound!

- Jordan



More information about the macports-dev mailing list