Reorder superuser check in pg_log_backend_memory_contexts()
authorMichael Paquier <michael@paquier.xyz>
Mon, 7 Jun 2021 23:53:12 +0000 (08:53 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 7 Jun 2021 23:53:12 +0000 (08:53 +0900)
The use of this function is limited to superusers and the code includes
a hardcoded check for that.  However, the code would look for the PGPROC
entry to signal for the memory dump before checking if the user is a
superuser or not, which does not make sense if we know that an error
will be returned.  Note that the code would let one know if a process
was a PostgreSQL process or not even for non-authorized users, which is
not the case now, but this avoids taking ProcArrayLock that will most
likely finish by being unnecessary.

Thanks to Julien Rouhaud and Tom Lane for the discussion.

Discussion: https://postgr.es/m/YLxw1uVGIAP5uMPl@paquier.xyz

src/backend/utils/adt/mcxtfuncs.c

index 2984768d1994882e66bdae93ca62f455d4681e79..0d52613bc32aeb5d716e32ea65f47c33783dc45d 100644 (file)
@@ -175,7 +175,15 @@ Datum
 pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
 {
    int         pid = PG_GETARG_INT32(0);
-   PGPROC     *proc = BackendPidGetProc(pid);
+   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);
 
    /*
     * BackendPidGetProc returns NULL if the pid isn't valid; but by the time
@@ -197,12 +205,6 @@ pg_log_backend_memory_contexts(PG_FUNCTION_ARGS)
        PG_RETURN_BOOL(false);
    }
 
-   /* Only allow superusers to log memory contexts. */
-   if (!superuser())
-       ereport(ERROR,
-               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
-                errmsg("must be a superuser to log memory contexts")));
-
    if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, proc->backendId) < 0)
    {
        /* Again, just a warning to allow loops */