[rush] rush-daemon-transport: long socket paths are silently truncated so workspaces share one daemon; reclaim lock steal is not exclusive; deleting the runtime dir leaves an unreachable daemon running
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 45/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- linux, nodejs, typescript
Línea de trabajo
The issue points to specific files: libraries/rush-daemon-transport/src/DaemonPaths.ts for socket path length, DaemonReclaimLock.ts for mutex handling, and DaemonReclaim.ts for lock cleanup. Start by reproducing the truncation with a long XDG_RUNTIME_DIR, then examine the socket creation and reclaim lock logic. Testing involves concurrent processes and file system operations. 'Done' means each of the three problems is fixed with robust error handling and atomic operations.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
Three robustness problems in the daemon transport, each reproduced on Linux with rush-client/rushd from main @ 60007c9a8c:
- Socket paths longer than
sun_path(108 bytes) are silently truncated, so different workspaces share one daemon.resolveDaemonPaths(libraries/rush-daemon-transport/src/DaemonPaths.ts:61-67) builds<base>/rushd-<uid>/rushd-<32hex>.sock(the base plus 55 bytes) and never checks the result against the limit. Node/libuv then truncate the path onlisten()/connect(). The part that gets cut off is the workspace key: with a 77-character base the socket is namedrushd-44c88aeea54e6, and with 90 characters it is justrushd-. So with a longXDG_RUNTIME_DIRorTMPDIR(deep CI, sandbox, Nix or Bazel-style directories), workspace B talks to workspace A's daemon:daemon statusin ws2 reports ws1's PID,buildfails withCannot attest the restarting daemon ownership, anddaemon stopin ws1 can stop the wrong daemon. Expected: detect overlong paths and switch to a shorter derived location (for example a hashed path under a short base), or fail with a clear error. Never truncate silently. - The reclaim mutex's steal path is not exclusive. On EEXIST with a dead
mutexPid,tryAcquireReclaimLock(DaemonReclaimLock.ts:73-86) callsrewriteMutexEntry(:47-64), which doesunlinkSync(lock)and thenwriteFileSync(lock, { flag: 'wx' }). Two stealers can both see "dead holder"; B then unlinks A's fresh file and creates its own, so both acquire. In 10 trials with 16 concurrent stealers, every trial had more than one holder (2-6). In addition,readMutexPidtreats a just-created, still-empty file as dead, and thefinallyinDaemonReclaim.ts:46-52unlinks.reclaimeven when another process owns it. Expected: steal atomically (for example rename a uniquely named file over the lock and re-verify ownership after writing), and release only a lock you still own. - Deleting the runtime dir or socket leaves an unreachable live daemon running alongside a new one. systemd-logind removes
/run/user/<uid>at logout, and tmp cleaners can remove it too. The old daemon keeps running, unreachable, until its idle timeout (900 s by default); the next client auto-starts a second daemon for the same workspace; anddaemon stoponly reaches the new one. Expected: after binding, the host periodically re-validates thatlstat(socketPath)still matches the bound inode and that the lockfile still names its own PID, and shuts down (or re-publishes its endpoint) when it doesn't.
Repro steps
- Start the daemon with
XDG_RUNTIME_DIR=<90-char dir>in two different workspaces, then rundaemon statusin the second: it reports the first workspace's PID. - Seed
<key>.pid.json.reclaimwith{"mutexPid": <dead pid>}and have 16 forked processes calltryAcquireReclaimLockat the same moment: more than one acquires. rush-client daemon start && rush-client build, thenrm -rf $XDG_RUNTIME_DIR/rushd-<uid>, thenrush-client build: two daemon processes now exist for the workspace.
Expected result: As described for each item above.
Actual result: As described for each item above.
Details
This was found during an automated performance/behavior analysis of rush-client/rushd on Linux. Each item was confirmed independently (item 1 twice).
Standard questions
| Question | Answer |
|---|---|
@microsoft/rush globally installed version? |
built from main @ 60007c9a8c (5.179.0) |
rushVersion from rush.json? |
5.179.0 |
pnpmVersion, npmVersion, or yarnVersion from rush.json? |
pnpm@10.27.0 |
(if pnpm) useWorkspaces from pnpm-config.json? |
true |
| Operating system? | Linux (WSL2 Ubuntu 24.04) |
| Would you consider contributing a PR? | Yes |
Node.js version (node -v)? |
22.23.2 |
- Lenguaje dominante
- TypeScript
- Estrellas
- 6.5k
- Forks
- 708
- Merge medio
- 4 d 13 h
- PR fusionados (30 d)
- 62
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/rushstack
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Dificultad 4/5 3-5 días Aptitud para principiantes 40/100
Todos los issues de microsoft/rushstack
Issues similares
-
bug(cli): hapi doctor inline-media prints a fabricated B:\ helper-script path in packaged installs Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
-
Crush Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
catppuccin/catppuccin#3125 ·
-
Add a SECURITY.md Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
ElementsProject/cln-application#167 · 1 comentario · 1 reacción ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Quantco/pnpm-licenses#17 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100