Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sHV8m-008KQv-3i for pgsql-hackers@arkaria.postgresql.org; Wed, 12 Jun 2024 21:04:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sHV8j-0075Y9-FC for pgsql-hackers@arkaria.postgresql.org; Wed, 12 Jun 2024 21:04:18 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sHV8i-0075Y0-SQ for pgsql-hackers@lists.postgresql.org; Wed, 12 Jun 2024 21:04:17 +0000 Received: from mail-io1-xd2a.google.com ([2607:f8b0:4864:20::d2a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sHV8c-0010vh-7R for pgsql-hackers@postgresql.org; Wed, 12 Jun 2024 21:04:16 +0000 Received: by mail-io1-xd2a.google.com with SMTP id ca18e2360f4ac-7eb01106015so9553539f.1 for ; Wed, 12 Jun 2024 14:04:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718226249; x=1718831049; darn=postgresql.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=ut380FdXmqd62zbkyE2SHrdJ0CIgOp+dREzGtvJX3xo=; b=hj12R7zdIfGgOwylEtsjJEJQpNT+pRlkeEIBSVn7ghwXyLoftb0E8pnCJRTGmyoref Re9LwLv6fKyM6u7VIPAHUfzEOwO1CpfgJciOTIhhJvsJi/NvdwOpY83AuDWX3TWXsVZY wTmcl6gDkVUn2ROzeV9+/y+YRE+epc7zH0ifDRqPRjpfCAjAuyCDL6ftLEWHSNyc3alA pPCaVkWNv4vDMZ7Smj3RMOzeRkckIITCaWfzrBeeRwB+bUXZJlzrR53w84FhqiHeu7No m5jcwk6jI1nDFoDXylMN8vLJ+4oaMWJ6xj/4y5P9KPHtGp+xI762D+zYVFiUy8+TiZ7Z 5cNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718226249; x=1718831049; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ut380FdXmqd62zbkyE2SHrdJ0CIgOp+dREzGtvJX3xo=; b=vxuOB/A6T1eKmjH73ebOdBILgkL8ZE6eFQmFxUShi0MwdvwBdfSoqQxGgWje2kYVno P8o1/PTanRykF09G4b3Zx2akbbycjtSYNcBjBcd+6Hyk+vOGlhaoBRvyAYsWUvawH1Te sb5cGfRTxt/hDp5oth5B+p1QfGUuP1NP95bycdD3eWI6iht6vgG/8grloj2RbZo5kj/x hqADW78Y2a2Eop8odXNO7H3L0xiyMvZN32BQCbqUmMnDABLEhRJn4bzElgfm6KPxLNzH Aw/xRkoKpKRPPW2C2TNHxtJ4oyze4petUC6/n2Q5X64hQ5XwyYkyhmlo+gZLQhZg59Rd v1Tg== X-Forwarded-Encrypted: i=1; AJvYcCU8ybjEcq3Sn7tKaTmn4K7VMx4OikgGxtb9uQL/9AQytJMJPcdl9bRDEENIcyAW8aZuqEQY8RMEW9S2B/MB2DA0bOSNUiVf2tAEArf6 X-Gm-Message-State: AOJu0YxlTv5nHhrGKHXTsTHw4F4ELRGpMuYuuNnfNsauA7OQwk4t1s8I m0FODHUVUErHL1Gl66RXNplnqaybX6C86gAmOqvzNl278vMdpIQ1 X-Google-Smtp-Source: AGHT+IGVWVeJ2YnBHYwaDqqkCH6dANhcYyiTb3f+zsnux45wk/jnKlXfXe+9CijhFY579IU6cCzSGg== X-Received: by 2002:a05:6602:641f:b0:7eb:7df7:461c with SMTP id ca18e2360f4ac-7ebcd19d897mr379090339f.21.1718226249250; Wed, 12 Jun 2024 14:04:09 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id ca18e2360f4ac-7eb814ff700sm188396039f.52.2024.06.12.14.04.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 12 Jun 2024 14:04:08 -0700 (PDT) Date: Wed, 12 Jun 2024 16:04:06 -0500 From: Nathan Bossart To: Michael Paquier Cc: Kirill Reshke , "Leung, Anthony" , "Andrey M. Borodin" , "pgsql-hackers@postgresql.org" Subject: Re: Allow non-superuser to cancel superuser tasks. Message-ID: References: <20240410150034.GA1673069@nathanxps13> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="8o9oIr3uRRuBRCEH" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --8o9oIr3uRRuBRCEH Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I adjusted 0001 based on my upthread feedback. -- nathan --8o9oIr3uRRuBRCEH Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v5-0001-Introduce-pg_signal_autovacuum_worker.patch" From 118f95346fcf8099ab28d2f9186185171e3b88af Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 12 Jun 2024 15:38:14 -0500 Subject: [PATCH v5 1/1] 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. Author: Kirill Reshke Reviewed-by: Anthony Leung, Michael Paquier Discussion: https://postgr.es/m/CALdSSPhC4GGmbnugHfB9G0%3DfAxjCSug_-rmL9oUh0LTxsyBfsg%40mail.gmail.com --- doc/src/sgml/func.sgml | 8 +++-- doc/src/sgml/user-manag.sgml | 5 +++ src/backend/storage/ipc/signalfuncs.c | 46 +++++++++++++++++++++------ src/include/catalog/pg_authid.dat | 5 +++ 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 17c44bc338..7d5b7acb68 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -28037,7 +28037,9 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); Cancels the current query of the session whose backend process has the specified process ID. This is also allowed if the - calling role is a member of the role whose backend is being canceled or + calling role has privileges of the role whose backend is being canceled, + the backend process is an autovacuum worker and the calling role has + privileges of pg_signal_autovacuum_worker, or the calling role has privileges of pg_signal_backend, however only superusers can cancel superuser backends. @@ -28111,7 +28113,9 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); Terminates the session whose backend process has the specified process ID. This is also allowed if the calling role - is a member of the role whose backend is being terminated or the + has privileges of the role whose backend is being terminated, + the backend process is an autovacuum worker and the calling role has + privileges of pg_signal_autovacuum_worker, or the calling role has privileges of pg_signal_backend, however only superusers can terminate superuser backends. diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 07a16247d7..340cefff70 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -661,6 +661,11 @@ DROP ROLE doomed_role; pg_signal_backend Signal another backend to cancel a query or terminate its session. + + pg_signal_autovacuum_worker + Signal an autovacuum worker to cancel the current table's vacuum + or terminate its session. + pg_read_server_files Allow reading files from any location the database can access on the server with COPY and diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c index 88e9bf8125..780a1c682a 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 queries of 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 worker processes.", + "pg_signal_autovacuum_worker"))); + if (r == SIGNAL_BACKEND_NOPERMISSION) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat index bf00815c14..0129f67eaa 100644 --- a/src/include/catalog/pg_authid.dat +++ b/src/include/catalog/pg_authid.dat @@ -99,5 +99,10 @@ rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f', rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1', rolpassword => '_null_', rolvaliduntil => '_null_' }, +{ oid => '8916', oid_symbol => 'ROLE_PG_SIGNAL_AUTOVACUUM_WORKER', + rolname => 'pg_signal_autovacuum_worker', rolsuper => 'f', rolinherit => 't', + rolcreaterole => 'f', rolcreatedb => 'f', rolcanlogin => 'f', + rolreplication => 'f', rolbypassrls => 'f', rolconnlimit => '-1', + rolpassword => '_null_', rolvaliduntil => '_null_' }, ] -- 2.39.3 (Apple Git-146) --8o9oIr3uRRuBRCEH--