@@ -99,14 +99,13 @@ typedef struct
9999} trace_request ;
100100
101101static void SendCurrentUserId (void );
102- Oid GetRemoteBackendUserId (PGPROC * proc , int * error_code );
102+ Oid GetRemoteBackendUserId (PGPROC * proc );
103103static void SendWorkerPids (void );
104104List * GetRemoteBackendWorkers (PGPROC * proc , int * error_code );
105105
106106/* Shared memory variables */
107107shm_toc * toc = NULL ;
108- user_data * caller = NULL ;
109- pg_qs_params * params = NULL ;
108+ pg_qs_params * params = NULL ;
110109trace_request * trace_req = NULL ;
111110shm_mq * mq = NULL ;
112111
@@ -122,11 +121,10 @@ pg_qs_shmem_size()
122121
123122 shm_toc_initialize_estimator (& e );
124123
125- nkeys = 4 ;
124+ nkeys = 3 ;
126125
127- shm_toc_estimate_chunk (& e , sizeof (user_data ));
128- shm_toc_estimate_chunk (& e , sizeof (pg_qs_params ));
129126 shm_toc_estimate_chunk (& e , sizeof (trace_request ));
127+ shm_toc_estimate_chunk (& e , sizeof (pg_qs_params ));
130128 shm_toc_estimate_chunk (& e , (Size ) QUEUE_SIZE );
131129
132130 shm_toc_estimate_keys (& e , nkeys );
@@ -144,30 +142,28 @@ pg_qs_shmem_startup(void)
144142 bool found ;
145143 Size shmem_size = pg_qs_shmem_size ();
146144 void * shmem ;
145+ int num_toc = 0 ;
147146
148147 shmem = ShmemInitStruct ("pg_query_state" , shmem_size , & found );
149148 if (!found )
150149 {
151150 toc = shm_toc_create (PG_QS_MODULE_KEY , shmem , shmem_size );
152151
153- caller = shm_toc_allocate (toc , sizeof (user_data ));
154- shm_toc_insert (toc , 0 , caller );
155152 params = shm_toc_allocate (toc , sizeof (pg_qs_params ));
156- shm_toc_insert (toc , 1 , params );
153+ shm_toc_insert (toc , num_toc ++ , params );
157154 trace_req = shm_toc_allocate (toc , sizeof (trace_request ));
158- shm_toc_insert (toc , 2 , trace_req );
155+ shm_toc_insert (toc , num_toc ++ , trace_req );
159156 MemSet (trace_req , 0 , sizeof (trace_request ));
160157 mq = shm_toc_allocate (toc , QUEUE_SIZE );
161- shm_toc_insert (toc , 3 , mq );
158+ shm_toc_insert (toc , num_toc ++ , mq );
162159 }
163160 else
164161 {
165162 toc = shm_toc_attach (PG_QS_MODULE_KEY , shmem );
166163
167- caller = shm_toc_lookup (toc , 0 );
168- params = shm_toc_lookup (toc , 1 );
169- trace_req = shm_toc_lookup (toc , 2 );
170- mq = shm_toc_lookup (toc , 3 );
164+ params = shm_toc_lookup (toc , num_toc ++ );
165+ trace_req = shm_toc_lookup (toc , num_toc ++ );
166+ mq = shm_toc_lookup (toc , num_toc ++ );
171167 }
172168
173169 if (prev_shmem_startup_hook )
@@ -282,27 +278,6 @@ _PG_fini(void)
282278 postExecProcNode_hook = prev_postExecProcNode ;
283279}
284280
285- /*
286- * Find PGPROC entry
287- */
288- static PGPROC *
289- search_proc (int pid )
290- {
291- int i ;
292-
293- if (pid <= 0 )
294- return NULL ;
295-
296- for (i = 0 ; i < ProcGlobal -> allProcCount ; i ++ )
297- {
298- PGPROC * proc = & ProcGlobal -> allProcs [i ];
299- if (proc -> pid == pid )
300- return proc ;
301- }
302-
303- return NULL ;
304- }
305-
306281/*
307282 * In trace mode suspend query execution until other backend resumes it
308283 */
@@ -314,7 +289,7 @@ suspend_traceable_query()
314289 /* Check whether current backend is traced */
315290 if (MyProcPid == trace_req -> traceable )
316291 {
317- PGPROC * tracer = search_proc (trace_req -> tracer );
292+ PGPROC * tracer = BackendPidGetProc (trace_req -> tracer );
318293
319294 Assert (tracer != NULL );
320295
@@ -587,6 +562,7 @@ pg_query_state(PG_FUNCTION_ARGS)
587562 text * format_text = PG_GETARG_TEXT_P (6 );
588563 ExplainFormat format ;
589564 PGPROC * proc ;
565+ Oid counterpart_user_id ;
590566 shm_mq_handle * mqh ;
591567 shm_mq_result mq_receive_result ;
592568 int send_signal_result ;
@@ -601,7 +577,7 @@ pg_query_state(PG_FUNCTION_ARGS)
601577 ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
602578 errmsg ("attempt to extract state of current process" )));
603579
604- proc = search_proc (pid );
580+ proc = BackendPidGetProc (pid );
605581 if (!proc || proc -> backendId == InvalidBackendId )
606582 ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
607583 errmsg ("backend with pid=%d not found" , pid )));
@@ -624,9 +600,10 @@ pg_query_state(PG_FUNCTION_ARGS)
624600 init_lock_tag (& tag , PG_QUERY_STATE_KEY );
625601 LockAcquire (& tag , ExclusiveLock , false, false);
626602
627- /* fill in caller's user data */
628- caller -> user_id = GetUserId ();
629- caller -> superuser = superuser ();
603+ counterpart_user_id = GetRemoteBackendUserId (proc );
604+ if (!(superuser () || GetUserId () == counterpart_user_id ))
605+ ereport (ERROR , (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
606+ errmsg ("permission denied" )));
630607
631608 /* fill in parameters of query state request */
632609 params -> verbose = verbose ;
@@ -673,9 +650,6 @@ pg_query_state(PG_FUNCTION_ARGS)
673650 LockRelease (& tag , ExclusiveLock , false);
674651 SRF_RETURN_DONE (funcctx );
675652 }
676- case PERM_DENIED :
677- ereport (ERROR , (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
678- errmsg ("permission denied" )));
679653 case STAT_DISABLED :
680654 elog (INFO , "query execution statistics disabled" );
681655 LockRelease (& tag , ExclusiveLock , false);
@@ -769,7 +743,7 @@ exec_trace_cmd(pid_t pid, trace_cmd cmd)
769743 ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
770744 errmsg ("attempt to trace self process" )));
771745
772- proc = search_proc (pid );
746+ proc = BackendPidGetProc (pid );
773747 if (!proc || proc -> backendId == InvalidBackendId )
774748 ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
775749 errmsg ("backend with pid=%d not found" , pid )));
@@ -872,39 +846,35 @@ SendCurrentUserId(void)
872846#define COULD_NOT_SEND_SIGNAL 2
873847#define INVALID_MQ_READ 3
874848
849+ /*
850+ * Extract effective user id of external backend session
851+ * Assume `proc` is valid backend and doesn't point to current process
852+ */
875853Oid
876- GetRemoteBackendUserId (PGPROC * proc , int * error_code )
854+ GetRemoteBackendUserId (PGPROC * proc )
877855{
878856 int sig_result ;
879857 shm_mq_handle * mqh ;
880858 shm_mq_result mq_receive_result ;
881859 Oid * result ;
882860 Size res_len ;
883861
884- if (proc -> backendId == InvalidBackendId )
885- {
886- * error_code = NOT_BACKEND_PROCESS ;
887- return InvalidOid ;
888- }
862+ Assert (proc && proc != MyProc && proc -> backendId != InvalidBackendId );
889863
890864 mq = shm_mq_create (mq , QUEUE_SIZE );
891865 shm_mq_set_sender (mq , proc );
892866 shm_mq_set_receiver (mq , MyProc );
893867
894868 sig_result = SendProcSignal (proc -> pid , RolePollReason , proc -> backendId );
895869 if (sig_result == -1 )
896- {
897- * error_code = COULD_NOT_SEND_SIGNAL ;
898- return InvalidOid ;
899- }
870+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
871+ errmsg ("invalid send signal" )));
900872
901873 mqh = shm_mq_attach (mq , NULL , NULL );
902874 mq_receive_result = shm_mq_receive_with_timeout (mqh , & res_len , (void * * ) & result , 1000 );
903875 if (mq_receive_result != SHM_MQ_SUCCESS )
904- {
905- * error_code = INVALID_MQ_READ ;
906- return InvalidOid ;
907- }
876+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
877+ errmsg ("invalid read from message queue" )));
908878
909879 shm_mq_detach (mq );
910880
@@ -991,7 +961,7 @@ GetRemoteBackendWorkers(PGPROC *proc, int *error_code)
991961 if (proc -> backendId == InvalidBackendId )
992962 {
993963 * error_code = NOT_BACKEND_PROCESS ;
994- return InvalidOid ;
964+ return NIL ;
995965 }
996966
997967 mq = shm_mq_create (mq , QUEUE_SIZE );
@@ -1002,15 +972,15 @@ GetRemoteBackendWorkers(PGPROC *proc, int *error_code)
1002972 if (sig_result == -1 )
1003973 {
1004974 * error_code = COULD_NOT_SEND_SIGNAL ;
1005- return InvalidOid ;
975+ return NIL ;
1006976 }
1007977
1008978 mqh = shm_mq_attach (mq , NULL , NULL );
1009979 mq_receive_result = shm_mq_receive_with_timeout (mqh , & msg_len , (void * * ) & msg , 1000 );
1010980 if (mq_receive_result != SHM_MQ_SUCCESS )
1011981 {
1012982 * error_code = INVALID_MQ_READ ;
1013- return InvalidOid ;
983+ return NIL ;
1014984 }
1015985
1016986 for (i = 0 ; i < msg -> num ; i ++ )
0 commit comments