From 118a45dfd5663bb78de9b609f4dec6e06fad1c64 Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Sun, 9 Aug 2026 10:45:14 +0300 Subject: [PATCH] redis: link -pie through REDIS_LDFLAGS, not LDFLAGS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arm64 build failed at: gcc -o commandfilter.so commandfilter.xo -shared -pie -Wl,-z,relro -Wl,-z,now /usr/bin/ld: Scrt1.o: in function `_start': undefined reference to `main' Redis does not link executables only, which is what this recipe assumed. Its test modules are shared objects, tests/modules/Makefile links them with `$(SHOBJ_LDFLAGS) $(LDFLAGS)`, and Redis 8.x builds them as part of the default target — so -pie in LDFLAGS becomes `gcc -shared -pie` and the linker goes looking for main in a shared object. src/Makefile composes FINAL_LDFLAGS = $(LDFLAGS) $(OPT) $(REDIS_LDFLAGS) and reaches it only through REDIS_LD, which links redis-server, redis-cli and redis-benchmark — exactly the three binaries the recipe verifies. The modules Makefile never mentions REDIS_LDFLAGS. So -pie moves there and LDFLAGS keeps the hardening flags, which are valid for shared objects too. That puts redis on the same footing as the recipes that already split the two: CPython's LINKFORSHARED, PHP's EXTRA_LDFLAGS_PROGRAM, Postgres's LDFLAGS_EX. Fixes the same latent bug in dragonfly, found while auditing the rest: it had -pie in LDFLAGS *and* passed -DCMAKE_EXE_LINKER_FLAGS. CMake seeds CMAKE_SHARED_LINKER_FLAGS from LDFLAGS as well, so the LDFLAGS copy was both redundant and a trap waiting for the first shared object the build produces. After the audit only node and bun still carry -pie in LDFLAGS. A default node build genuinely links no shared objects; bun is unverified and already the most fragile recipe here. Both rest on the assumption that just proved wrong for redis, and only a real build will settle them. --- README.md | 3 ++- recipes/dragonfly.pkl | 5 ++++- recipes/redis.pkl | 9 ++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e323d08..39453e2 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,8 @@ build links matters** — a project that also produces shared objects cannot sim | Project | Where `-pie` goes | Why | |---|---|---| | Node.js | `LDFLAGS` | A default Node build links executables only | -| Redis, Bun | `LDFLAGS` | Dependencies are static archives | +| Bun | `LDFLAGS` | Dependencies are static archives | +| Redis | `REDIS_LDFLAGS` | `LDFLAGS` is reused when linking Redis's test modules | | CPython | `LINKFORSHARED` | `LDFLAGS` is reused for stdlib extension `.so` files | | PHP | `EXTRA_LDFLAGS_PROGRAM` | PHP's own program-only link variable | | PostgreSQL | `LDFLAGS_EX` | Postgres separates `_EX` (executables) from `_SL` (shared libs) | diff --git a/recipes/dragonfly.pkl b/recipes/dragonfly.pkl index 714bc46..453174c 100644 --- a/recipes/dragonfly.pkl +++ b/recipes/dragonfly.pkl @@ -20,7 +20,10 @@ version { env = new { [#"CFLAGS"#] = #"-fPIC -fstack-protector-strong"# [#"CXXFLAGS"#] = #"-fPIC -fstack-protector-strong"# - [#"LDFLAGS"#] = #"-pie -Wl,-z,relro -Wl,-z,now"# + // -pie is passed through CMAKE_EXE_LINKER_FLAGS at configure time instead of + // LDFLAGS: CMake seeds CMAKE_SHARED_LINKER_FLAGS from LDFLAGS too, so -pie + // here would break any shared object the build produces. + [#"LDFLAGS"#] = #"-Wl,-z,relro -Wl,-z,now"# } dependencies = new { diff --git a/recipes/redis.pkl b/recipes/redis.pkl index 391feda..1f2997e 100644 --- a/recipes/redis.pkl +++ b/recipes/redis.pkl @@ -18,8 +18,15 @@ version { } env = new { + // Redis builds shared objects as well as executables: its test modules link + // with `$(SHOBJ_LDFLAGS) $(LDFLAGS)`, so -pie in LDFLAGS produces + // `gcc -shared -pie` and the link dies on an undefined reference to `main`. + // + // src/Makefile composes FINAL_LDFLAGS = $(LDFLAGS) $(OPT) $(REDIS_LDFLAGS) + // and uses it only for the executables, so REDIS_LDFLAGS is where -pie goes. [#"CFLAGS"#] = #"-fPIC -fstack-protector-strong"# - [#"LDFLAGS"#] = #"-pie -Wl,-z,relro -Wl,-z,now"# + [#"LDFLAGS"#] = #"-Wl,-z,relro -Wl,-z,now"# + [#"REDIS_LDFLAGS"#] = #"-pie"# } dependencies = new { -- 2.51.2