Merge pull request #17782 from Homebrew/system_command-uid
Fix UID handling with cask `installer script:`
This commit is contained in:
commit
f84b8ebf69
@ -35,9 +35,10 @@ module Cask
|
|||||||
command.run!(
|
command.run!(
|
||||||
executable_path,
|
executable_path,
|
||||||
**args,
|
**args,
|
||||||
env: { "PATH" => PATH.new(
|
env: { "PATH" => PATH.new(
|
||||||
HOMEBREW_PREFIX/"bin", HOMEBREW_PREFIX/"sbin", ENV.fetch("PATH")
|
HOMEBREW_PREFIX/"bin", HOMEBREW_PREFIX/"sbin", ENV.fetch("PATH")
|
||||||
) },
|
) },
|
||||||
|
reset_uid: true,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -279,6 +279,9 @@ class SystemCommand
|
|||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def must_succeed?; end
|
def must_succeed?; end
|
||||||
|
|
||||||
|
sig { returns(T::Boolean) }
|
||||||
|
def reset_uid?; end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Utils
|
module Utils
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "attrable"
|
require "attrable"
|
||||||
require "open3"
|
|
||||||
require "plist"
|
require "plist"
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
require "uri"
|
require "uri"
|
||||||
@ -92,6 +91,7 @@ class SystemCommand
|
|||||||
verbose: T.nilable(T::Boolean),
|
verbose: T.nilable(T::Boolean),
|
||||||
secrets: T.any(String, T::Array[String]),
|
secrets: T.any(String, T::Array[String]),
|
||||||
chdir: T.any(String, Pathname),
|
chdir: T.any(String, Pathname),
|
||||||
|
reset_uid: T::Boolean,
|
||||||
timeout: T.nilable(T.any(Integer, Float)),
|
timeout: T.nilable(T.any(Integer, Float)),
|
||||||
).void
|
).void
|
||||||
}
|
}
|
||||||
@ -109,6 +109,7 @@ class SystemCommand
|
|||||||
verbose: false,
|
verbose: false,
|
||||||
secrets: [],
|
secrets: [],
|
||||||
chdir: T.unsafe(nil),
|
chdir: T.unsafe(nil),
|
||||||
|
reset_uid: false,
|
||||||
timeout: nil
|
timeout: nil
|
||||||
)
|
)
|
||||||
require "extend/ENV"
|
require "extend/ENV"
|
||||||
@ -140,6 +141,7 @@ class SystemCommand
|
|||||||
@verbose = verbose
|
@verbose = verbose
|
||||||
@secrets = (Array(secrets) + ENV.sensitive_environment.values).uniq
|
@secrets = (Array(secrets) + ENV.sensitive_environment.values).uniq
|
||||||
@chdir = chdir
|
@chdir = chdir
|
||||||
|
@reset_uid = reset_uid
|
||||||
@timeout = timeout
|
@timeout = timeout
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -152,7 +154,7 @@ class SystemCommand
|
|||||||
|
|
||||||
attr_reader :executable, :args, :input, :chdir, :env
|
attr_reader :executable, :args, :input, :chdir, :env
|
||||||
|
|
||||||
attr_predicate :sudo?, :sudo_as_root?, :must_succeed?
|
attr_predicate :sudo?, :sudo_as_root?, :must_succeed?, :reset_uid?
|
||||||
|
|
||||||
sig { returns(T::Boolean) }
|
sig { returns(T::Boolean) }
|
||||||
def debug?
|
def debug?
|
||||||
@ -238,12 +240,7 @@ class SystemCommand
|
|||||||
}
|
}
|
||||||
options[:chdir] = chdir if chdir
|
options[:chdir] = chdir if chdir
|
||||||
|
|
||||||
raw_stdin, raw_stdout, raw_stderr, raw_wait_thr = Open3.popen3(
|
raw_stdin, raw_stdout, raw_stderr, raw_wait_thr = exec3(env, executable, *args, **options)
|
||||||
env.merge({ "COLUMNS" => Tty.width.to_s }),
|
|
||||||
[executable, executable],
|
|
||||||
*args,
|
|
||||||
**options,
|
|
||||||
)
|
|
||||||
|
|
||||||
write_input_to(raw_stdin)
|
write_input_to(raw_stdin)
|
||||||
raw_stdin.close_write
|
raw_stdin.close_write
|
||||||
@ -276,9 +273,56 @@ class SystemCommand
|
|||||||
rescue Interrupt
|
rescue Interrupt
|
||||||
Process.kill("INT", raw_wait_thr.pid) if raw_wait_thr && !sudo?
|
Process.kill("INT", raw_wait_thr.pid) if raw_wait_thr && !sudo?
|
||||||
raise Interrupt
|
raise Interrupt
|
||||||
rescue SystemCallError => e
|
ensure
|
||||||
@status = $CHILD_STATUS
|
raw_stdin&.close
|
||||||
@output << [:stderr, e.message]
|
raw_stdout&.close
|
||||||
|
raw_stderr&.close
|
||||||
|
end
|
||||||
|
|
||||||
|
sig {
|
||||||
|
params(
|
||||||
|
env: T::Hash[String, String],
|
||||||
|
executable: String,
|
||||||
|
args: String,
|
||||||
|
options: T.untyped,
|
||||||
|
).returns([IO, IO, IO, Thread])
|
||||||
|
}
|
||||||
|
def exec3(env, executable, *args, **options)
|
||||||
|
in_r, in_w = IO.pipe
|
||||||
|
options[:in] = in_r
|
||||||
|
in_w.sync = true
|
||||||
|
|
||||||
|
out_r, out_w = IO.pipe
|
||||||
|
options[:out] = out_w
|
||||||
|
|
||||||
|
err_r, err_w = IO.pipe
|
||||||
|
options[:err] = err_w
|
||||||
|
|
||||||
|
pid = fork do
|
||||||
|
Process::UID.change_privilege(Process.euid) if reset_uid? && Process.euid != Process.uid
|
||||||
|
|
||||||
|
exec(
|
||||||
|
env.merge({ "COLUMNS" => Tty.width.to_s }),
|
||||||
|
[executable, executable],
|
||||||
|
*args,
|
||||||
|
**options,
|
||||||
|
)
|
||||||
|
rescue SystemCallError => e
|
||||||
|
$stderr.puts(e.message)
|
||||||
|
exit!(127)
|
||||||
|
end
|
||||||
|
wait_thr = Process.detach(pid)
|
||||||
|
|
||||||
|
[in_w, out_r, err_r, wait_thr]
|
||||||
|
rescue
|
||||||
|
in_w&.close
|
||||||
|
out_r&.close
|
||||||
|
err_r&.close
|
||||||
|
raise
|
||||||
|
ensure
|
||||||
|
in_r&.close
|
||||||
|
out_w&.close
|
||||||
|
err_w&.close
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(raw_stdin: IO).void }
|
sig { params(raw_stdin: IO).void }
|
||||||
|
|||||||
@ -25,10 +25,10 @@ RSpec.describe SystemCommand do
|
|||||||
|
|
||||||
describe "the resulting command line" do
|
describe "the resulting command line" do
|
||||||
it "includes the given variables explicitly" do
|
it "includes the given variables explicitly" do
|
||||||
expect(Open3)
|
expect(command)
|
||||||
.to receive(:popen3)
|
.to receive(:exec3)
|
||||||
.with(
|
.with(
|
||||||
an_instance_of(Hash), ["/usr/bin/env", "/usr/bin/env"], "A=1", "B=2", "C=3",
|
an_instance_of(Hash), "/usr/bin/env", "A=1", "B=2", "C=3",
|
||||||
"env", *env_args,
|
"env", *env_args,
|
||||||
pgroup: true
|
pgroup: true
|
||||||
)
|
)
|
||||||
@ -55,14 +55,14 @@ RSpec.describe SystemCommand do
|
|||||||
|
|
||||||
describe "the resulting command line" do
|
describe "the resulting command line" do
|
||||||
it "includes the given variables explicitly" do
|
it "includes the given variables explicitly" do
|
||||||
expect(Open3)
|
expect(command)
|
||||||
.to receive(:popen3)
|
.to receive(:exec3)
|
||||||
.with(
|
.with(
|
||||||
an_instance_of(Hash), ["/usr/bin/sudo", "/usr/bin/sudo"], "-E",
|
an_instance_of(Hash), "/usr/bin/sudo", "-E",
|
||||||
"A=1", "B=2", "C=3", "--", "env", *env_args, pgroup: nil
|
"A=1", "B=2", "C=3", "--", "env", *env_args, pgroup: nil
|
||||||
)
|
)
|
||||||
.and_wrap_original do |original_popen3, *_, &block|
|
.and_wrap_original do |original_exec3, *_, &block|
|
||||||
original_popen3.call("true", &block)
|
original_exec3.call({}, "true", &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
command.run!
|
command.run!
|
||||||
@ -76,14 +76,14 @@ RSpec.describe SystemCommand do
|
|||||||
|
|
||||||
describe "the resulting command line" do
|
describe "the resulting command line" do
|
||||||
it "includes the given variables explicitly" do
|
it "includes the given variables explicitly" do
|
||||||
expect(Open3)
|
expect(command)
|
||||||
.to receive(:popen3)
|
.to receive(:exec3)
|
||||||
.with(
|
.with(
|
||||||
an_instance_of(Hash), ["/usr/bin/sudo", "/usr/bin/sudo"], "-u", "root",
|
an_instance_of(Hash), "/usr/bin/sudo", "-u", "root",
|
||||||
"-E", "A=1", "B=2", "C=3", "--", "env", *env_args, pgroup: nil
|
"-E", "A=1", "B=2", "C=3", "--", "env", *env_args, pgroup: nil
|
||||||
)
|
)
|
||||||
.and_wrap_original do |original_popen3, *_, &block|
|
.and_wrap_original do |original_exec3, *_, &block|
|
||||||
original_popen3.call("true", &block)
|
original_exec3.call({}, "true", &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
command.run!
|
command.run!
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user