Allow GRANT on pg_log_backend_memory_contexts().
authorJeff Davis <[email protected]>
Tue, 26 Oct 2021 20:13:52 +0000 (13:13 -0700)
committerJeff Davis <[email protected]>
Tue, 26 Oct 2021 20:31:38 +0000 (13:31 -0700)
Remove superuser check, allowing any user granted permissions on
pg_log_backend_memory_contexts() to log the memory contexts of any
backend.

Note that this could allow a privileged non-superuser to log the
memory contexts of a superuser backend, but as discussed, that does
not seem to be a problem.

Reviewed-by: Nathan Bossart, Bharath Rupireddy, Michael Paquier, Kyotaro Horiguchi, Andres Freund
Discussion: https://postgr.es/m/e5cf6684d17c8d1ef4904ae248605ccd6da03e72[email protected]

doc/src/sgml/func.sgml
src/backend/catalog/system_functions.sql
src/backend/utils/adt/mcxtfuncs.c
src/include/catalog/catversion.h
src/test/regress/expected/misc_functions.out
src/test/regress/sql/misc_functions.sql

index 5677032cb28f50e7362e5f5b76fd3321c0dad8d6..4b49dff2ffc63183f3fe8d4c7987f5930624a28e 100644 (file)
@@ -25332,7 +25332,6 @@ SELECT collation for ('foo' COLLATE "de_DE");
         (See <xref linkend="runtime-config-logging"/> for more information),
         but will not be sent to the client regardless of
         <xref linkend="guc-client-min-messages"/>.
-        Only superusers can request to log the memory contexts.
        </para></entry>
       </row>
 
index a416e94d3717a873e2d33a23ed2a72a78ddf204a..54c93b16c4c195fbcb630bd58bfb275533699ed1 100644 (file)
@@ -699,6 +699,8 @@ REVOKE EXECUTE ON FUNCTION pg_ls_dir(text) FROM public;
 
 REVOKE EXECUTE ON FUNCTION pg_ls_dir(text,boolean,boolean) FROM public;
 
+REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer) FROM PUBLIC;
+
 --
 -- We also set up some things as accessible to standard roles.
 --
index 0d52613bc32aeb5d716e32ea65f47c33783dc45d..6ddbf70b30c815a0927cb11cd8e771b6404fb084 100644 (file)
@@ -162,10 +162,10 @@ pg_get_backend_memory_contexts(PG_FUNCTION_ARGS)
  * pg_log_backend_memory_contexts
  *             Signal a backend process to log its memory contexts.
  *
- * Only superusers are allowed to signal to log the memory contexts
- * because allowing any users to issue this request at an unbounded
- * rate would cause lots of log messages and which can lead to
- * denial of service.
+ * By default, only superusers are allowed to signal to log the memory
+ * contexts because allowing any users to issue this request at an unbounded
+ * rate would cause lots of log messages and which can lead to denial of
+ * service. Additional roles can be permitted with GRANT.
  *
  * On receipt of this signal, a backend sets the flag in the signal
  * handler, which causes the next CHECK_FOR_INTERRUPTS() to log the
@@ -177,12 +177,6 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
        int                     pid = PG_GETARG_INT32(0);
        PGPROC     *proc;
 
-       /* Only allow superusers to log memory contexts. */
-       if (!superuser())
-               ereport(ERROR,
-                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-                                errmsg("must be a superuser to log memory contexts")));
-
        proc = BackendPidGetProc(pid);
 
        /*
index 3253b8751b1360e8e2d173e1cf27d43ee69ba135..468491825a1ec5dfb71945934cb615b4eabe1bc0 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     202109101
+#define CATALOG_VERSION_NO     202110260
 
 #endif
index e845042d38de7c69fffc6153fe19760e2228a183..71d316cad3e472a281db527bb373e9dc9bf3c9d4 100644 (file)
@@ -138,14 +138,43 @@ HINT:  No function matches the given name and argument types. You might need to
 --
 -- Memory contexts are logged and they are not returned to the function.
 -- Furthermore, their contents can vary depending on the timing. However,
--- we can at least verify that the code doesn't fail.
+-- we can at least verify that the code doesn't fail, and that the
+-- permissions are set properly.
 --
-SELECT * FROM pg_log_backend_memory_contexts(pg_backend_pid());
+SELECT pg_log_backend_memory_contexts(pg_backend_pid());
  pg_log_backend_memory_contexts 
 --------------------------------
  t
 (1 row)
 
+CREATE ROLE regress_log_memory;
+SELECT has_function_privilege('regress_log_memory',
+  'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); -- no
+ has_function_privilege 
+------------------------
+ f
+(1 row)
+
+GRANT EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer)
+  TO regress_log_memory;
+SELECT has_function_privilege('regress_log_memory',
+  'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); -- yes
+ has_function_privilege 
+------------------------
+ t
+(1 row)
+
+SET ROLE regress_log_memory;
+SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+ pg_log_backend_memory_contexts 
+--------------------------------
+ t
+(1 row)
+
+RESET ROLE;
+REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer)
+  FROM regress_log_memory;
+DROP ROLE regress_log_memory;
 --
 -- Test some built-in SRFs
 --
index a398349afc63edb24e3afaa001d1d6d36eb0db01..8c23874b3f5dfe1d486f1bb5536aeee0f2837f1f 100644 (file)
@@ -35,9 +35,31 @@ SELECT num_nulls();
 --
 -- Memory contexts are logged and they are not returned to the function.
 -- Furthermore, their contents can vary depending on the timing. However,
--- we can at least verify that the code doesn't fail.
+-- we can at least verify that the code doesn't fail, and that the
+-- permissions are set properly.
 --
-SELECT * FROM pg_log_backend_memory_contexts(pg_backend_pid());
+
+SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+
+CREATE ROLE regress_log_memory;
+
+SELECT has_function_privilege('regress_log_memory',
+  'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); -- no
+
+GRANT EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer)
+  TO regress_log_memory;
+
+SELECT has_function_privilege('regress_log_memory',
+  'pg_log_backend_memory_contexts(integer)', 'EXECUTE'); -- yes
+
+SET ROLE regress_log_memory;
+SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+RESET ROLE;
+
+REVOKE EXECUTE ON FUNCTION pg_log_backend_memory_contexts(integer)
+  FROM regress_log_memory;
+
+DROP ROLE regress_log_memory;
 
 --
 -- Test some built-in SRFs