Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sudo timestamp reset may break scripts #17912

Closed
3 tasks done
bhavanki opened this issue Jul 30, 2024 · 6 comments
Closed
3 tasks done

sudo timestamp reset may break scripts #17912

bhavanki opened this issue Jul 30, 2024 · 6 comments
Labels
bug Reproducible Homebrew/brew bug

Comments

@bhavanki
Copy link

brew doctor output

Your system is ready to brew.

Verification

  • My "brew doctor output" above says Your system is ready to brew. and am still able to reproduce my issue.
  • I ran brew update twice and am still able to reproduce my issue.
  • This issue's title and/or description do not reference a single formula e.g. brew install wget. If they do, open an issue at https://github.com/Homebrew/homebrew-core/issues/new/choose instead.

brew config output

HOMEBREW_VERSION: 4.3.12-10-g6e9947d
ORIGIN: https://github.com/Homebrew/brew
HEAD: 6e9947d570e64a840a40c46aa001610574589314
Last commit: 20 minutes ago
Core tap HEAD: faa508ab98e669454be141eee7791b68bd0225ce
Core tap last commit: 6 minutes ago
Core tap JSON: 30 Jul 16:08 UTC
Core cask tap JSON: 30 Jul 16:08 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_EDITOR: vi
HOMEBREW_GITHUB_API_TOKEN: set
HOMEBREW_MAKE_JOBS: 11
HOMEBREW_SORBET_RUNTIME: set
Homebrew Ruby: 3.3.4 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.3.4/bin/ruby
CPU: 11-core 64-bit arm_lobos
Clang: 15.0.0 build 1500
Git: 2.45.2 => /opt/homebrew/bin/git
Curl: 8.6.0 => /usr/bin/curl
macOS: 14.5-arm64
CLT: 15.3.0.0.1.1708646388
Xcode: N/A
Rosetta 2: false

What were you trying to do (and why)?

Run brew commands within a script that has acquired sudo access and expects to keep it throughout execution.

What happened (include all command output)?

After using brew, the script proceeded to run additional commands under sudo, and I was prompted again for a password.

Eventually, the script called Ansible to execute a playbook on the local machine. The first task step that required sudo access failed, because there was no terminal to get a password from.

TASK [geerlingguy.mac.homebrew : Ensure Homebrew parent directory has correct permissions (M1).] ***********************
fatal: [localhost]: FAILED! => changed=false
  module_stderr: |-
    sudo: a password is required
  module_stdout: ''
  msg: |-
    MODULE FAILURE
    See stdout/stderr for the exact error
  rc: 1

Even after ensuring that Ansible was called with sudo, that access was lost after a step in the playbook called brew to install a missing formula. The next step that required sudo failed in the same fashion.

What did you expect to happen?

For the script to execute to completion, with sudo access available for all script commands (and Ansible steps) following execution of brew.

Step-by-step reproduction instructions (by running brew commands)

# Reproducing the Ansible issue is tricky in this medium. To reproduce the problem just on the scripting side, run these commands in a script or at the command line.

sudo date; brew --prefix; sudo date
@bhavanki bhavanki added the bug Reproducible Homebrew/brew bug label Jul 30, 2024
@bhavanki
Copy link
Author

This recent PR introduced the new behavior. #17694

@MikeMcQuaid
Copy link
Member

Duplicate of #17905, WONTFIX sorry.

@MikeMcQuaid MikeMcQuaid closed this as not planned Won't fix, can't repro, duplicate, stale Jul 30, 2024
@bhavanki
Copy link
Author

I understand the reason for the change. However, IMO this new behavior is an overreach.

  • The problem is in formula privilege escalation, but the removal of sudo occurs for any execution of brew. The scope of the fix is too broad. (Reducing the scope wouldn't fully fix this problem, to be fair.)
  • An executable should not alter its calling environment as a side effect. brew should restore sudo access for ensuing processes, even if it blocks it for itself.

@MikeMcQuaid
Copy link
Member

  • brew should restore sudo access for ensuing processes, even if it blocks it for itself.

@bhavanki If you can provide details (ideally a pull request) for how this is technically possible: we'd love that. We haven't been able to figure out how to do this yet.

  • The problem is in formula privilege escalation, but the removal of sudo occurs for any execution of brew.

Almost all executions of Homebrew (not just installs) may require reading potentially untrusted Ruby code. It's hard to scope this much more tightly than it is currently, unfortunately.

@bhavanki
Copy link
Author

Thanks for continuing the conversation.

  • brew should restore sudo access for ensuing processes, even if it blocks it for itself.

@bhavanki If you can provide details (ideally a pull request) for how this is technically possible: we'd love that. We haven't been able to figure out how to do this yet.

Yeah, I doubt access can be restored (especially if you all haven't discovered how to). With some further experimenting, I did find a workaround for leaving access in place. It works because sudo caches credentials by user and by TTY, so if the brew command runs in its own TTY, it can freely do away with any inherited access (in fact, I think it never gets it).

This Stack Overflow answer proposes using the script command for this purpose, and it seems to work. I created this shell function to call instead of brew in my own script.

brew() {
  script -q /dev/null "$(command -v brew)" "$@" | sed 's/\r//g'
}

(This is for macOS. Also, the script command seems to emit rogue carriage return characters, hence the sed usage.)

I don't imagine that this exact mechanism could work in brew, but maybe something else adjusting the TTY might. Anyway, hopefully this will solve the problem within my own script.

And, just for completeness: Ansible lets you supply a "become" password which is equivalent to prompting for sudo. It's an extra prompt for the user, but lets Ansible run steps requiring sudo without requiring it to be established ahead of time. It's probably the "right" way anyway.

  • The problem is in formula privilege escalation, but the removal of sudo occurs for any execution of brew.

Almost all executions of Homebrew (not just installs) may require reading potentially untrusted Ruby code. It's hard to scope this much more tightly than it is currently, unfortunately.

Ah, understood, that's too bad!

@MikeMcQuaid
Copy link
Member

Thanks @bhavanki!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Reproducible Homebrew/brew bug
Projects
None yet
Development

No branches or pull requests

2 participants