Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 8 additions & 29 deletions src/backend/storage/ipc/signalfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ static int
pg_signal_backend(int pid, int sig, char *msg)
{
PGPROC *proc = BackendPidGetProc(pid);
LocalPgBackendStatus *local_beentry;

/*
* BackendPidGetProc returns NULL if the pid isn't valid; but by the time
Expand All @@ -73,34 +72,14 @@ pg_signal_backend(int pid, int sig, char *msg)
return SIGNAL_BACKEND_ERROR;
}

local_beentry = pgstat_fetch_stat_local_beentry_by_pid(pid);

/* Only allow superusers to signal superuser-owned backends. */
if (superuser_arg(proc->roleId) && !superuser())
{
Oid role;
char * appname;

if (local_beentry == NULL) {
return SIGNAL_BACKEND_NOSUPERUSER;
}

role = get_role_oid("mdb_admin", true /*if nodoby created mdb_admin role in this database*/);
appname = local_beentry->backendStatus.st_appname;

// only allow mdb_admin to kill su queries
if (!is_member_of_role(GetUserId(), role)) {
return SIGNAL_BACKEND_NOSUPERUSER;
}

if (local_beentry->backendStatus.st_backendType == B_AUTOVAC_WORKER) {
// ok
} else if (appname != NULL && strcmp(appname, "MDB") == 0) {
// ok
} else {
return SIGNAL_BACKEND_NOSUPERUSER;
}
}
/*
* Only allow superusers to signal superuser-owned backends. Any process
* not advertising a role might have the importance of a superuser-owned
* backend, so treat it that way.
*/
if ((!OidIsValid(proc->roleId) || superuser_arg(proc->roleId)) &&
!superuser())
return SIGNAL_BACKEND_NOSUPERUSER;

/* Users can signal backends they have role membership in. */
if (!has_privs_of_role(GetUserId(), proc->roleId) &&
Expand Down
18 changes: 18 additions & 0 deletions src/test/regress/expected/privileges.out
Original file line number Diff line number Diff line change
Expand Up @@ -1986,6 +1986,24 @@ TABLE information_schema.enabled_roles;

INSERT INTO datdba_only DEFAULT VALUES;
ERROR: permission denied for table datdba_only
ROLLBACK;
-- pg_signal_backend can't signal superusers
RESET SESSION AUTHORIZATION;
BEGIN;
CREATE OR REPLACE FUNCTION terminate_nothrow(pid int) RETURNS bool
LANGUAGE plpgsql SECURITY DEFINER SET client_min_messages = error AS $$
BEGIN
RETURN pg_terminate_backend($1);
EXCEPTION WHEN OTHERS THEN
RETURN false;
END$$;
ALTER FUNCTION terminate_nothrow OWNER TO pg_signal_backend;
SELECT backend_type FROM pg_stat_activity
WHERE CASE WHEN COALESCE(usesysid, 10) = 10 THEN terminate_nothrow(pid) END;
backend_type
--------------
(0 rows)

ROLLBACK;
-- test default ACLs
\c -
Expand Down
15 changes: 15 additions & 0 deletions src/test/regress/sql/privileges.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,21 @@ TABLE information_schema.enabled_roles;
INSERT INTO datdba_only DEFAULT VALUES;
ROLLBACK;

-- pg_signal_backend can't signal superusers
RESET SESSION AUTHORIZATION;
BEGIN;
CREATE OR REPLACE FUNCTION terminate_nothrow(pid int) RETURNS bool
LANGUAGE plpgsql SECURITY DEFINER SET client_min_messages = error AS $$
BEGIN
RETURN pg_terminate_backend($1);
EXCEPTION WHEN OTHERS THEN
RETURN false;
END$$;
ALTER FUNCTION terminate_nothrow OWNER TO pg_signal_backend;
SELECT backend_type FROM pg_stat_activity
WHERE CASE WHEN COALESCE(usesysid, 10) = 10 THEN terminate_nothrow(pid) END;
ROLLBACK;

-- test default ACLs
\c -

Expand Down
Loading