install: report an over-long relative path instead of a panic for --cafile, --cwd and add --filter
Closed
RO
1mo ago+144+144+012345678901234567890123456789-22-22-01234567890123456789
Problem
bun install --cafile=<relative path near PATH_MAX>crashes withpanic: range end index 4109 out of range for slice of length 4095.bun install --cwd ./<long>andbun add --filter <ws> ./<long>crash the same way. An absolute path of the same length prints an error and exits 1.- The cause is
join_abs_string_buf, which writes the joined path into aPATH_MAXbuffer with no length check. Three sites join a user-supplied relative path onto the cwd with it:src/install/PackageManager.rs:2300(cafile),src/install/PackageManager/CommandLineArguments.rs:1615(--cwd),src/install/PackageManager/add_remove_with_filter.rs:405(add --filter).
Fix
- All three sites use
join_abs_string_buf_checked. It returnsNonewhen the normalized result does not fit the buffer. - On
None, each site prints the error it already prints for a bad path of that kind and exits 1:HTTPThread: could not find CA file: '<value>',failed to change directory to "<value>": ENAMETOOLONG,Dependency "<value>" has an unsafe folder path. The absolute--cwdbranch copied into the buffer unchecked too. It now takes the same error path. - Verified:
test/cli/install/bun-install-registry.test.ts(cafile at the exact buffer length, one byte past, far past, and the bunfigcafilekey),test/cli/install/bun-install.test.ts(--cwdrelative and absolute),test/cli/install/bun-add-filter.test.ts(add --filterlocal path). Each new test except the exact-fit one fails on the release build with the panic. Also ran allcafile,--cwdand--filtertests in those files. - Self-reviewed: the first commit was reviewed before the PR opened (3 concerns, all addressed). The review of the second commit did not return. I pushed it on the basis of the local test runs listed above.
Background
--cafile(andcafilein bunfig[install]) names a CA certificate bundle for registry TLS.PackageManager::initresolves a relative value against the original cwd before it starts the HTTP thread. The bunfig key feeds the sameoptions.ca_file_namefield.bun_paths::resolve_path::join_abs_string_bufjoins path parts into a caller buffer ofMAX_PATH_BYTES(4096 on Linux, 1024 on macOS, about 98 KB on Windows). The_checkedvariant is the fallible form for user-controlled input.WorkspaceMap.rs,OverrideMap.rsandlockfile/Package.rsalready use it.- Considered a check at only the cafile site: it leaves the same panic reachable from two other flags. The three sites share one mechanism, so the fix goes to all three.
Downsides
- None found. The checked join takes the same fast path as the unchecked one when the joined length is below the buffer length (
src/paths/resolve_path.rs:1690). Only an input that does not fit pays the slow path, and that input crashed before.
Notes
Repro on bun 1.4.2 and canary:
cd "$(mktemp -d)"; echo '{"name":"a","dependencies":{"x":"1"}}' > package.json
L=$(head -c 4090 /dev/zero | tr '\0' a)
bun install --cafile=$L
bun install --cwd ./$L
bun install --cwd /$(head -c 5000 /dev/zero | tr '\0' a)
bun add --filter b ./$L # in a workspace root with a workspace named b
All four print panic: range end index N out of range for slice of length 4096 (4095 for the cafile case) on the release build.
The --cwd and add --filter sites came from a review comment on this PR. The cafile boundary tests and the bunfig entry point test came from another.
no test proof · iteration 0 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/cli/install/bun-install.test.ts, test/cli/install/bun-install-registry.test.ts, test/cli/install/bun-add-filter.test.ts