formula_installer: conditionally deny network access in sandbox

This commit is contained in:
Caleb Xu 2024-04-13 00:25:00 -04:00
parent aac156ccdf
commit a3cfff72fd
No known key found for this signature in database
GPG Key ID: 47E6040D07B8407D
3 changed files with 41 additions and 2 deletions

View File

@ -925,7 +925,7 @@ on_request: installed_on_request?, options:)
formula.specified_path, formula.specified_path,
].concat(build_argv) ].concat(build_argv)
Utils.safe_fork do Utils.safe_fork do |error_pipe|
if Sandbox.available? if Sandbox.available?
sandbox = Sandbox.new sandbox = Sandbox.new
formula.logs.mkpath formula.logs.mkpath
@ -937,6 +937,7 @@ on_request: installed_on_request?, options:)
sandbox.allow_fossil sandbox.allow_fossil
sandbox.allow_write_xcode sandbox.allow_write_xcode
sandbox.allow_write_cellar(formula) sandbox.allow_write_cellar(formula)
sandbox.deny_all_network_except_pipe(error_pipe) unless formula.network_access_allowed?(:build)
sandbox.exec(*args) sandbox.exec(*args)
else else
exec(*args) exec(*args)
@ -1151,7 +1152,7 @@ on_request: installed_on_request?, options:)
args << post_install_formula_path args << post_install_formula_path
Utils.safe_fork do Utils.safe_fork do |error_pipe|
if Sandbox.available? if Sandbox.available?
sandbox = Sandbox.new sandbox = Sandbox.new
formula.logs.mkpath formula.logs.mkpath
@ -1161,6 +1162,7 @@ on_request: installed_on_request?, options:)
sandbox.allow_write_xcode sandbox.allow_write_xcode
sandbox.deny_write_homebrew_repository sandbox.deny_write_homebrew_repository
sandbox.allow_write_cellar(formula) sandbox.allow_write_cellar(formula)
sandbox.deny_all_network_except_pipe(error_pipe) unless formula.network_access_allowed?(:postinstall)
Keg::KEG_LINK_DIRECTORIES.each do |dir| Keg::KEG_LINK_DIRECTORIES.each do |dir|
sandbox.allow_write_path "#{HOMEBREW_PREFIX}/#{dir}" sandbox.allow_write_path "#{HOMEBREW_PREFIX}/#{dir}"
end end

View File

@ -3,11 +3,13 @@
require "formula" require "formula"
require "formula_installer" require "formula_installer"
require "keg" require "keg"
require "sandbox"
require "tab" require "tab"
require "cmd/install" require "cmd/install"
require "test/support/fixtures/testball" require "test/support/fixtures/testball"
require "test/support/fixtures/testball_bottle" require "test/support/fixtures/testball_bottle"
require "test/support/fixtures/failball" require "test/support/fixtures/failball"
require "test/support/fixtures/failball_offline_install"
RSpec.describe FormulaInstaller do RSpec.describe FormulaInstaller do
matcher :be_poured_from_bottle do matcher :be_poured_from_bottle do
@ -70,6 +72,10 @@ RSpec.describe FormulaInstaller do
end end
end end
specify "offline installation" do
expect { temporary_install(FailballOfflineInstall.new) }.to raise_error(BuildError) if Sandbox.available?
end
specify "Formula is not poured from bottle when compiler specified" do specify "Formula is not poured from bottle when compiler specified" do
temporary_install(TestballBottle.new, cc: "clang") do |f| temporary_install(TestballBottle.new, cc: "clang") do |f|
tab = Tab.for_formula(f) tab = Tab.for_formula(f)

View File

@ -0,0 +1,31 @@
# typed: true
# frozen_string_literal: true
class FailballOfflineInstall < Formula
def initialize(name = "failball_offline_install", path = Pathname.new(__FILE__).expand_path, spec = :stable,
alias_path: nil, tap: nil, force_bottle: false)
super
end
DSL_PROC = proc do
url "file://#{TEST_FIXTURE_DIR}/tarballs/testball-0.1.tbz"
sha256 TESTBALL_SHA256
deny_network_access! :build
end.freeze
private_constant :DSL_PROC
DSL_PROC.call
def self.inherited(other)
super
other.instance_eval(&DSL_PROC)
end
def install
system "curl", "example.org"
prefix.install "bin"
prefix.install "libexec"
Dir.chdir "doc"
end
end