--- prefix-portage-2.2.01.21688/cnf/make.globals.orig 2013-01-10 22:22:09.000000000 +0100 +++ prefix-portage-2.2.01.21688/cnf/make.globals 2013-03-19 18:50:01.000000000 +0100 @@ -149,6 +149,20 @@ # Signing command used by repoman PORTAGE_GPG_SIGNING_COMMAND="gpg --sign --digest-algo SHA256 --clearsign --yes --default-key \"\${PORTAGE_GPG_KEY}\" --homedir \"\${PORTAGE_GPG_DIR}\" \"\${FILE}\"" +# Writeable paths for Mac OS X seatbelt sandbox +# +# If path ends in a slash (/), access will recursively be allowed to directory +# contents (using a regex), not the directory itself. Without a slash, access +# to the directory or file itself will be allowed (using a literal), so it can +# be created, removed and changed. If both is needed, the directory needs to be +# given twice, once with and once without the slash. Obviously this only makes +# sense for directories, not files. +# +# An empty value for either variable will disable all restrictions on the +# corresponding operation. +MACOSSANDBOX_PATHS="/dev/fd/ /private/tmp/ /private/var/tmp/ @@PORTAGE_BUILDDIR@@/ @@PORTAGE_ACTUAL_DISTDIR@@/" +MACOSSANDBOX_PATHS_CONTENT_ONLY="/dev/null /dev/dtracehelper /dev/tty /private/var/run/syslog" + # ***************************** # ** DO NOT EDIT THIS FILE ** # *************************************************** --- prefix-portage-2.2.01.21688/pym/portage/const.py.orig 2013-01-27 22:52:12.000000000 +0100 +++ prefix-portage-2.2.01.21688/pym/portage/const.py 2013-03-19 18:22:02.000000000 +0100 @@ -78,31 +78,12 @@ PRELINK_BINARY = "/usr/sbin/prelink" MACOSSANDBOX_BINARY = "/usr/bin/sandbox-exec" MACOSSANDBOX_PROFILE = '''(version 1) - (allow default) - (deny file-write*) - -(allow file-read* file-write* - (literal - #"@@WRITEABLE_PREFIX@@" - #"/dev/tty" - #"/dev/dtracehelper" - ) - - (regex - #"^@@WRITEABLE_PREFIX_RE@@/" - #"^(/private)?/var/tmp" - #"^(/private)?/tmp" - ) -) - -(allow file-read-data file-write-data - (regex - #"^/dev/null$" - #"^(/private)?/var/run/syslog$" - ) -)''' +(allow file-write* +@@MACOSSANDBOX_PATHS@@) +(allow file-write-data +@@MACOSSANDBOX_PATHS_CONTENT_ONLY@@)''' PORTAGE_GROUPNAME = portagegroup PORTAGE_USERNAME = portageuser --- prefix-portage-2.2.01.21688/pym/portage/package/ebuild/doebuild.py.orig 2013-01-27 22:45:00.000000000 +0100 +++ prefix-portage-2.2.01.21688/pym/portage/package/ebuild/doebuild.py 2013-03-19 18:45:40.000000000 +0100 @@ -1477,17 +1477,67 @@ spawn_func = portage.process.spawn_fakeroot elif "sandbox" in features and platform.system() == 'Darwin': keywords["opt_name"] += " macossandbox" - sbprefixpath = mysettings["PORTAGE_BUILDDIR"] + sbprofile = MACOSSANDBOX_PROFILE - # escape some characters with special meaning in re's - sbprefixre = sbprefixpath.replace("+", "\+") - sbprefixre = sbprefixre.replace("*", "\*") - sbprefixre = sbprefixre.replace("[", "\[") - sbprefixre = sbprefixre.replace("[", "\[") + # determine variable names from profile: split + # "text@@VARNAME@@moretext@@OTHERVAR@@restoftext" into + # ("text", # "VARNAME", "moretext", "OTHERVAR", "restoftext") + # and extract variable named by reading every second item. + variables = [] + for line in sbprofile.split("\n"): + variables.extend(line.split("@@")[1:-1:2]) + + for var in variables: + paths = "" + if var in mysettings: + paths = mysettings[var] + else: + writemsg("Warning: sandbox profile references variable %s " + "which is not set.\nThe rule using it will have no " + "effect, which is most likely not the intended " + "result.\nPlease check make.conf/make.globals.\n" % + var) + + # not set or empty value + if not paths: + sbprofile = sbprofile.replace("@@%s@@" % var, "") + continue - sbprofile = MACOSSANDBOX_PROFILE - sbprofile = sbprofile.replace("@@WRITEABLE_PREFIX@@", sbprefixpath) - sbprofile = sbprofile.replace("@@WRITEABLE_PREFIX_RE@@", sbprefixre) + rules_literal = "" + rules_regex = "" + + # FIXME: Allow for quoting inside the variable to allow paths with + # spaces in them? + for path in paths.split(" "): + # do a second round of token replacements to be able to + # reference settings like EPREFIX or PORTAGE_BUILDDIR. + for token in path.split("@@")[1:-1:2]: + if token not in mysettings: + continue + + path = path.replace("@@%s@@" % token, mysettings[token]) + + if "@@" in path: + # unreplaced tokens left - silently ignore path - needed + # for PORTAGE_ACTUAL_DISTDIR which isn't always set + pass + elif path[-1] == os.sep: + # path ends in slash - make it a regex and allow access + # recursively. + path = path.replace("+", "\+") + path = path.replace("*", "\*") + path = path.replace("[", "\[") + path = path.replace("[", "\[") + rules_regex += " #\"^%s\"\n" % path + else: + rules_literal += " #\"%s\"\n" % path + + rules = "" + if rules_literal: + rules += " (literal\n" + rules_literal + " )\n" + if rules_regex: + rules += " (regex\n" + rules_regex + " )\n" + sbprofile = sbprofile.replace("@@%s@@" % var, rules) keywords["profile"] = sbprofile spawn_func = portage.process.spawn_macossandbox