diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2d1a065 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ + +# top-most EditorConfig file +root = true + +# rules for all files +# we use tabs with indent size 4 +[*] +indent_style = spaces +indent_size = 4 +tab_width = 8 +end_of_line = lf +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true diff --git a/prioritize.c b/prioritize.c index 872cef2..38ac2b8 100644 --- a/prioritize.c +++ b/prioritize.c @@ -74,14 +74,20 @@ set_backend_priority(PG_FUNCTION_ARGS) else if (!superuser()) { /* * Since the user is not superuser, check for matching roles. Trust - * that BackendPidGetProc will return NULL if the pid isn't valid, - * even though the check for whether it's a backend process is below. - * The IsBackendPid check can't be relied on as definitive even if it - * was first. The process might end between successive checks + * that BackendPidGetProcWithLock will return NULL if the pid isn't + * valid, even though the check for whether it's a backend process is + * below. The IsBackendPid check can't be relied on as definitive even + * if it was first. The process might end between successive checks * regardless of their order. There's no way to acquire a lock on an * arbitrary process to prevent that. + * + * We do take the ProcArrayLock manually instead of using + * BackendPidGetProc, because we need to be sure that the contents of + * proc don't change from under us while we're using them. */ - proc = BackendPidGetProc(pid); + LWLockAcquire(ProcArrayLock, LW_SHARED); + + proc = BackendPidGetProcWithLock(pid); if (proc == NULL) { /* @@ -94,9 +100,12 @@ set_backend_priority(PG_FUNCTION_ARGS) } else if (proc->roleId != GetUserId()) + LWLockRelease(ProcArrayLock); ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to nice arbitrary backends")))); + LWLockRelease(ProcArrayLock); + /* Otherwise, the backend PID is valid and our user is allowed * to set its priority.