Bug report
Calling a function you've been denied EXECUTE on crashes the backend connection
with SIGSEGV instead of returning a clean 42501, when the connecting role has
BOTH supautils and safeupdate in session_preload_libraries — exactly the
authenticator role's default configuration, i.e. what PostgREST uses for
every request via SET ROLE anon/authenticated.
Environment
- Local Supabase CLI stack (
supabase start), Postgres 17.6
- Nix-packaged build:
.../postgresql-and-plugins-17.6/bin/.postgres-wrapped
Reproduction (isolated, trivial function, no app logic involved)
CREATE FUNCTION test_trivial() RETURNS int LANGUAGE sql AS $$ SELECT 1 $$;
REVOKE EXECUTE ON FUNCTION test_trivial() FROM <role>; (schema USAGE still granted)
- Connect as
authenticator (session_preload_libraries = 'supautils, safeupdate'),
SET ROLE anon; (or any role denied EXECUTE on the function)
SELECT test_trivial();
- Connection dies instantly: "Connection terminated unexpectedly" client-side.
Isolation results
supautils alone preloaded, same denied call → clean 42501, no crash.
safeupdate alone preloaded, same denied call → clean 42501, no crash.
- Both together (matching
authenticator's real config) → SIGSEGV, 100% reproducible
on the first call, regardless of function body (tested plain SQL and SECURITY
DEFINER; not specific to either).
Server-side evidence
dmesg inside the container shows, identically on every occurrence:
segfault at 0 ip <consistent offset> sp ... error 4 in .postgres-wrapped[...]
.postgres-wrapped: potentially unexpected fatal signal 11.
segfault at 0 = NULL-pointer dereference. pg_postmaster_start_time() is
unchanged across every crash — only the individual backend dies, not postmaster.
Ruled out OOM: host VM had 8.8GB free, zero OOM-killer lines in dmesg across the
whole session.
Why this matters
authenticator's preload-library combination is presumably the Supabase default
across all projects. Any real PostgREST request that correctly gets EXECUTE-denied
(a perfectly normal authorization outcome, not misconfiguration) will crash the
backend instead of returning 403, on any project using this default.
Happy to provide the full investigation transcript or test further if useful.
Bug report
Calling a function you've been denied EXECUTE on crashes the backend connection
with SIGSEGV instead of returning a clean 42501, when the connecting role has
BOTH
supautilsandsafeupdateinsession_preload_libraries— exactly theauthenticatorrole's default configuration, i.e. what PostgREST uses forevery request via
SET ROLE anon/authenticated.Environment
supabase start), Postgres 17.6.../postgresql-and-plugins-17.6/bin/.postgres-wrappedReproduction (isolated, trivial function, no app logic involved)
CREATE FUNCTION test_trivial() RETURNS int LANGUAGE sql AS $$ SELECT 1 $$;REVOKE EXECUTE ON FUNCTION test_trivial() FROM <role>;(schema USAGE still granted)authenticator(session_preload_libraries = 'supautils, safeupdate'),SET ROLE anon;(or any role denied EXECUTE on the function)SELECT test_trivial();Isolation results
supautilsalone preloaded, same denied call → clean42501, no crash.safeupdatealone preloaded, same denied call → clean42501, no crash.authenticator's real config) → SIGSEGV, 100% reproducibleon the first call, regardless of function body (tested plain SQL and SECURITY
DEFINER; not specific to either).
Server-side evidence
dmesginside the container shows, identically on every occurrence:segfault at 0= NULL-pointer dereference.pg_postmaster_start_time()isunchanged across every crash — only the individual backend dies, not postmaster.
Ruled out OOM: host VM had 8.8GB free, zero OOM-killer lines in dmesg across the
whole session.
Why this matters
authenticator's preload-library combination is presumably the Supabase defaultacross all projects. Any real PostgREST request that correctly gets EXECUTE-denied
(a perfectly normal authorization outcome, not misconfiguration) will crash the
backend instead of returning 403, on any project using this default.
Happy to provide the full investigation transcript or test further if useful.