-
-
Notifications
You must be signed in to change notification settings - Fork 10.1k
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
brew.sh: Don't allow system tmp dirs as prefixes #4397
brew.sh: Don't allow system tmp dirs as prefixes #4397
Conversation
Library/Homebrew/brew.sh
Outdated
Your HOMEBREW_PREFIX is in the system temporary directory, which Homebrew | ||
uses to store downloads and builds. You can resolve this by installing Homebrew to | ||
either the standard prefix (/usr/local/) or to a non-standard prefix that is not | ||
the system temporary directory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/the/in the/
Library/Homebrew/brew.sh
Outdated
if [[ $(realpath "${HOMEBREW_PREFIX}") = /private/tmp/* ]] | ||
then | ||
odie <<EOS | ||
Your HOMEBREW_PREFIX is in the system temporary directory, which Homebrew |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth just saying e.g. /private/tmp
? Also, should we do this on Linux or with a different directory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that the connection between /tmp
and /private/tmp
might confuse some users (Apple links /tmp
to /private/tmp
for FHS compliance), so I just went with "system temporary directory." I can change it/add those directories to the message if you think it'll improve the error, though.
The relocation code at fault isn't used on Linux, so Linuxbrew users might not encounter this problem at all. I'll confirm that in a bit with some local testing.
Library/Homebrew/brew.sh
Outdated
odie <<EOS | ||
Your HOMEBREW_PREFIX is in the system temporary directory, which Homebrew | ||
uses to store downloads and builds. You can resolve this by installing Homebrew to | ||
either the standard prefix (/usr/local/) or to a non-standard prefix that is not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(/usr/local)
maybe?
The underlying issue specifically affects HOMEBREW_TEMP regardless of whether it's the default /tmp or some other path (and if HOMEBREW_TEMP isn't /tmp then /tmp is unaffected) so I'm wondering if the check and the messaging should check the value of HOMEBREW_TEMP for a non-default value and handle that case correctly too. |
Yeah, I'll update it to handle this. It gets a little complicated, though, thanks to the Edit: Actually, I guess |
bin/brew
Outdated
@@ -72,7 +73,7 @@ then | |||
|
|||
FILTERED_ENV=() | |||
# Filter all but the specific variables. | |||
for VAR in HOME SHELL PATH TERM COLUMNS LOGNAME USER CI TRAVIS SSH_AUTH_SOCK SUDO_ASKPASS \ | |||
for VAR in HOME SHELL PATH TEMP TERM COLUMNS LOGNAME USER CI TRAVIS SSH_AUTH_SOCK SUDO_ASKPASS \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want to add this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I misread this code. I thought this was explicitly whitelisting HOMEBREW_TEMP
, but I guess it would clobber it instead.
Library/Homebrew/config.rb
Outdated
@@ -39,7 +39,7 @@ | |||
HOMEBREW_LOGS = Pathname.new(ENV["HOMEBREW_LOGS"] || "~/Library/Logs/Homebrew/").expand_path | |||
|
|||
# Must use /tmp instead of $TMPDIR because long paths break Unix domain sockets | |||
HOMEBREW_TEMP = Pathname.new(ENV.fetch("HOMEBREW_TEMP", "/tmp")) | |||
HOMEBREW_TEMP = Pathname.new(ENV.fetch("HOMEBREW_TEMP", "/tmp")).realpath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will never be unset/set to /tmp
now.
We provide a /private/tmp fallback in bin/brew, so this is no longer necessary.
Looks like the test failure is coming from Any thoughts on how best to resolve this? I could add another environment variable allowing the behavior in the PR to be overridden for testing purposes, or change |
I'd vote on doing this; no reason it can't act in the current directory (as a developer, testing command) if it's cleaned up afterwards. |
bin/brew
Outdated
@@ -21,6 +21,7 @@ symlink_target_directory() { | |||
BREW_FILE_DIRECTORY="$(quiet_cd "${0%/*}/" && pwd -P)" | |||
HOMEBREW_BREW_FILE="${BREW_FILE_DIRECTORY%/}/${0##*/}" | |||
HOMEBREW_PREFIX="${HOMEBREW_BREW_FILE%/*/*}" | |||
HOMEBREW_TEMP="${HOMEBREW_TEMP:-/private/tmp}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this upset Linux? Worth setting in brew.sh
to a different default for macOS and not-macOS?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, /private/tmp
is macOS only. Moving it to brew.sh
sounds good.
Additionally, assign HOMEBREW_TEMP based on the host system (/tmp for Linux, /private/tmp for macOS).
Library/Homebrew/brew.sh
Outdated
@@ -108,6 +108,8 @@ then | |||
then | |||
HOMEBREW_CACHE="$HOME/Library/Caches/Homebrew" | |||
fi | |||
|
|||
HOMEBREW_TEMP="${HOMEBREW_TEMP:-/private/tmp}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 to defining here. I wonder if it's worth doing just the same -z
as above for consistency? Alternatively; replace the -z
s that have no complex logic with this form?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of replacing with the :-
form, since it's the standard bashism for a default value and we use similar bashisms elsewhere in the code.
Library/Homebrew/brew.sh
Outdated
@@ -294,6 +299,19 @@ EOS | |||
} | |||
check-run-command-as-root | |||
|
|||
check-prefix-is-not-tmpdir() { | |||
if [[ "${HOMEBREW_PREFIX}" = "${HOMEBREW_TEMP}"* ]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wants guarded to macOS only, check against the system temp rather than just HOMEBREW_TEMP
(maybe a HOMEBREW_SYSTEM_TEMP
var?) and use that directory in the output, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HOMEBREW_SYSTEM_TEMP
could be potentially used wherever private/tmp
is hardcoded, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check against the system temp rather than just HOMEBREW_TEMP
I might be misunderstanding, but: won't this leave open the case where they set both their prefix and their temp to something weird, e.g., $HOME
? We want to stop all situations where Homebrew is both installing to and using the same prefix as a temporary directory, not just /private/tmp
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@woodruffw Ok so is it fine to e.g. have the prefix in /tmp
if HOMEBREW_TEMP
is set elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, exactly.
Library/Homebrew/brew.sh
Outdated
HOMEBREW_CACHE="$HOME/.cache/Homebrew" | ||
fi | ||
fi | ||
cache_home="${XDG_CACHE_HOME:-${HOME}/.cache}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use all caps for variable name here and just don't export it.
Library/Homebrew/brew.sh
Outdated
if [[ "${HOMEBREW_PREFIX}" = "${HOMEBREW_TEMP}"* ]] | ||
then | ||
odie <<EOS | ||
Your HOMEBREW_PREFIX is in the system temporary directory, which Homebrew |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HOMEBREW_TEMP
isn't necessary the system temporary directory. To expand on my previous comment (and avoid the autohiding): is the issue if:
- the prefix is in the system temporary directory
- the prefix is the in the HOMEBREW_TEMP temporary directory
- either
We should ensure that the wording makes that clear and the logic is as minimal as possible to the actual problems we've seen people experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is when the prefix is in the HOMEBREW_TEMP
temporary directory. I'll correct the language here 🙂
Thanks @woodruffw and sorry for all the back and forth! Took me a while to understand what was going on here. |
@@ -39,7 +39,7 @@ | |||
HOMEBREW_LOGS = Pathname.new(ENV["HOMEBREW_LOGS"] || "~/Library/Logs/Homebrew/").expand_path | |||
|
|||
# Must use /tmp instead of $TMPDIR because long paths break Unix domain sockets | |||
HOMEBREW_TEMP = Pathname.new(ENV.fetch("HOMEBREW_TEMP", "/tmp")) | |||
HOMEBREW_TEMP = Pathname.new(ENV["HOMEBREW_TEMP"]).realpath |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will crash when the dir doesn't exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. Fixing 😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Ignore that -- I see #4415 takes care of the |
brew style
with your changes locally?brew tests
with your changes locally?This explicitly forbids the use of the system's temporary directory as an installation prefix, as we perform checks against the temporary directory when doing binary relocation.
See: Homebrew/homebrew-core#28877 (comment)