From 563387a7b42ce16d6280be469a08fe7f0b87bfe1 Mon Sep 17 00:00:00 2001 From: Ilya Kulakov Date: Tue, 14 Feb 2023 13:24:36 -0800 Subject: [PATCH] sudo: explicitly specify the root user where necessary With sudoers one may override default sudo user. This mostly works provided the admin configured the replacement appropriately. However there are exceptions that absolutely must be run by root such as /usr/sbin/installer and, under certain circumstances, /bin/launchctl. --- .../cask/artifact/abstract_uninstall.rb | 20 ++++++++++--------- Library/Homebrew/cask/artifact/pkg.rb | 2 +- Library/Homebrew/cask/pkg.rb | 8 ++++---- Library/Homebrew/system_command.rb | 12 ++++++++--- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Library/Homebrew/cask/artifact/abstract_uninstall.rb b/Library/Homebrew/cask/artifact/abstract_uninstall.rb index d1c56a303d..6528b5ddc8 100644 --- a/Library/Homebrew/cask/artifact/abstract_uninstall.rb +++ b/Library/Homebrew/cask/artifact/abstract_uninstall.rb @@ -106,13 +106,14 @@ module Cask all_services.each do |service| ohai "Removing launchctl service #{service}" booleans.each do |with_sudo| + sudo_user = with_sudo ? "root" : "" plist_status = command.run( "/bin/launchctl", args: ["list", service], - sudo: with_sudo, print_stderr: false + sudo: sudo_user, print_stderr: false ).stdout if plist_status.start_with?("{") - command.run!("/bin/launchctl", args: ["remove", service], sudo: with_sudo) + command.run!("/bin/launchctl", args: ["remove", service], sudo: sudo_user) sleep 1 end paths = [ @@ -122,13 +123,13 @@ module Cask paths.each { |elt| elt.prepend(Dir.home).freeze } unless with_sudo paths = paths.map { |elt| Pathname(elt) }.select(&:exist?) paths.each do |path| - command.run!("/bin/rm", args: ["-f", "--", path], sudo: with_sudo) + command.run!("/bin/rm", args: ["-f", "--", path], sudo: sudo_user) end # undocumented and untested: pass a path to uninstall :launchctl next unless Pathname(service).exist? - command.run!("/bin/launchctl", args: ["unload", "-w", "--", service], sudo: with_sudo) - command.run!("/bin/rm", args: ["-f", "--", service], sudo: with_sudo) + command.run!("/bin/launchctl", args: ["unload", "-w", "--", service], sudo: sudo_user) + command.run!("/bin/rm", args: ["-f", "--", service], sudo: sudo_user) sleep 1 end end @@ -301,14 +302,15 @@ module Cask def uninstall_kext(*kexts, command: nil, **_) kexts.each do |kext| ohai "Unloading kernel extension #{kext}" - is_loaded = system_command!("/usr/sbin/kextstat", args: ["-l", "-b", kext], sudo: true).stdout + is_loaded = system_command!("/usr/sbin/kextstat", args: ["-l", "-b", kext], sudo: "root").stdout if is_loaded.length > 1 - system_command!("/sbin/kextunload", args: ["-b", kext], sudo: true) + system_command!("/sbin/kextunload", args: ["-b", kext], sudo: "root") sleep 1 end - system_command!("/usr/sbin/kextfind", args: ["-b", kext], sudo: true).stdout.chomp.lines.each do |kext_path| + kexts = system_command!("/usr/sbin/kextfind", args: ["-b", kext], sudo: "root").stdout + kexts.chomp.lines.each do |kext_path| ohai "Removing kernel extension #{kext_path}" - system_command!("/bin/rm", args: ["-rf", kext_path], sudo: true) + system_command!("/bin/rm", args: ["-rf", kext_path], sudo: "root") end end end diff --git a/Library/Homebrew/cask/artifact/pkg.rb b/Library/Homebrew/cask/artifact/pkg.rb index 7a22057909..7002257be8 100644 --- a/Library/Homebrew/cask/artifact/pkg.rb +++ b/Library/Homebrew/cask/artifact/pkg.rb @@ -62,7 +62,7 @@ module Cask "USER" => User.current, "USERNAME" => User.current, } - command.run!("/usr/sbin/installer", sudo: true, args: args, print_stdout: true, env: env) + command.run!("/usr/sbin/installer", sudo: "root", args: args, print_stdout: true, env: env) end end diff --git a/Library/Homebrew/cask/pkg.rb b/Library/Homebrew/cask/pkg.rb index cc3d4d06cb..15258a420f 100644 --- a/Library/Homebrew/cask/pkg.rb +++ b/Library/Homebrew/cask/pkg.rb @@ -32,7 +32,7 @@ module Cask "/usr/bin/xargs", args: ["-0", "--", "/bin/rm", "--"], input: pkgutil_bom_files.join("\0"), - sudo: true, + sudo: "root", ) end @@ -42,7 +42,7 @@ module Cask "/usr/bin/xargs", args: ["-0", "--", "/bin/rm", "--"], input: pkgutil_bom_specials.join("\0"), - sudo: true, + sudo: "root", ) end @@ -59,7 +59,7 @@ module Cask sig { void } def forget odebug "Unregistering pkg receipt (aka forgetting)" - @command.run!("/usr/sbin/pkgutil", args: ["--forget", package_id], sudo: true) + @command.run!("/usr/sbin/pkgutil", args: ["--forget", package_id], sudo: "root") end sig { returns(T::Array[Pathname]) } @@ -114,7 +114,7 @@ module Cask "/usr/bin/xargs", args: ["-0", "--", RMDIR_SH.to_s], input: Array(path).join("\0"), - sudo: true, + sudo: "root", ) end diff --git a/Library/Homebrew/system_command.rb b/Library/Homebrew/system_command.rb index 9e7e98fabe..f9d843561a 100644 --- a/Library/Homebrew/system_command.rb +++ b/Library/Homebrew/system_command.rb @@ -64,7 +64,7 @@ class SystemCommand params( executable: T.any(String, Pathname), args: T::Array[T.any(String, Integer, Float, URI::Generic)], - sudo: T::Boolean, + sudo: T.any(T::Boolean, String), env: T::Hash[String, String], input: T.any(String, T::Array[String]), must_succeed: T::Boolean, @@ -122,7 +122,12 @@ class SystemCommand attr_reader :executable, :args, :input, :chdir, :env - attr_predicate :sudo?, :print_stdout?, :print_stderr?, :must_succeed? + attr_predicate :print_stdout?, :print_stderr?, :must_succeed? + + sig { returns(T::Boolean) } + def sudo? + @sudo != false && @sudo != "" + end sig { returns(T::Boolean) } def debug? @@ -153,8 +158,9 @@ class SystemCommand sig { returns(T::Array[String]) } def sudo_prefix + user_flags = @sudo.is_a?(String) ? ["-u", @sudo] : [] askpass_flags = ENV.key?("SUDO_ASKPASS") ? ["-A"] : [] - ["/usr/bin/sudo", *askpass_flags, "-E", *env_args, "--"] + ["/usr/bin/sudo", *user_flags, *askpass_flags, "-E", *env_args, "--"] end sig { returns(T::Array[String]) }