aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc
diff options
context:
space:
mode:
authorNathan Bossart <nathan@postgresql.org>2024-07-09 13:03:40 -0500
committerNathan Bossart <nathan@postgresql.org>2024-07-09 13:03:40 -0500
commitccd38024bc3c61e62af2097d408a670661713e68 (patch)
treefb66df8f4e9f7652c9c914811633d03f8641f29d /src/backend/storage/ipc
parent629520be5f9da9d0192c7f6c8796bfddb4746760 (diff)
downloadpostgresql-ccd38024bc3c61e62af2097d408a670661713e68.tar.gz
postgresql-ccd38024bc3c61e62af2097d408a670661713e68.zip
Introduce pg_signal_autovacuum_worker.
Since commit 3a9b18b309, roles with privileges of pg_signal_backend cannot signal autovacuum workers. Many users treated the ability to signal autovacuum workers as a feature instead of a bug, so we are reintroducing it via a new predefined role. Having privileges of this new role, named pg_signal_autovacuum_worker, only permits signaling autovacuum workers. It does not permit signaling other types of superuser backends. Bumps catversion. Author: Kirill Reshke Reviewed-by: Anthony Leung, Michael Paquier, Andrey Borodin Discussion: https://postgr.es/m/CALdSSPhC4GGmbnugHfB9G0%3DfAxjCSug_-rmL9oUh0LTxsyBfsg%40mail.gmail.com
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r--src/backend/storage/ipc/signalfuncs.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c
index 88e9bf8125d..aa729a36e39 100644
--- a/src/backend/storage/ipc/signalfuncs.c
+++ b/src/backend/storage/ipc/signalfuncs.c
@@ -34,8 +34,9 @@
* role as the backend being signaled. For "dangerous" signals, an explicit
* check for superuser needs to be done prior to calling this function.
*
- * Returns 0 on success, 1 on general failure, 2 on normal permission error
- * and 3 if the caller needs to be a superuser.
+ * Returns 0 on success, 1 on general failure, 2 on normal permission error,
+ * 3 if the caller needs to be a superuser, and 4 if the caller needs to have
+ * privileges of pg_signal_autovacuum_worker.
*
* In the event of a general failure (return code 1), a warning message will
* be emitted. For permission errors, doing that is the responsibility of
@@ -45,6 +46,7 @@
#define SIGNAL_BACKEND_ERROR 1
#define SIGNAL_BACKEND_NOPERMISSION 2
#define SIGNAL_BACKEND_NOSUPERUSER 3
+#define SIGNAL_BACKEND_NOAUTOVAC 4
static int
pg_signal_backend(int pid, int sig)
{
@@ -77,15 +79,27 @@ pg_signal_backend(int pid, int sig)
/*
* 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.
+ * backend, so treat it that way. As an exception, we allow roles with
+ * privileges of pg_signal_autovacuum_worker to signal autovacuum workers
+ * (which do not advertise a role).
+ *
+ * Otherwise, users can signal backends for roles they have privileges of.
*/
- if ((!OidIsValid(proc->roleId) || superuser_arg(proc->roleId)) &&
- !superuser())
- return SIGNAL_BACKEND_NOSUPERUSER;
+ if (!OidIsValid(proc->roleId) || superuser_arg(proc->roleId))
+ {
+ ProcNumber procNumber = GetNumberFromPGProc(proc);
+ PgBackendStatus *procStatus = pgstat_get_beentry_by_proc_number(procNumber);
- /* Users can signal backends they have role membership in. */
- if (!has_privs_of_role(GetUserId(), proc->roleId) &&
- !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
+ if (procStatus && procStatus->st_backendType == B_AUTOVAC_WORKER)
+ {
+ if (!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_AUTOVACUUM_WORKER))
+ return SIGNAL_BACKEND_NOAUTOVAC;
+ }
+ else if (!superuser())
+ return SIGNAL_BACKEND_NOSUPERUSER;
+ }
+ else if (!has_privs_of_role(GetUserId(), proc->roleId) &&
+ !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
return SIGNAL_BACKEND_NOPERMISSION;
/*
@@ -130,6 +144,13 @@ pg_cancel_backend(PG_FUNCTION_ARGS)
errdetail("Only roles with the %s attribute may cancel queries of roles with the %s attribute.",
"SUPERUSER", "SUPERUSER")));
+ if (r == SIGNAL_BACKEND_NOAUTOVAC)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied to cancel query"),
+ errdetail("Only roles with privileges of the \"%s\" role may cancel autovacuum workers.",
+ "pg_signal_autovacuum_worker")));
+
if (r == SIGNAL_BACKEND_NOPERMISSION)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -236,6 +257,13 @@ pg_terminate_backend(PG_FUNCTION_ARGS)
errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
"SUPERUSER", "SUPERUSER")));
+ if (r == SIGNAL_BACKEND_NOAUTOVAC)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied to terminate process"),
+ errdetail("Only roles with privileges of the \"%s\" role may terminate autovacuum workers.",
+ "pg_signal_autovacuum_worker")));
+
if (r == SIGNAL_BACKEND_NOPERMISSION)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),