From 1412e6051a0b76522e0111dc01b9abf0f4607893 Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Tue, 7 Sep 2021 11:22:46 +0200 Subject: [PATCH 1/2] Add editorconfig file This way Github knows how to display tabs correctly. Without it indentation is a mess and it's very hard to read the code. --- .editorconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .editorconfig 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 From a9daad89401340defe9bddd3c26fff6d772a7c2c Mon Sep 17 00:00:00 2001 From: Jelte Fennema Date: Tue, 7 Sep 2021 11:36:55 +0200 Subject: [PATCH 2/2] Guard against race conditions Accessing proc without having a lock is unsafe, because the entry that it points to might be reused. --- prioritize.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) 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.