sandbox: redesign API

This commit is contained in:
Xu Cheng 2015-04-13 18:05:15 +08:00
parent 06f72ab38f
commit a6be0b5bb8
3 changed files with 48 additions and 21 deletions

View File

@ -474,7 +474,10 @@ class FormulaInstaller
Utils.safe_fork do Utils.safe_fork do
if Sandbox.available? && ARGV.sandbox? if Sandbox.available? && ARGV.sandbox?
sandbox = Sandbox.new(formula) sandbox = Sandbox.new
sandbox.allow_write_temp_and_cache
sandbox.allow_write_log(formula)
sandbox.allow_write_cellar(formula)
sandbox.exec(*args) sandbox.exec(*args)
else else
exec(*args) exec(*args)

View File

@ -8,29 +8,45 @@ class Sandbox
OS.mac? && File.executable?(SANDBOX_EXEC) OS.mac? && File.executable?(SANDBOX_EXEC)
end end
def initialize(formula=nil) def initialize
@profile = SandboxProfile.new @profile = SandboxProfile.new
unless formula.nil?
allow_write "/private/tmp", :type => :subpath
allow_write "/private/var/folders", :type => :subpath
allow_write HOMEBREW_TEMP, :type => :subpath
allow_write HOMEBREW_LOGS/formula.name, :type => :subpath
allow_write HOMEBREW_CACHE, :type => :subpath
allow_write formula.rack, :type => :subpath
allow_write formula.etc, :type => :subpath
allow_write formula.var, :type => :subpath
end end
def add_rule(rule)
@profile.add_rule(rule)
end end
def allow_write(path, options={}) def allow_write(path, options={})
case options[:type] add_rule :allow => true, :operation => "file-write*", :filter => path_filter(path, options[:type])
when :regex then filter = "regex \#\"#{path}\""
when :subpath then filter = "subpath \"#{expand_realpath(Pathname.new(path))}\""
when :literal, nil then filter = "literal \"#{expand_realpath(Pathname.new(path))}\""
end end
@profile.add_rule :allow => true,
:operation => "file-write*", def deny_write(path, options={})
:filter => filter add_rule :allow => false, :operation => "file-write*", :filter => path_filter(path, options[:type])
end
def allow_write_path(path)
allow_write path, :type => :subpath
end
def deny_write_path(path)
deny_write path, :type => :subpath
end
def allow_write_temp_and_cache
allow_write_path "/private/tmp"
allow_write "^/private/var/folders/[^/]+/[^/]+/[C,T]/", :type => :regex
allow_write_path HOMEBREW_TEMP
allow_write_path HOMEBREW_CACHE
end
def allow_write_cellar(formula)
allow_write_path formula.rack
allow_write_path formula.etc
allow_write_path formula.var
end
def allow_write_log(formula)
allow_write_path HOMEBREW_LOGS/formula.name
end end
def exec(*args) def exec(*args)
@ -57,6 +73,14 @@ class Sandbox
path.exist? ? path.realpath : expand_realpath(path.parent)/path.basename path.exist? ? path.realpath : expand_realpath(path.parent)/path.basename
end end
def path_filter(path, type)
case type
when :regex then "regex \#\"#{path}\""
when :subpath then "subpath \"#{expand_realpath(Pathname.new(path))}\""
when :literal, nil then "literal \"#{expand_realpath(Pathname.new(path))}\""
end
end
class SandboxProfile class SandboxProfile
SEATBELT_ERB = <<-EOS.undent SEATBELT_ERB = <<-EOS.undent
(version 1) (version 1)

View File

@ -10,7 +10,7 @@ class SandboxTest < Homebrew::TestCase
s = Sandbox.new s = Sandbox.new
testpath = Pathname.new(TEST_TMPDIR) testpath = Pathname.new(TEST_TMPDIR)
foo = testpath/"foo" foo = testpath/"foo"
s.allow_write "#{testpath}", :type => :subpath s.allow_write foo
s.exec "touch", foo s.exec "touch", foo
assert_predicate foo, :exist? assert_predicate foo, :exist?
foo.unlink foo.unlink