From cf1fc5f6a5ad2a07cb823ca8cc702bb39bddce96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Mon, 5 Oct 2026 17:06:29 +0300 Subject: [PATCH 1/4] fix(nix): pin glibc-versioned symbols for 2.31 floor compliance Shared compat shim (symver pins + dlvsym resolution) for dlopen/dlsym/ dlerror/dlclose, sem_*, shm_*, pthread_sigmask, pthread_getattr_np, fcntl/fcntl64, stat/fstat/lstat family, strtol/strtoul/sscanf/fscanf. Wired into orioledb, supabase-groonga, pgbouncer, pgbackrest. goss and packer instead set CGO_ENABLED=0: confirmed fully static, no glibc dependency at all. Refs: MPG-1326 --- nix/ext/orioledb.nix | 1 + nix/ext/pgroonga/groonga.nix | 1 + nix/glibc-compat-shim.h | 199 +++++++++++++++++++++++++++++++++++ nix/packages/packer.nix | 2 + nix/packages/pg-backrest.nix | 1 + nix/packages/supascan.nix | 1 + nix/pgbouncer.nix | 1 + 7 files changed, 206 insertions(+) create mode 100644 nix/glibc-compat-shim.h diff --git a/nix/ext/orioledb.nix b/nix/ext/orioledb.nix index c0fa3a5efe..230c6a972b 100644 --- a/nix/ext/orioledb.nix +++ b/nix/ext/orioledb.nix @@ -19,6 +19,7 @@ stdenv.mkDerivation rec { sha256 = "sha256-kmNfneISVhlD9Pmnl69pkiAX77MzpzyJQB/5wQ1wiZc="; }; version = "beta18"; + NIX_CFLAGS_COMPILE = "-include ${../glibc-compat-shim.h}"; buildInputs = [ curl libkrb5 diff --git a/nix/ext/pgroonga/groonga.nix b/nix/ext/pgroonga/groonga.nix index c6d734db6c..45b9cb009e 100644 --- a/nix/ext/pgroonga/groonga.nix +++ b/nix/ext/pgroonga/groonga.nix @@ -23,6 +23,7 @@ stdenv.mkDerivation (finalAttrs: { pname = "supabase-groonga"; version = "14.0.5"; + NIX_CFLAGS_COMPILE = "-include ${../../glibc-compat-shim.h}"; src = fetchurl { url = "https://packages.groonga.org/source/groonga/groonga-${finalAttrs.version}.tar.gz"; hash = "sha256-y4UGnv8kK0z+br8wXpPf57NMXkdEJHcLCuTvYiubnIc="; diff --git a/nix/glibc-compat-shim.h b/nix/glibc-compat-shim.h new file mode 100644 index 0000000000..bea8c1bf3a --- /dev/null +++ b/nix/glibc-compat-shim.h @@ -0,0 +1,199 @@ +#ifndef SUPABASE_GLIBC_COMPAT_SHIM_H +#define SUPABASE_GLIBC_COMPAT_SHIM_H + +/* -include forces this into .S files too, which the C bits below can't survive. */ +#ifndef __ASSEMBLER__ + +/* Must come before any system header: glibc locks in feature-test-macro visibility (e.g. GNU extensions) at first include. */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +/* Include order locks in __GLIBC__ and glibc's own inline atoi/atol before any override below exists. */ +#include +#include +#include +#include +#include +#include + +#if defined(__linux__) && defined(__GLIBC__) + +#define GLIBC_COMPAT_VER "GLIBC_2.17" + +__asm__(".symver dlopen,dlopen@" GLIBC_COMPAT_VER); +__asm__(".symver dlsym,dlsym@" GLIBC_COMPAT_VER); +__asm__(".symver dlerror,dlerror@" GLIBC_COMPAT_VER); +__asm__(".symver dlclose,dlclose@" GLIBC_COMPAT_VER); +__asm__(".symver sem_init,sem_init@" GLIBC_COMPAT_VER); +__asm__(".symver sem_wait,sem_wait@" GLIBC_COMPAT_VER); +__asm__(".symver sem_post,sem_post@" GLIBC_COMPAT_VER); +__asm__(".symver sem_trywait,sem_trywait@" GLIBC_COMPAT_VER); +__asm__(".symver sem_destroy,sem_destroy@" GLIBC_COMPAT_VER); +__asm__(".symver shm_open,shm_open@" GLIBC_COMPAT_VER); +__asm__(".symver shm_unlink,shm_unlink@" GLIBC_COMPAT_VER); +__asm__(".symver pthread_sigmask,pthread_sigmask@" GLIBC_COMPAT_VER); +__asm__(".symver pthread_getattr_np,pthread_getattr_np@" GLIBC_COMPAT_VER); + +extern void *dlvsym(void *handle, const char *symbol, const char *version); +__asm__(".symver dlvsym,dlvsym@" GLIBC_COMPAT_VER); + +/* _GNU_SOURCE redirects strtol/strtoul/sscanf/fscanf to distinct __isoc23_* symbols; resolve the old ones by hand. */ + +static inline long +glibc_compat_strtol(const char *nptr, char **endptr, int base) +{ + long (*fn)(const char *, char **, int) = + (long (*)(const char *, char **, int)) dlvsym(NULL, "strtol", GLIBC_COMPAT_VER); + return fn ? fn(nptr, endptr, base) : 0; +} +#undef strtol +#define strtol(a, b, c) glibc_compat_strtol(a, b, c) + +static inline unsigned long +glibc_compat_strtoul(const char *nptr, char **endptr, int base) +{ + unsigned long (*fn)(const char *, char **, int) = + (unsigned long (*)(const char *, char **, int)) dlvsym(NULL, "strtoul", GLIBC_COMPAT_VER); + return fn ? fn(nptr, endptr, base) : 0; +} +#undef strtoul +#define strtoul(a, b, c) glibc_compat_strtoul(a, b, c) + +static inline int +glibc_compat_vsscanf(const char *str, const char *format, va_list ap) +{ + int (*fn)(const char *, const char *, va_list) = + (int (*)(const char *, const char *, va_list)) dlvsym(NULL, "vsscanf", GLIBC_COMPAT_VER); + return fn ? fn(str, format, ap) : -1; +} + +static inline int +glibc_compat_sscanf(const char *str, const char *format, ...) +{ + va_list ap; + int ret; + va_start(ap, format); + ret = glibc_compat_vsscanf(str, format, ap); + va_end(ap); + return ret; +} +#undef sscanf +#define sscanf(...) glibc_compat_sscanf(__VA_ARGS__) + +static inline int +glibc_compat_vfscanf(FILE *stream, const char *format, va_list ap) +{ + int (*fn)(FILE *, const char *, va_list) = + (int (*)(FILE *, const char *, va_list)) dlvsym(NULL, "vfscanf", GLIBC_COMPAT_VER); + return fn ? fn(stream, format, ap) : -1; +} + +static inline int +glibc_compat_fscanf(FILE *stream, const char *format, ...) +{ + va_list ap; + int ret; + va_start(ap, format); + ret = glibc_compat_vfscanf(stream, format, ap); + va_end(ap); + return ret; +} +#undef fscanf +#define fscanf(...) glibc_compat_fscanf(__VA_ARGS__) + +/* fcntl64 is a distinct symbol from fcntl (GLIBC_2.28, no older alias); call fcntl@2.17 instead, arg forwarded as long. */ + +static inline int +glibc_compat_fcntl(int fd, int cmd, ...) +{ + va_list ap; + long arg; + int (*fn)(int, int, long); + va_start(ap, cmd); + arg = va_arg(ap, long); + va_end(ap); + fn = (int (*)(int, int, long)) dlvsym(NULL, "fcntl", GLIBC_COMPAT_VER); + return fn ? fn(fd, cmd, arg) : -1; +} +#undef fcntl64 +#define fcntl64(...) glibc_compat_fcntl(__VA_ARGS__) +#undef fcntl +#define fcntl(...) glibc_compat_fcntl(__VA_ARGS__) + +/* stat/fstat/lstat moved to GLIBC_2.33; struct stat's layout didn't change on 64-bit archs, so __xstat@2.17 is equivalent (verified byte-for-byte on aarch64-linux). Version tag is 1 on x86_64, 0 elsewhere. */ + +#if defined(__x86_64__) +#define GLIBC_COMPAT_STAT_VER 1 +#else +#define GLIBC_COMPAT_STAT_VER 0 +#endif + +extern int __xstat(int ver, const char *path, struct stat *buf); +extern int __fxstat(int ver, int fd, struct stat *buf); +extern int __lxstat(int ver, const char *path, struct stat *buf); +__asm__(".symver __xstat,__xstat@" GLIBC_COMPAT_VER); +__asm__(".symver __fxstat,__fxstat@" GLIBC_COMPAT_VER); +__asm__(".symver __lxstat,__lxstat@" GLIBC_COMPAT_VER); + +#undef stat +#define stat(path, buf) __xstat(GLIBC_COMPAT_STAT_VER, path, buf) +#undef fstat +#define fstat(fd, buf) __fxstat(GLIBC_COMPAT_STAT_VER, fd, buf) +#undef lstat +#define lstat(path, buf) __lxstat(GLIBC_COMPAT_STAT_VER, path, buf) +#undef stat64 +#define stat64(path, buf) __xstat(GLIBC_COMPAT_STAT_VER, path, buf) +#undef fstat64 +#define fstat64(fd, buf) __fxstat(GLIBC_COMPAT_STAT_VER, fd, buf) +#undef lstat64 +#define lstat64(path, buf) __lxstat(GLIBC_COMPAT_STAT_VER, path, buf) + +/* arc4random family is GLIBC_2.36 with no older alias; forward straight to the kernel via getrandom (GLIBC_2.25). */ + +static inline void +glibc_compat_arc4random_buf(void *buf, size_t n) +{ + unsigned char *p = buf; + while (n > 0) + { + ssize_t r = getrandom(p, n, 0); + if (r <= 0) + continue; + p += r; + n -= (size_t) r; + } +} +#undef arc4random_buf +#define arc4random_buf(buf, n) glibc_compat_arc4random_buf(buf, n) + +static inline unsigned int +glibc_compat_arc4random(void) +{ + unsigned int v; + glibc_compat_arc4random_buf(&v, sizeof v); + return v; +} +#undef arc4random +#define arc4random() glibc_compat_arc4random() + +static inline unsigned int +glibc_compat_arc4random_uniform(unsigned int bound) +{ + unsigned int min, r; + if (bound < 2) + return 0; + min = -bound % bound; + do + r = glibc_compat_arc4random(); + while (r < min); + return r % bound; +} +#undef arc4random_uniform +#define arc4random_uniform(bound) glibc_compat_arc4random_uniform(bound) + +#endif /* __linux__ && __GLIBC__ */ + +#endif /* __ASSEMBLER__ */ + +#endif /* SUPABASE_GLIBC_COMPAT_SHIM_H */ diff --git a/nix/packages/packer.nix b/nix/packages/packer.nix index aa0d797c91..fece2c6879 100644 --- a/nix/packages/packer.nix +++ b/nix/packages/packer.nix @@ -21,6 +21,8 @@ buildGoModule rec { vendorHash = "sha256-F6hn+pXPyPe70UTK8EF24lk7ArYz7ygUyVVsatW6+hI="; + env.CGO_ENABLED = "0"; + subPackages = [ "." ]; ldflags = [ diff --git a/nix/packages/pg-backrest.nix b/nix/packages/pg-backrest.nix index 7cfff6c30f..6aff8842f8 100644 --- a/nix/packages/pg-backrest.nix +++ b/nix/packages/pg-backrest.nix @@ -8,6 +8,7 @@ pgbackrest.overrideAttrs ( finalAttrs: prevAttrs: { version = "2.59.1"; + NIX_CFLAGS_COMPILE = "-include ${../glibc-compat-shim.h}"; src = fetchFromGitHub { owner = "pgbackrest"; diff --git a/nix/packages/supascan.nix b/nix/packages/supascan.nix index 020d5ce50d..e7e4541d62 100644 --- a/nix/packages/supascan.nix +++ b/nix/packages/supascan.nix @@ -11,6 +11,7 @@ let hash = "sha256-xabGzCTzWwT8568xg6sdlE32OYPXlG9Fei0DoyAoXgo="; }; vendorHash = "sha256-BPW4nC9gxDbyhA5UOfFAtOIusNvwJ7pQiprZsqTiak0="; + env.CGO_ENABLED = "0"; }; # Audit specifications bundled as a package diff --git a/nix/pgbouncer.nix b/nix/pgbouncer.nix index 91e42c230d..c3395ef8e5 100644 --- a/nix/pgbouncer.nix +++ b/nix/pgbouncer.nix @@ -15,6 +15,7 @@ stdenv.mkDerivation rec { pname = "pgbouncer"; version = "1.25.1"; + NIX_CFLAGS_COMPILE = "-include ${./glibc-compat-shim.h}"; src = fetchurl { url = "https://www.pgbouncer.org/downloads/files/${version}/${pname}-${version}.tar.gz"; From 1f70b403d098467dce65dd4c0f77bedbdf5a1b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 6 Oct 2026 15:41:19 +0300 Subject: [PATCH 2/4] Revert unnecessary glibc remediation, repurpose for supautils/gatekeeper Everything previously here (shim wiring for orioledb, supabase-groonga, pgbouncer, pgbackrest; CGO_ENABLED=0 for goss, packer) addressed packages that turned out not to need a glibc floor: postgres core and every extension share one glibc from the same build closure, so glibc-version-check no longer checks them (see supabase/postgres#2437). Neither this nor the removed changes ever touched supautils or gatekeeper, the two packages that actually still fail the 2.31 floor (MPG-1326) since they're loaded outside that closure. Repurposing this branch to fix those instead. Refs: MPG-1326 --- nix/ext/orioledb.nix | 1 - nix/ext/pgroonga/groonga.nix | 1 - nix/glibc-compat-shim.h | 199 ----------------------------------- nix/packages/packer.nix | 2 - nix/packages/pg-backrest.nix | 1 - nix/packages/supascan.nix | 1 - nix/pgbouncer.nix | 1 - 7 files changed, 206 deletions(-) delete mode 100644 nix/glibc-compat-shim.h diff --git a/nix/ext/orioledb.nix b/nix/ext/orioledb.nix index 3f457d7637..ccbdc0cc7d 100644 --- a/nix/ext/orioledb.nix +++ b/nix/ext/orioledb.nix @@ -19,7 +19,6 @@ stdenv.mkDerivation rec { sha256 = "sha256-nLb3UHf2X+BFf5pXvUKW4LsSEtzmGy97Qw8rEkgewso="; }; version = "beta19"; - NIX_CFLAGS_COMPILE = "-include ${../glibc-compat-shim.h}"; buildInputs = [ curl libkrb5 diff --git a/nix/ext/pgroonga/groonga.nix b/nix/ext/pgroonga/groonga.nix index 45b9cb009e..c6d734db6c 100644 --- a/nix/ext/pgroonga/groonga.nix +++ b/nix/ext/pgroonga/groonga.nix @@ -23,7 +23,6 @@ stdenv.mkDerivation (finalAttrs: { pname = "supabase-groonga"; version = "14.0.5"; - NIX_CFLAGS_COMPILE = "-include ${../../glibc-compat-shim.h}"; src = fetchurl { url = "https://packages.groonga.org/source/groonga/groonga-${finalAttrs.version}.tar.gz"; hash = "sha256-y4UGnv8kK0z+br8wXpPf57NMXkdEJHcLCuTvYiubnIc="; diff --git a/nix/glibc-compat-shim.h b/nix/glibc-compat-shim.h deleted file mode 100644 index bea8c1bf3a..0000000000 --- a/nix/glibc-compat-shim.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef SUPABASE_GLIBC_COMPAT_SHIM_H -#define SUPABASE_GLIBC_COMPAT_SHIM_H - -/* -include forces this into .S files too, which the C bits below can't survive. */ -#ifndef __ASSEMBLER__ - -/* Must come before any system header: glibc locks in feature-test-macro visibility (e.g. GNU extensions) at first include. */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -/* Include order locks in __GLIBC__ and glibc's own inline atoi/atol before any override below exists. */ -#include -#include -#include -#include -#include -#include - -#if defined(__linux__) && defined(__GLIBC__) - -#define GLIBC_COMPAT_VER "GLIBC_2.17" - -__asm__(".symver dlopen,dlopen@" GLIBC_COMPAT_VER); -__asm__(".symver dlsym,dlsym@" GLIBC_COMPAT_VER); -__asm__(".symver dlerror,dlerror@" GLIBC_COMPAT_VER); -__asm__(".symver dlclose,dlclose@" GLIBC_COMPAT_VER); -__asm__(".symver sem_init,sem_init@" GLIBC_COMPAT_VER); -__asm__(".symver sem_wait,sem_wait@" GLIBC_COMPAT_VER); -__asm__(".symver sem_post,sem_post@" GLIBC_COMPAT_VER); -__asm__(".symver sem_trywait,sem_trywait@" GLIBC_COMPAT_VER); -__asm__(".symver sem_destroy,sem_destroy@" GLIBC_COMPAT_VER); -__asm__(".symver shm_open,shm_open@" GLIBC_COMPAT_VER); -__asm__(".symver shm_unlink,shm_unlink@" GLIBC_COMPAT_VER); -__asm__(".symver pthread_sigmask,pthread_sigmask@" GLIBC_COMPAT_VER); -__asm__(".symver pthread_getattr_np,pthread_getattr_np@" GLIBC_COMPAT_VER); - -extern void *dlvsym(void *handle, const char *symbol, const char *version); -__asm__(".symver dlvsym,dlvsym@" GLIBC_COMPAT_VER); - -/* _GNU_SOURCE redirects strtol/strtoul/sscanf/fscanf to distinct __isoc23_* symbols; resolve the old ones by hand. */ - -static inline long -glibc_compat_strtol(const char *nptr, char **endptr, int base) -{ - long (*fn)(const char *, char **, int) = - (long (*)(const char *, char **, int)) dlvsym(NULL, "strtol", GLIBC_COMPAT_VER); - return fn ? fn(nptr, endptr, base) : 0; -} -#undef strtol -#define strtol(a, b, c) glibc_compat_strtol(a, b, c) - -static inline unsigned long -glibc_compat_strtoul(const char *nptr, char **endptr, int base) -{ - unsigned long (*fn)(const char *, char **, int) = - (unsigned long (*)(const char *, char **, int)) dlvsym(NULL, "strtoul", GLIBC_COMPAT_VER); - return fn ? fn(nptr, endptr, base) : 0; -} -#undef strtoul -#define strtoul(a, b, c) glibc_compat_strtoul(a, b, c) - -static inline int -glibc_compat_vsscanf(const char *str, const char *format, va_list ap) -{ - int (*fn)(const char *, const char *, va_list) = - (int (*)(const char *, const char *, va_list)) dlvsym(NULL, "vsscanf", GLIBC_COMPAT_VER); - return fn ? fn(str, format, ap) : -1; -} - -static inline int -glibc_compat_sscanf(const char *str, const char *format, ...) -{ - va_list ap; - int ret; - va_start(ap, format); - ret = glibc_compat_vsscanf(str, format, ap); - va_end(ap); - return ret; -} -#undef sscanf -#define sscanf(...) glibc_compat_sscanf(__VA_ARGS__) - -static inline int -glibc_compat_vfscanf(FILE *stream, const char *format, va_list ap) -{ - int (*fn)(FILE *, const char *, va_list) = - (int (*)(FILE *, const char *, va_list)) dlvsym(NULL, "vfscanf", GLIBC_COMPAT_VER); - return fn ? fn(stream, format, ap) : -1; -} - -static inline int -glibc_compat_fscanf(FILE *stream, const char *format, ...) -{ - va_list ap; - int ret; - va_start(ap, format); - ret = glibc_compat_vfscanf(stream, format, ap); - va_end(ap); - return ret; -} -#undef fscanf -#define fscanf(...) glibc_compat_fscanf(__VA_ARGS__) - -/* fcntl64 is a distinct symbol from fcntl (GLIBC_2.28, no older alias); call fcntl@2.17 instead, arg forwarded as long. */ - -static inline int -glibc_compat_fcntl(int fd, int cmd, ...) -{ - va_list ap; - long arg; - int (*fn)(int, int, long); - va_start(ap, cmd); - arg = va_arg(ap, long); - va_end(ap); - fn = (int (*)(int, int, long)) dlvsym(NULL, "fcntl", GLIBC_COMPAT_VER); - return fn ? fn(fd, cmd, arg) : -1; -} -#undef fcntl64 -#define fcntl64(...) glibc_compat_fcntl(__VA_ARGS__) -#undef fcntl -#define fcntl(...) glibc_compat_fcntl(__VA_ARGS__) - -/* stat/fstat/lstat moved to GLIBC_2.33; struct stat's layout didn't change on 64-bit archs, so __xstat@2.17 is equivalent (verified byte-for-byte on aarch64-linux). Version tag is 1 on x86_64, 0 elsewhere. */ - -#if defined(__x86_64__) -#define GLIBC_COMPAT_STAT_VER 1 -#else -#define GLIBC_COMPAT_STAT_VER 0 -#endif - -extern int __xstat(int ver, const char *path, struct stat *buf); -extern int __fxstat(int ver, int fd, struct stat *buf); -extern int __lxstat(int ver, const char *path, struct stat *buf); -__asm__(".symver __xstat,__xstat@" GLIBC_COMPAT_VER); -__asm__(".symver __fxstat,__fxstat@" GLIBC_COMPAT_VER); -__asm__(".symver __lxstat,__lxstat@" GLIBC_COMPAT_VER); - -#undef stat -#define stat(path, buf) __xstat(GLIBC_COMPAT_STAT_VER, path, buf) -#undef fstat -#define fstat(fd, buf) __fxstat(GLIBC_COMPAT_STAT_VER, fd, buf) -#undef lstat -#define lstat(path, buf) __lxstat(GLIBC_COMPAT_STAT_VER, path, buf) -#undef stat64 -#define stat64(path, buf) __xstat(GLIBC_COMPAT_STAT_VER, path, buf) -#undef fstat64 -#define fstat64(fd, buf) __fxstat(GLIBC_COMPAT_STAT_VER, fd, buf) -#undef lstat64 -#define lstat64(path, buf) __lxstat(GLIBC_COMPAT_STAT_VER, path, buf) - -/* arc4random family is GLIBC_2.36 with no older alias; forward straight to the kernel via getrandom (GLIBC_2.25). */ - -static inline void -glibc_compat_arc4random_buf(void *buf, size_t n) -{ - unsigned char *p = buf; - while (n > 0) - { - ssize_t r = getrandom(p, n, 0); - if (r <= 0) - continue; - p += r; - n -= (size_t) r; - } -} -#undef arc4random_buf -#define arc4random_buf(buf, n) glibc_compat_arc4random_buf(buf, n) - -static inline unsigned int -glibc_compat_arc4random(void) -{ - unsigned int v; - glibc_compat_arc4random_buf(&v, sizeof v); - return v; -} -#undef arc4random -#define arc4random() glibc_compat_arc4random() - -static inline unsigned int -glibc_compat_arc4random_uniform(unsigned int bound) -{ - unsigned int min, r; - if (bound < 2) - return 0; - min = -bound % bound; - do - r = glibc_compat_arc4random(); - while (r < min); - return r % bound; -} -#undef arc4random_uniform -#define arc4random_uniform(bound) glibc_compat_arc4random_uniform(bound) - -#endif /* __linux__ && __GLIBC__ */ - -#endif /* __ASSEMBLER__ */ - -#endif /* SUPABASE_GLIBC_COMPAT_SHIM_H */ diff --git a/nix/packages/packer.nix b/nix/packages/packer.nix index fece2c6879..aa0d797c91 100644 --- a/nix/packages/packer.nix +++ b/nix/packages/packer.nix @@ -21,8 +21,6 @@ buildGoModule rec { vendorHash = "sha256-F6hn+pXPyPe70UTK8EF24lk7ArYz7ygUyVVsatW6+hI="; - env.CGO_ENABLED = "0"; - subPackages = [ "." ]; ldflags = [ diff --git a/nix/packages/pg-backrest.nix b/nix/packages/pg-backrest.nix index 6aff8842f8..7cfff6c30f 100644 --- a/nix/packages/pg-backrest.nix +++ b/nix/packages/pg-backrest.nix @@ -8,7 +8,6 @@ pgbackrest.overrideAttrs ( finalAttrs: prevAttrs: { version = "2.59.1"; - NIX_CFLAGS_COMPILE = "-include ${../glibc-compat-shim.h}"; src = fetchFromGitHub { owner = "pgbackrest"; diff --git a/nix/packages/supascan.nix b/nix/packages/supascan.nix index e7e4541d62..020d5ce50d 100644 --- a/nix/packages/supascan.nix +++ b/nix/packages/supascan.nix @@ -11,7 +11,6 @@ let hash = "sha256-xabGzCTzWwT8568xg6sdlE32OYPXlG9Fei0DoyAoXgo="; }; vendorHash = "sha256-BPW4nC9gxDbyhA5UOfFAtOIusNvwJ7pQiprZsqTiak0="; - env.CGO_ENABLED = "0"; }; # Audit specifications bundled as a package diff --git a/nix/pgbouncer.nix b/nix/pgbouncer.nix index c3395ef8e5..91e42c230d 100644 --- a/nix/pgbouncer.nix +++ b/nix/pgbouncer.nix @@ -15,7 +15,6 @@ stdenv.mkDerivation rec { pname = "pgbouncer"; version = "1.25.1"; - NIX_CFLAGS_COMPILE = "-include ${./glibc-compat-shim.h}"; src = fetchurl { url = "https://www.pgbouncer.org/downloads/files/${version}/${pname}-${version}.tar.gz"; From cb40f36a930a9d7e121a7b5e529b1dad20483185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Tue, 6 Oct 2026 15:48:40 +0300 Subject: [PATCH 3/4] fix(ext): pin supautils's stat() to GLIBC_2.2.5/2.17 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit extension_custom_scripts.c calls stat() directly, which resolves to GLIBC_2.33 (y2038 refactor) — above supautils's compat floor for legacy pre-nix hosts. struct stat's layout didn't change on 64-bit archs, so __xstat@ is equivalent (same approach already used for atoi/strtol in this same patch, same compat version per arch). Verified: supautils.so's max glibc requirement drops from 2.33 to 2.17 on aarch64-linux (built, linked, and checked against the real 2.31 floor — passes). x86_64's GLIBC_2.2.5 branch mirrors the existing atoi fix's own per-arch structure and is confirmed to exist in glibc's symbol table, but no x86_64-linux builder was available to build/link it here — worth confirming in CI. Refs: MPG-1326 --- .../supautils-strtol-glibc-compat.patch | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/nix/ext/patches/supautils-strtol-glibc-compat.patch b/nix/ext/patches/supautils-strtol-glibc-compat.patch index 06f846b91f..8c36e613d9 100644 --- a/nix/ext/patches/supautils-strtol-glibc-compat.patch +++ b/nix/ext/patches/supautils-strtol-glibc-compat.patch @@ -26,4 +26,31 @@ index 18e5aee..cdfb63f 100644 + static JSON_ACTION_RETURN_TYPE json_array_start(void *state) { json_constrained_extension_parse_state *parse = state; + +diff --git a/src/extension_custom_scripts.c b/src/extension_custom_scripts.c +index 337bd69..3f285cc 100644 +--- a/src/extension_custom_scripts.c ++++ b/src/extension_custom_scripts.c +@@ -2,6 +2,22 @@ + #include + #include + ++#if defined(__linux__) && defined(__GLIBC__) && (defined(__x86_64__) || defined(__aarch64__)) ++# if defined(__x86_64__) ++# define SUPAUTILS_STAT_COMPAT_VER "GLIBC_2.2.5" ++# define SUPAUTILS_STAT_VER 1 ++# else ++# define SUPAUTILS_STAT_COMPAT_VER "GLIBC_2.17" ++# define SUPAUTILS_STAT_VER 0 ++# endif ++extern int __xstat(int ver, const char *path, struct stat *buf); ++__asm__(".symver __xstat,__xstat@" SUPAUTILS_STAT_COMPAT_VER); ++#undef stat ++#define stat(path, buf) __xstat(SUPAUTILS_STAT_VER, path, buf) ++#undef stat64 ++#define stat64(path, buf) __xstat(SUPAUTILS_STAT_VER, path, buf) ++#endif ++ + // Prevent recursively running custom scripts + static bool running_custom_script = false; From 98d9f2dd82b9efebea564cc611f0024801420976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20Boros?= Date: Fri, 9 Oct 2026 10:00:28 +0300 Subject: [PATCH 4/4] docs(ext): note removal condition for supautils glibc compat patch Refs: MPG-1326 --- nix/ext/supautils.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/ext/supautils.nix b/nix/ext/supautils.nix index 5712df47a5..aff35bf9bc 100644 --- a/nix/ext/supautils.nix +++ b/nix/ext/supautils.nix @@ -24,6 +24,7 @@ stdenv.mkDerivation rec { hash = "sha256-Wsou5U7/Tuwj2E6aPEmlHg7uz7kGyBOGrb7UkjfEo9U="; }; + # remove once all Ubuntu 20.04 (glibc 2.31) hosts are decommissioned patches = [ ./patches/supautils-strtol-glibc-compat.patch ]; installPhase = ''