Skip to content

SIGSEGV on function EXECUTE permission denial when a superuser session has SET ROLE (17.6.1.106; clean on 17.6.1.071) #2409

Description

@ACRamirez1

Description

On supabase/postgres:17.6.1.106 a function EXECUTE permission denial raises SIGSEGV and takes down the whole postmaster (all server processes terminated; reinitializing), instead of returning 42501 permission denied for function.

supabase/postgres:17.6.1.071 returns the error cleanly. Both images report server_version = 17.6, so this is an image-build regression rather than a Postgres version difference.

This breaks any pgTAP suite that asserts a function is not executable by a given role, because supabase test db connects as the superuser postgres.

Reproduction

Against a stock supabase start on an affected image:

CREATE FUNCTION public.zz_t() RETURNS boolean LANGUAGE sql STABLE SECURITY DEFINER AS 'SELECT true';
REVOKE ALL ON FUNCTION public.zz_t() FROM PUBLIC, anon;
BEGIN; SET LOCAL ROLE anon; SELECT public.zz_t(); COMMIT;

Result:

server closed the connection unexpectedly
	This probably means the server terminated abnormally
	before or while processing the request.

Postmaster log:

LOG:  server process (PID 370) was terminated by signal 11: Segmentation fault
LOG:  all server processes terminated; reinitializing
LOG:  database system was not properly shut down; automatic recovery in progress

Conditions required

All three must hold. Removing any one gives a clean ERROR: permission denied for function:

  1. The login role is a superuser (postgres). A non-superuser login is unaffected — connecting as authenticator and doing SET ROLE anon returns the error cleanly, which is why PostgREST traffic does not trigger it.
  2. The role has been switched via SET ROLE or SET LOCAL ROLE.
  3. The denial is on a FUNCTION. A table permission denial (permission denied for table) under identical conditions is clean.

Also reproduces with SET ROLE (not just SET LOCAL ROLE), and with authenticated as well as anon, so it is not role-specific. Still crashes with SET pgaudit.log = 'none', so it does not appear to be pgaudit's logging path.

Affected / unaffected

Image server_version Result
public.ecr.aws/supabase/postgres:17.6.1.071 (Supabase CLI 2.72.7) 17.6 clean ERROR: permission denied for function
public.ecr.aws/supabase/postgres:17.6.1.106 (Supabase CLI 2.98.2) 17.6 SIGSEGV

shared_preload_libraries on the affected image: pg_stat_statements, pgaudit, plpgsql, plpgsql_check, pg_cron, pg_net, pgsodium, auto_explain, pg_tle, plan_filter, supabase_vault

Impact

Production traffic through PostgREST is unaffected (it logs in as the non-superuser authenticator) — verified with live anon-key HTTP calls, which return 401 42501 with the server staying up. The practical impact is on local/CI testing: any pgTAP assertion that a role cannot execute a function crashes the database, since supabase test db connects as postgres.

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