Skip to content

Commit 0f297d8

Browse files
authored
Merge pull request #32 from ArchiveBox/claude/magical-pascal-iR9iO
Fix root-as-dropped-euid exec env and restore Binary.load_or_install
2 parents 322aaaf + 501cc33 commit 0f297d8

4 files changed

Lines changed: 38 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ PATH = "" # prepends cargo_root/bin and cargo_home/bi
952952
cargo_root = None # set this for hermetic installs
953953
```
954954

955-
- Install root: set `install_root=Path(...)` or `install_root=Path(...)` for isolated installs under `<cargo_root>/bin`; otherwise installs go through `cargo_home`.
955+
- Install root: set `install_root=Path(...)` or `cargo_root=Path(...)` for isolated installs under `<cargo_root>/bin`; otherwise installs go through `cargo_home`.
956956
- Auto-switching: none.
957957
- `dry_run`: shared behavior.
958958
- Security: `min_release_age` and `postinstall_scripts=False` are unsupported and are ignored with a warning if explicitly requested.

abxpkg/binprovider.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1732,10 +1732,18 @@ def drop_privileges():
17321732
sudo_proc.stderr,
17331733
)
17341734

1735+
# When running as root but dropping to a non-root user (e.g. brew),
1736+
# use the target user's HOME/LOGNAME/USER env so the dropped-privilege
1737+
# subprocess finds its own cache/config dirs instead of root's.
1738+
dropped_env = (
1739+
sudo_env
1740+
if current_euid == 0 and run_as_uid != current_euid
1741+
else fallback_env
1742+
)
17351743
proc = subprocess.run(
17361744
cmd,
17371745
cwd=str(cwd_path),
1738-
env=fallback_env,
1746+
env=dropped_env,
17391747
preexec_fn=drop_privileges,
17401748
**kwargs,
17411749
)

abxpkg/binprovider_brew.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,26 @@ def _refresh_bin_link(
163163
link_path = self._linked_bin_path(bin_name)
164164
assert link_path is not None, "_refresh_bin_link requires bin_dir to be set"
165165
link_path.parent.mkdir(parents=True, exist_ok=True)
166+
# When running as root but brew itself drops to its owner uid via
167+
# ``self.exec``, we also need the managed shim dir (and its parents)
168+
# traversable by that target uid so version probes / load() calls from
169+
# the dropped-privilege subprocess can reach the symlink.
170+
current_euid = os.geteuid()
171+
target_uid = self.EUID
172+
if current_euid == 0 and target_uid not in (0, current_euid):
173+
try:
174+
pw_record = self.get_pw_record(target_uid)
175+
os.chown(link_path.parent, target_uid, pw_record.pw_gid)
176+
except Exception:
177+
pass
178+
walk_path = link_path.parent
179+
while walk_path != walk_path.parent:
180+
try:
181+
mode = walk_path.stat().st_mode
182+
walk_path.chmod(mode | 0o055)
183+
except Exception:
184+
break
185+
walk_path = walk_path.parent
166186
if link_path.exists() or link_path.is_symlink():
167187
link_path.unlink(missing_ok=True)
168188
link_path.symlink_to(target)

abxpkg/binprovider_puppeteer.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ class PuppeteerProvider(BinProvider):
6666
# Only set in managed mode: setup()/default_abspath_handler() use it to expose stable
6767
# browser launch shims under ``<install_root>/bin``; global mode leaves it unset.
6868
bin_dir: Path | None = None
69+
# Explicit override for the directory browsers get downloaded into. When
70+
# unset, cache_dir defaults to ``<install_root>/cache``; when set, it wins
71+
# so callers can point ``PUPPETEER_CACHE_DIR`` at an arbitrary path.
72+
browser_cache_dir: Path | None = None
6973

7074
@computed_field
7175
@property
@@ -80,7 +84,10 @@ def supports_postinstall_disable(self, action, no_cache: bool = False) -> bool:
8084
@computed_field
8185
@property
8286
def cache_dir(self) -> Path | None:
83-
# Browser downloads always live under ``install_root/cache`` when we
87+
# Explicit override wins so PUPPETEER_CACHE_DIR can be any path.
88+
if self.browser_cache_dir is not None:
89+
return self.browser_cache_dir
90+
# Otherwise browser downloads live under ``install_root/cache`` when we
8491
# manage an install root; global mode leaves cache ownership to the host.
8592
if self.install_root is not None:
8693
return self.install_root / "cache"

0 commit comments

Comments
 (0)