From 3d6869aa9f73464215b12c82a91e6aaec55c520f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 8 Sep 2026 04:36:33 +0300 Subject: [PATCH 1/4] supautils: match prod debug symbols and glibc symbol versions --- .../supautils-strtol-glibc-compat.patch | 29 +++++++++++++++++++ nix/ext/supautils.nix | 4 +++ 2 files changed, 33 insertions(+) create mode 100644 nix/ext/patches/supautils-strtol-glibc-compat.patch diff --git a/nix/ext/patches/supautils-strtol-glibc-compat.patch b/nix/ext/patches/supautils-strtol-glibc-compat.patch new file mode 100644 index 0000000000..6e8292d8f5 --- /dev/null +++ b/nix/ext/patches/supautils-strtol-glibc-compat.patch @@ -0,0 +1,29 @@ +diff --git a/src/constrained_extensions.c b/src/constrained_extensions.c +index 18e5aee..d5172a3 100644 +--- a/src/constrained_extensions.c ++++ b/src/constrained_extensions.c +@@ -9,6 +9,24 @@ + #include "constrained_extensions.h" + #include "utils.h" + ++// Force GLIBC_2.17 (atoi's inlined strtol, dlsym/dlvsym) for older-glibc hosts. ++#if defined(__linux__) && defined(__GLIBC__) ++extern void *dlvsym(void *handle, const char *symbol, const char *version); ++extern void *dlsym(void *handle, const char *symbol); ++__asm__(".symver dlvsym,dlvsym@GLIBC_2.17"); ++__asm__(".symver dlsym,dlsym@GLIBC_2.17"); ++static int ++_supautils_compat_atoi(const char *nptr) ++{ ++ long (*fn)(const char *, char **, int) = ++ (long (*)(const char *, char **, int)) dlvsym((void *) 0, "strtol", "GLIBC_2.17"); ++ if (!fn) ++ fn = (long (*)(const char *, char **, int)) dlsym((void *) 0, "strtol"); ++ return fn ? (int) fn(nptr, NULL, 10) : 0; ++} ++#define atoi(a) _supautils_compat_atoi(a) ++#endif ++ + static JSON_ACTION_RETURN_TYPE json_array_start(void *state) { + json_constrained_extension_parse_state *parse = state; + diff --git a/nix/ext/supautils.nix b/nix/ext/supautils.nix index 361cd1b741..bd16c8919c 100644 --- a/nix/ext/supautils.nix +++ b/nix/ext/supautils.nix @@ -12,6 +12,8 @@ stdenv.mkDerivation rec { buildInputs = [ postgresql ]; + dontStrip = true; + src = fetchFromGitHub { owner = "supabase"; repo = pname; @@ -19,6 +21,8 @@ stdenv.mkDerivation rec { hash = "sha256-O2zVVVf2OFTCc4BYHuGJ67odU0TwMnTJQuz9uk+a4/0="; }; + patches = [ ./patches/supautils-strtol-glibc-compat.patch ]; + installPhase = '' mkdir -p $out/lib From 274e75a5de38ddd18e464a7d77564df48c643b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Wed, 9 Sep 2026 01:32:21 +0300 Subject: [PATCH 2/4] supautils: drop unversioned dlsym fallback in glibc-compat shim The fallback silently re-resolved strtol to its default (newest) version if the GLIBC_2.17 lookup ever failed, defeating the whole point of the patch. GLIBC_2.17 is strtol's only version node in modern glibc (the 2.38 one is a distinct symbol, __isoc23_strtol, from the C23 variant of atoi/stdlib.h), and it's already comfortably below the project's glibc 2.31 floor, so no version bump is needed here. Co-Authored-By: Claude Sonnet 5 --- nix/ext/patches/supautils-strtol-glibc-compat.patch | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/nix/ext/patches/supautils-strtol-glibc-compat.patch b/nix/ext/patches/supautils-strtol-glibc-compat.patch index 6e8292d8f5..935dcaf835 100644 --- a/nix/ext/patches/supautils-strtol-glibc-compat.patch +++ b/nix/ext/patches/supautils-strtol-glibc-compat.patch @@ -1,24 +1,22 @@ diff --git a/src/constrained_extensions.c b/src/constrained_extensions.c -index 18e5aee..d5172a3 100644 +index 18e5aee..4eced0b 100644 --- a/src/constrained_extensions.c +++ b/src/constrained_extensions.c -@@ -9,6 +9,24 @@ +@@ -9,6 +9,22 @@ #include "constrained_extensions.h" #include "utils.h" -+// Force GLIBC_2.17 (atoi's inlined strtol, dlsym/dlvsym) for older-glibc hosts. ++// Modern glibc's inlined atoi() calls __isoc23_strtol@GLIBC_2.38 instead of ++// strtol. That symbol doesn't exist on older hosts, so resolve plain ++// strtol@GLIBC_2.17 (its only version node) directly instead. +#if defined(__linux__) && defined(__GLIBC__) +extern void *dlvsym(void *handle, const char *symbol, const char *version); -+extern void *dlsym(void *handle, const char *symbol); +__asm__(".symver dlvsym,dlvsym@GLIBC_2.17"); -+__asm__(".symver dlsym,dlsym@GLIBC_2.17"); +static int +_supautils_compat_atoi(const char *nptr) +{ + long (*fn)(const char *, char **, int) = + (long (*)(const char *, char **, int)) dlvsym((void *) 0, "strtol", "GLIBC_2.17"); -+ if (!fn) -+ fn = (long (*)(const char *, char **, int)) dlsym((void *) 0, "strtol"); + return fn ? (int) fn(nptr, NULL, 10) : 0; +} +#define atoi(a) _supautils_compat_atoi(a) From 66af52362324121a10d42e4328ba5f29336ac097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Wed, 9 Sep 2026 01:35:26 +0300 Subject: [PATCH 3/4] supautils: shorten glibc-compat comment Co-Authored-By: Claude Sonnet 5 --- nix/ext/patches/supautils-strtol-glibc-compat.patch | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/nix/ext/patches/supautils-strtol-glibc-compat.patch b/nix/ext/patches/supautils-strtol-glibc-compat.patch index 935dcaf835..970c441501 100644 --- a/nix/ext/patches/supautils-strtol-glibc-compat.patch +++ b/nix/ext/patches/supautils-strtol-glibc-compat.patch @@ -1,14 +1,12 @@ diff --git a/src/constrained_extensions.c b/src/constrained_extensions.c -index 18e5aee..4eced0b 100644 +index 18e5aee..64757d7 100644 --- a/src/constrained_extensions.c +++ b/src/constrained_extensions.c -@@ -9,6 +9,22 @@ +@@ -9,6 +9,20 @@ #include "constrained_extensions.h" #include "utils.h" -+// Modern glibc's inlined atoi() calls __isoc23_strtol@GLIBC_2.38 instead of -+// strtol. That symbol doesn't exist on older hosts, so resolve plain -+// strtol@GLIBC_2.17 (its only version node) directly instead. ++// atoi's inlined strtol resolves to __isoc23_strtol@GLIBC_2.38; pin strtol@GLIBC_2.17 instead. +#if defined(__linux__) && defined(__GLIBC__) +extern void *dlvsym(void *handle, const char *symbol, const char *version); +__asm__(".symver dlvsym,dlvsym@GLIBC_2.17"); From cf5b0c1b9ac79c67ed5ebddd4421175c4a5989a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Wed, 9 Sep 2026 01:59:40 +0300 Subject: [PATCH 4/4] supautils: fix glibc-compat version pin for x86_64 GLIBC_2.17 isn't a valid version node for dlvsym/strtol on x86_64 (verified via objdump against the real glibc: x86_64's nodes are 2.2.5/2.34, since that symbol's ABI never changed at 2.17 there). It only worked on aarch64 because aarch64 support was added in glibc 2.17, making that its earliest possible tag. Pin per-arch: 2.2.5 on x86_64, 2.17 on aarch64. Co-Authored-By: Claude Sonnet 5 --- .../supautils-strtol-glibc-compat.patch | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/nix/ext/patches/supautils-strtol-glibc-compat.patch b/nix/ext/patches/supautils-strtol-glibc-compat.patch index 970c441501..1e3bf484c0 100644 --- a/nix/ext/patches/supautils-strtol-glibc-compat.patch +++ b/nix/ext/patches/supautils-strtol-glibc-compat.patch @@ -1,20 +1,27 @@ diff --git a/src/constrained_extensions.c b/src/constrained_extensions.c -index 18e5aee..64757d7 100644 +index 18e5aee..cdfb63f 100644 --- a/src/constrained_extensions.c +++ b/src/constrained_extensions.c -@@ -9,6 +9,20 @@ +@@ -9,6 +9,27 @@ #include "constrained_extensions.h" #include "utils.h" -+// atoi's inlined strtol resolves to __isoc23_strtol@GLIBC_2.38; pin strtol@GLIBC_2.17 instead. -+#if defined(__linux__) && defined(__GLIBC__) ++// atoi's inlined strtol resolves to __isoc23_strtol@GLIBC_2.38; pin strtol's oldest ++// version node instead (2.2.5 on x86_64, 2.17 on aarch64, which glibc added support ++// for at 2.17, so it has no earlier tag). ++#if defined(__linux__) && defined(__GLIBC__) && (defined(__x86_64__) || defined(__aarch64__)) ++# if defined(__x86_64__) ++# define SUPAUTILS_GLIBC_COMPAT_VER "GLIBC_2.2.5" ++# else ++# define SUPAUTILS_GLIBC_COMPAT_VER "GLIBC_2.17" ++# endif +extern void *dlvsym(void *handle, const char *symbol, const char *version); -+__asm__(".symver dlvsym,dlvsym@GLIBC_2.17"); ++__asm__(".symver dlvsym,dlvsym@" SUPAUTILS_GLIBC_COMPAT_VER); +static int +_supautils_compat_atoi(const char *nptr) +{ + long (*fn)(const char *, char **, int) = -+ (long (*)(const char *, char **, int)) dlvsym((void *) 0, "strtol", "GLIBC_2.17"); ++ (long (*)(const char *, char **, int)) dlvsym((void *) 0, "strtol", SUPAUTILS_GLIBC_COMPAT_VER); + return fn ? (int) fn(nptr, NULL, 10) : 0; +} +#define atoi(a) _supautils_compat_atoi(a)