Skip to content

install: fold the open bun install / pm / pack+publish PRs into one branch (172 PRs) - #39403

Draft
Jarred-Sumner wants to merge 176 commits into
mainfrom
claude/install-mega
Draft

install: fold the open bun install / pm / pack+publish PRs into one branch (172 PRs)#39403
Jarred-Sumner wants to merge 176 commits into
mainfrom
claude/install-mega

Conversation

@Jarred-Sumner

Copy link
Copy Markdown
Collaborator

Folds the open bun install / bun pm / pack+publish PRs from Aug 12–17 into one branch so they can be reviewed and landed together. Each original PR is one squashed commit here (<title> (#N)), in dependency order, so the branch stays bisectable; conflict resolutions between overlapping PRs live in the later PR's commit, and cross-PR API reconciliation is in the mega-merge fixup: commits at the end.

172 PRs folded, 2 excluded, 1 pending (see below). cargo check --workspace and cargo clippy --workspace are clean; test status is tracked in the checklist at the bottom.

Not folded

PR Why
#37925 semantic conflict with #39002 (which needs optional peers bound at load); #39002 is newer and explicitly calls this out
#38777 security screen: make_executable() follows an absolute bin-target symlink out of a file:/link: package and chmods the real file (CVE-2019-16775 class) when the folder dep resolves to an ancestor dir; needs rework before merging
#38557 written against the pre-bun audit fix audit_command.rs; needs a hand re-port (in progress)

Security screen

Every folded diff was reviewed for regressions (path traversal, credential leakage, TLS/integrity weakening, lifecycle-script trust widening, terminal injection, new unsafe on untrusted input). One PR was dropped for it (#38777 above). Items a reviewer may still want to eyeball — none were judged exploitable regressions:

  • bunx: serialize concurrent installs into the shared cache dir with a file lock #37851 (concern, low): bunx serialises concurrent installs into the shared /bunx-- dir with an flock on /.bunx-lock; the lock file is opened by path with O_CREAT|O_RDWR and without O_NOFOLLOW, adding a small symlink-following primitive inside the pre-existing TOCTOU window of the cache-dir trust check.
  • install: stamp lockfileVersion 1 on new bun.lock files #38741 (concern, low): New bun.lock files are stamped lockfileVersion 1 instead of 2, so the two v2-only parse-time fail-closed checks (off-registry npm tarball URL without a supported integrity hash; unsafe git .bun-tag) no longer apply to any lockfile created after this lands. The reduction is defence-in-depth only: the checks are keyed on a digit the lockfile tamperer also controls, main already stamps v1 whenever bun's own output would trip them, a tamperer can supply a matching integrity for their own tarball anyway, and the git tag is re-validated at checkout/extract time (repository.rs:923, extract_tarball.rs:484; github tags stay checked at every version).
  • install: fix default-trusted lifecycle scripts being blocked after yarn.lock migration #38795 (concern, low): Default-trusted check now ignores the URL fragment; the claim that this is exactly as strict as before is slightly off because bun_url lets a ? after # leak the fragment into the request path, though no attacker-chosen tarball results.
  • install: resolve .npmrc //host/ credentials by request URL #38800 (concern, low): .npmrc //host/path/ credentials are now resolved by request URL (npm nerf-dart semantics): scopes without credentials pick them up by registry URL, and tarballs on a host other than the registry get that host's own .npmrc credentials. Scope credentials still never leave the scope origin, but the by-URL match is scheme-agnostic and path-unnormalized, which slightly widens where a registry-controlled dist.tarball can make bun present a token.
  • install: install a git dependency's devDependencies before running its prepare scripts #38810 (concern, low): For a git/github dependency that is already in trustedDependencies and has a prepare-family script, runs a nested bun install --ignore-scripts --no-save in the checkout first. Lifecycle trust is not widened (only reached via has_trusted_dependency, nested install ignores scripts, git deps are never default-trusted), but the nested install fetches and then (via prepare) executes third-party devDependencies chosen by the git repo's ranges without the project's bunfig protections, notably install.minimumReleaseAge / overrides / scoped registries, and it forwards the default-registry token into a child process whose cwd is attacker-authored.
  • install: migrate a package's own file: directories from package-lock.json relative to the package #38990 (concern, low): package-lock file: targets inside a registry/tarball/git package are now migrated as package-relative folder rows without normalising the sub-path, so a hand-edited key with .. is no longer skipped at migration time and containment relies on the installer (hoisted linker checks it, with an overrides-name exemption; isolated linker does not).
  • install: don't issue openat2/fchmodat2 on Android (seccomp SIGSYS) #39084 (concern, low): Skips openat2/fchmodat2 on Android (kernel release contains 'android' OR both ANDROID_ROOT and ANDROID_DATA env vars set); symlink-safety semantics are preserved by the fallbacks, but the env-var trigger lets any environment downgrade RESOLVE_BENEATH/RESOLVE_IN_ROOT hardening on ordinary Linux.

Product-behaviour changes worth a deliberate look: #38741 (new bun.lock files are stamped lockfileVersion: 1 again), #38797 (libc recorded in bun.lock / bun.lockb meta), #38804 (a migrated lockfile and its package.json edits are only written when the command saves a lockfile), #38923 (bun pm ls lists what is installed and exits 1 without node_modules), #38813 (pack/publish resolve workspace:/catalog: from package.json files, not bun.lock).

Conflict resolutions that changed a PR's code (not just context)

Folded PRs

Peer binding, hoisting, bun.lock load/round-trip, resolver dedupe (21)

bun update / bun add package.json edits, overrides (7)

Lockfile migration (yarn / pnpm / npm) (17)

file: / link: / tarball / git local dependencies (16)

Path-buffer overflows: panic → error (15)

Terminal control-character escaping and credential redaction (9)

Registry auth, .npmrc, proxies, URL parsing (16)

bun pm subcommands, audit, help text (14)

bun pm pack / bun publish (13)

Linkers, bins, node_modules layout (9)

Lifecycle scripts, env, minimum-release-age, semver, auto-install (17)

Test-only changes (13)

Platform-specific (5)

Verification

  • cargo check --workspace
  • cargo clippy --workspace --no-deps
  • debug build
  • test/cli/install/** locally
  • CI

robobun added 30 commits August 17, 2026 01:03
robobun and others added 29 commits August 17, 2026 02:23
…Excludes, OwnedURL proxy, is_candidate, publishConfig scope helpers, pnpm optional lockfile)
@robobun

robobun commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator
Updated 9:33 PM PT - Aug 16th, 2026

@Jarred-Sumner, your commit 2381dc6 has 26 failures in Build #99835 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 39403

That installs a local version of the PR into your bun-39403 executable, so you can run:

bun-39403 --bun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants