Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0495aaa

Browse files
committed
Allow a user to kill his own queries using pg_cancel_backend()
Allows a user to use pg_cancel_queries() to cancel queries inother backends if they are running under the same role.pg_terminate_backend() still requires superuser permissoins.Short patch, many authors working on the bikeshed: Magnus Hagander,Josh Kupershmidt, Edward Muller, Greg Smith.
1 parent652300f commit0495aaa

File tree

2 files changed

+80
-13
lines changed

2 files changed

+80
-13
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14262,8 +14262,8 @@ SELECT set_config('log_statement_stats', 'off', false);
1426214262
<para>
1426314263
The functions shown in <xref
1426414264
linkend="functions-admin-signal-table"> send control signals to
14265-
other server processes. Use of these functions is restricted
14266-
to superusers.
14265+
other server processes. Use of these functions isusuallyrestricted
14266+
to superusers, with noted exceptions.
1426714267
</para>
1426814268

1426914269
<table id="functions-admin-signal-table">
@@ -14280,7 +14280,10 @@ SELECT set_config('log_statement_stats', 'off', false);
1428014280
<literal><function>pg_cancel_backend(<parameter>pid</parameter> <type>int</>)</function></literal>
1428114281
</entry>
1428214282
<entry><type>boolean</type></entry>
14283-
<entry>Cancel a backend's current query</entry>
14283+
<entry>Cancel a backend's current query. You can execute this against
14284+
another backend that has exactly the same role as the user calling the
14285+
function. In all other cases, you must be a superuser.
14286+
</entry>
1428414287
</row>
1428514288
<row>
1428614289
<entry>
@@ -14322,6 +14325,10 @@ SELECT set_config('log_statement_stats', 'off', false);
1432214325
<command>postgres</command> processes on the server (using
1432314326
<application>ps</> on Unix or the <application>Task
1432414327
Manager</> on <productname>Windows</>).
14328+
For the less restrictive <function>pg_cancel_backend</>, the role of an
14329+
active backend can be found from
14330+
the <structfield>usename</structfield> column of the
14331+
<structname>pg_stat_activity</structname> view.
1432514332
</para>
1432614333

1432714334
<para>

‎src/backend/utils/adt/misc.c

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include"postmaster/syslogger.h"
3131
#include"storage/fd.h"
3232
#include"storage/pmsignal.h"
33+
#include"storage/proc.h"
3334
#include"storage/procarray.h"
3435
#include"tcop/tcopprot.h"
3536
#include"utils/builtins.h"
@@ -70,15 +71,42 @@ current_query(PG_FUNCTION_ARGS)
7071
}
7172

7273
/*
73-
* Functions to send signals to other backends.
74+
* Send a signal to another backend.
75+
* The signal is delivered if the user is either a superuser or the same
76+
* role as the backend being signaled. For "dangerous" signals, an explicit
77+
* check for superuser needs to be done prior to calling this function.
78+
*
79+
* Returns 0 on success, 1 on general failure, and 2 on permission error.
80+
* In the event of a general failure (returncode 1), a warning message will
81+
* be emitted. For permission errors, doing that is the responsibility of
82+
* the caller.
7483
*/
75-
staticbool
84+
#defineSIGNAL_BACKEND_SUCCESS 0
85+
#defineSIGNAL_BACKEND_ERROR 1
86+
#defineSIGNAL_BACKEND_NOPERMISSION 2
87+
staticint
7688
pg_signal_backend(intpid,intsig)
7789
{
90+
PGPROC*proc;
91+
7892
if (!superuser())
79-
ereport(ERROR,
80-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
81-
(errmsg("must be superuser to signal other server processes"))));
93+
{
94+
/*
95+
* Since the user is not superuser, check for matching roles. Trust
96+
* that BackendPidGetProc will return NULL if the pid isn't valid,
97+
* even though the check for whether it's a backend process is below.
98+
* The IsBackendPid check can't be relied on as definitive even if it
99+
* was first. The process might end between successive checks
100+
* regardless of their order. There's no way to acquire a lock on an
101+
* arbitrary process to prevent that. But since so far all the callers
102+
* of this mechanism involve some request for ending the process
103+
* anyway, that it might end on its own first is not a problem.
104+
*/
105+
proc=BackendPidGetProc(pid);
106+
107+
if (proc==NULL||proc->roleId!=GetUserId())
108+
returnSIGNAL_BACKEND_NOPERMISSION;
109+
}
82110

83111
if (!IsBackendPid(pid))
84112
{
@@ -88,9 +116,18 @@ pg_signal_backend(int pid, int sig)
88116
*/
89117
ereport(WARNING,
90118
(errmsg("PID %d is not a PostgreSQL server process",pid)));
91-
returnfalse;
119+
returnSIGNAL_BACKEND_ERROR;
92120
}
93121

122+
/*
123+
* Can the process we just validated above end, followed by the pid being
124+
* recycled for a new process, before reaching here? Then we'd be trying
125+
* to kill the wrong thing. Seems near impossible when sequential pid
126+
* assignment and wraparound is used. Perhaps it could happen on a system
127+
* where pid re-use is randomized.That race condition possibility seems
128+
* too unlikely to worry about.
129+
*/
130+
94131
/* If we have setsid(), signal the backend's whole process group */
95132
#ifdefHAVE_SETSID
96133
if (kill(-pid,sig))
@@ -101,23 +138,46 @@ pg_signal_backend(int pid, int sig)
101138
/* Again, just a warning to allow loops */
102139
ereport(WARNING,
103140
(errmsg("could not send signal to process %d: %m",pid)));
104-
returnfalse;
141+
returnSIGNAL_BACKEND_ERROR;
105142
}
106-
returntrue;
143+
returnSIGNAL_BACKEND_SUCCESS;
107144
}
108145

146+
/*
147+
* Signal to cancel a backend process.This is allowed if you are superuser or
148+
* have the same role as the process being canceled.
149+
*/
109150
Datum
110151
pg_cancel_backend(PG_FUNCTION_ARGS)
111152
{
112-
PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0),SIGINT));
153+
intr=pg_signal_backend(PG_GETARG_INT32(0),SIGINT);
154+
155+
if (r==SIGNAL_BACKEND_NOPERMISSION)
156+
ereport(ERROR,
157+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
158+
(errmsg("must be superuser or have the same role to cancel queries running in other server processes"))));
159+
160+
PG_RETURN_BOOL(r==SIGNAL_BACKEND_SUCCESS);
113161
}
114162

163+
/*
164+
* Signal to terminate a backend process. Only allowed by superuser.
165+
*/
115166
Datum
116167
pg_terminate_backend(PG_FUNCTION_ARGS)
117168
{
118-
PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM));
169+
if (!superuser())
170+
ereport(ERROR,
171+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
172+
errmsg("must be superuser to terminate other server processes"),
173+
errhint("You can cancel your own processes with pg_cancel_backend().")));
174+
175+
PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0),SIGTERM)==SIGNAL_BACKEND_SUCCESS);
119176
}
120177

178+
/*
179+
* Signal to reload the database configuration
180+
*/
121181
Datum
122182
pg_reload_conf(PG_FUNCTION_ARGS)
123183
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp