Skip to content

SIGSEGV in backend when authenticator role (supautils+safeupdate preloaded) hits a denied-EXECUTE call #2495

Description

@sindhiim

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)

  1. CREATE FUNCTION test_trivial() RETURNS int LANGUAGE sql AS $$ SELECT 1 $$;
  2. REVOKE EXECUTE ON FUNCTION test_trivial() FROM <role>; (schema USAGE still granted)
  3. Connect as authenticator (session_preload_libraries = 'supautils, safeupdate'),
    SET ROLE anon; (or any role denied EXECUTE on the function)
  4. SELECT test_trivial();
  5. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions