Skip to content

Commit 3a9b18b

Browse files
committed
Ban role pg_signal_backend from more superuser backend types.
Documentation says it cannot signal "a backend owned by a superuser". On the contrary, it could signal background workers, including the logical replication launcher. It could signal autovacuum workers and the autovacuum launcher. Block all that. Signaling autovacuum workers and those two launchers doesn't stall progress beyond what one could achieve other ways. If a cluster uses a non-core extension with a background worker that does not auto-restart, this could create a denial of service with respect to that background worker. A background worker with bugs in its code for responding to terminations or cancellations could experience those bugs at a time the pg_signal_backend member chooses. Back-patch to v11 (all supported versions). Reviewed by Jelte Fennema-Nio. Reported by Hemanth Sandrana and Mahendrakar Srinivasarao. Security: CVE-2023-5870
1 parent 526fe0d commit 3a9b18b

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

src/backend/storage/ipc/signalfuncs.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,13 @@ pg_signal_backend(int pid, int sig)
7474
return SIGNAL_BACKEND_ERROR;
7575
}
7676

77-
/* Only allow superusers to signal superuser-owned backends. */
78-
if (superuser_arg(proc->roleId) && !superuser())
77+
/*
78+
* Only allow superusers to signal superuser-owned backends. Any process
79+
* not advertising a role might have the importance of a superuser-owned
80+
* backend, so treat it that way.
81+
*/
82+
if ((!OidIsValid(proc->roleId) || superuser_arg(proc->roleId)) &&
83+
!superuser())
7984
return SIGNAL_BACKEND_NOSUPERUSER;
8085

8186
/* Users can signal backends they have role membership in. */

src/test/regress/expected/privileges.out

+18
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,24 @@ SELECT * FROM pg_largeobject LIMIT 0;
20832083
SET SESSION AUTHORIZATION regress_priv_user1;
20842084
SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
20852085
ERROR: permission denied for table pg_largeobject
2086+
-- pg_signal_backend can't signal superusers
2087+
RESET SESSION AUTHORIZATION;
2088+
BEGIN;
2089+
CREATE OR REPLACE FUNCTION terminate_nothrow(pid int) RETURNS bool
2090+
LANGUAGE plpgsql SECURITY DEFINER SET client_min_messages = error AS $$
2091+
BEGIN
2092+
RETURN pg_terminate_backend($1);
2093+
EXCEPTION WHEN OTHERS THEN
2094+
RETURN false;
2095+
END$$;
2096+
ALTER FUNCTION terminate_nothrow OWNER TO pg_signal_backend;
2097+
SELECT backend_type FROM pg_stat_activity
2098+
WHERE CASE WHEN COALESCE(usesysid, 10) = 10 THEN terminate_nothrow(pid) END;
2099+
backend_type
2100+
--------------
2101+
(0 rows)
2102+
2103+
ROLLBACK;
20862104
-- test pg_database_owner
20872105
RESET SESSION AUTHORIZATION;
20882106
GRANT pg_database_owner TO regress_priv_user1;

src/test/regress/sql/privileges.sql

+15
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,21 @@ SELECT * FROM pg_largeobject LIMIT 0;
13491349
SET SESSION AUTHORIZATION regress_priv_user1;
13501350
SELECT * FROM pg_largeobject LIMIT 0; -- to be denied
13511351

1352+
-- pg_signal_backend can't signal superusers
1353+
RESET SESSION AUTHORIZATION;
1354+
BEGIN;
1355+
CREATE OR REPLACE FUNCTION terminate_nothrow(pid int) RETURNS bool
1356+
LANGUAGE plpgsql SECURITY DEFINER SET client_min_messages = error AS $$
1357+
BEGIN
1358+
RETURN pg_terminate_backend($1);
1359+
EXCEPTION WHEN OTHERS THEN
1360+
RETURN false;
1361+
END$$;
1362+
ALTER FUNCTION terminate_nothrow OWNER TO pg_signal_backend;
1363+
SELECT backend_type FROM pg_stat_activity
1364+
WHERE CASE WHEN COALESCE(usesysid, 10) = 10 THEN terminate_nothrow(pid) END;
1365+
ROLLBACK;
1366+
13521367
-- test pg_database_owner
13531368
RESET SESSION AUTHORIZATION;
13541369
GRANT pg_database_owner TO regress_priv_user1;

0 commit comments

Comments
 (0)