distcc 3.4 client crashes with buffer overflow on boltzmann #3

Closed
opened 2026-04-20 09:38:56 +00:00 by marfrit · 1 comment
Owner

distcc 3.4 (built 2026-04-17) from marfrit-packages crashes with glibc FORTIFY_SOURCE *** buffer overflow detected ***: terminated on every client invocation on boltzmann (aarch64, RK3588, Arch Linux ARM).

Reproducer:

$ distcc gcc --version
*** buffer overflow detected ***: terminated
$ echo $?
134

All masquerade variants (/usr/lib/distcc/aarch64-linux-gnu-gcc, a manually created /usr/lib/distcc/gcc -> /usr/bin/distcc symlink) exhibit identical behaviour. Kernel builds setting CC="distcc gcc" or using the masquerade PATH fail at the Kconfig scripts/Kconfig.include compiler-detection stage with:

scripts/Kconfig.include:45: Sorry, this C compiler is not supported.

Distccd on the same system (tesla, CT108) accepts jobs fine — only the client-side invocation on boltzmann is affected.

Likely cause: distcc 3.4 was built against an older glibc ABI, or built with _FORTIFY_SOURCE enabled over a code path that has an off-by-one. Needs rebuild against current glibc with fortify-level downgrade, or cherry-picked patch from upstream distcc 3.5 pre-release.

Blocks: kernel builds cannot use distcc on boltzmann. Local -j16 falls back to ~20-25 min instead of ~8 min with CT108+tesla workers.

Session reference: Bin campaign kernel rebuild 2026-04-20 (noether).

distcc 3.4 (built 2026-04-17) from marfrit-packages crashes with glibc FORTIFY_SOURCE `*** buffer overflow detected ***: terminated` on every client invocation on boltzmann (aarch64, RK3588, Arch Linux ARM). Reproducer: ``` $ distcc gcc --version *** buffer overflow detected ***: terminated $ echo $? 134 ``` All masquerade variants (`/usr/lib/distcc/aarch64-linux-gnu-gcc`, a manually created `/usr/lib/distcc/gcc -> /usr/bin/distcc` symlink) exhibit identical behaviour. Kernel builds setting `CC="distcc gcc"` or using the masquerade PATH fail at the Kconfig `scripts/Kconfig.include` compiler-detection stage with: ``` scripts/Kconfig.include:45: Sorry, this C compiler is not supported. ``` Distccd on the same system (tesla, CT108) accepts jobs fine — only the client-side invocation on boltzmann is affected. Likely cause: distcc 3.4 was built against an older glibc ABI, or built with `_FORTIFY_SOURCE` enabled over a code path that has an off-by-one. Needs rebuild against current glibc with fortify-level downgrade, or cherry-picked patch from upstream distcc 3.5 pre-release. Blocks: kernel builds cannot use distcc on boltzmann. Local -j16 falls back to ~20-25 min instead of ~8 min with CT108+tesla workers. Session reference: Bin campaign kernel rebuild 2026-04-20 (noether).
Author
Owner

Fixed in 3.4-17 (commit ef7911d) with fix-gcc-rewrite-fqn-overflow.patch.

Root cause

Upstream src/compile.c:dcc_gcc_rewrite_fqn() sized the rewritten-compiler-name buffer with strlen(argv[0] + 1)pointer arithmetic applied before strlen. For argv[0] = "gcc" that evaluates to strlen("cc") = 2, under-allocating the buffer by 2 bytes. Intent was strlen(argv[0]) + 1 (length plus terminator).

-    newcmd_len = strlen(target_with_vendor) + 1 + strlen(argv[0] + 1);
+    newcmd_len = strlen(target_with_vendor) + 1 + strlen(argv[0]) + 1;

The subsequent strcat(newcmd, argv[0]) then overflows by 2 bytes. Pre-FORTIFY builds (our old pkgrel=15 shipped before Arch's makepkg.conf bumped to _FORTIFY_SOURCE=2) silently clobbered 2 bytes of heap adjacent metadata — which happened to be harmless on the short-allocation paths glibc's tcache was using, so the bug went unnoticed for years. pkgrel=16 was built under FORTIFY=2, which promoted the silent overwrite into an abort().

Verification

  • tesla (aarch64 Arch LXC, pkgrel=15): runs clean. Same source, same PATH, different FORTIFY level at build time.
  • boltzmann (aarch64 BredOS, pkgrel=16): aborts with *** buffer overflow detected *** on every distcc gcc … invocation.
  • boltzmann after 3.4-17: clean, distcc gcc --version returns the expected cross-compiler banner.

Upstream

Worth filing at https://github.com/distcc/distcc/issues — the upstream v3.4 tag (2021) still carries this. Not yet done; will note if/when reported.

Fixed in 3.4-17 (commit ef7911d) with `fix-gcc-rewrite-fqn-overflow.patch`. ## Root cause Upstream `src/compile.c:dcc_gcc_rewrite_fqn()` sized the rewritten-compiler-name buffer with `strlen(argv[0] + 1)` — **pointer arithmetic applied *before* strlen**. For `argv[0] = "gcc"` that evaluates to `strlen("cc") = 2`, under-allocating the buffer by 2 bytes. Intent was `strlen(argv[0]) + 1` (length plus terminator). ```c - newcmd_len = strlen(target_with_vendor) + 1 + strlen(argv[0] + 1); + newcmd_len = strlen(target_with_vendor) + 1 + strlen(argv[0]) + 1; ``` The subsequent `strcat(newcmd, argv[0])` then overflows by 2 bytes. Pre-FORTIFY builds (our old pkgrel=15 shipped before Arch's makepkg.conf bumped to `_FORTIFY_SOURCE=2`) silently clobbered 2 bytes of heap adjacent metadata — which happened to be harmless on the short-allocation paths glibc's tcache was using, so the bug went unnoticed for years. pkgrel=16 was built under FORTIFY=2, which promoted the silent overwrite into an `abort()`. ## Verification - **tesla** (aarch64 Arch LXC, pkgrel=15): runs clean. Same source, same PATH, different FORTIFY level at build time. - **boltzmann** (aarch64 BredOS, pkgrel=16): aborts with `*** buffer overflow detected ***` on every `distcc gcc …` invocation. - **boltzmann after 3.4-17**: clean, `distcc gcc --version` returns the expected cross-compiler banner. ## Upstream Worth filing at https://github.com/distcc/distcc/issues — the upstream `v3.4` tag (2021) still carries this. Not yet done; will note if/when reported.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marfrit/marfrit-packages#3