Re: Allow non-superuser to cancel superuser tasks.

Michael Paquier <michael@paquier.xyz>

From: Michael Paquier <michael@paquier.xyz>
To: Kirill Reshke <reshkekirill@gmail.com>
Cc: Nathan Bossart <nathandbossart@gmail.com>, "Leung, Anthony" <antholeu@amazon.com>, "Andrey M. Borodin" <x4mmm@yandex-team.ru>, "pgsql-hackers@postgresql.org" <pgsql-hackers@postgresql.org>
Date: 2024-04-12T00:10:35Z
Lists: pgsql-hackers
On Thu, Apr 11, 2024 at 04:55:59PM +0500, Kirill Reshke wrote:
> The test doesn't fail because pg_terminate_backend actually meets his
> point: autovac is killed. But while dying, autovac also receives
> segfault. Thats because of injections points:
> 
> (gdb) bt
> #0  0x000056361c3379ea in tas (lock=0x7fbcb9632224 <error: Cannot
> access memory at address 0x7fbcb9632224>) at
> ../../../../src/include/storage/s_lock.h:228
> #1  ConditionVariableCancelSleep () at condition_variable.c:238
> #2  0x000056361c337e4b in ConditionVariableBroadcast
> (cv=0x7fbcb66f498c) at condition_variable.c:310
> #3  0x000056361c330a40 in CleanupProcSignalState (status=<optimized
> out>, arg=<optimized out>) at procsignal.c:240
> #4  0x000056361c328801 in shmem_exit (code=code@entry=1) at ipc.c:276
> #5  0x000056361c3288fc in proc_exit_prepare (code=code@entry=1) at ipc.c:198
> #6  0x000056361c3289bf in proc_exit (code=code@entry=1) at ipc.c:111
> #7  0x000056361c49ffa8 in errfinish (filename=<optimized out>,
> lineno=<optimized out>, funcname=0x56361c654370 <__func__.16>
> "ProcessInterrupts") at elog.c:592
> #8  0x000056361bf7191e in ProcessInterrupts () at postgres.c:3264
> #9  0x000056361c3378d7 in ConditionVariableTimedSleep
> (cv=0x7fbcb9632224, timeout=timeout@entry=-1,
> wait_event_info=117440513) at condition_variable.c:196
> #10 0x000056361c337d0b in ConditionVariableTimedSleep
> (wait_event_info=<optimized out>, timeout=-1, cv=<optimized out>) at
> condition_variable.c:135
> #11 ConditionVariableSleep (cv=<optimized out>,
> wait_event_info=<optimized out>) at condition_variable.c:98
> 
> discovered because of
> # Release injection point.
> $node->safe_psql('postgres',
> "SELECT injection_point_detach('autovacuum-worker-start');");
> added
> 
> v4 also suffers from that. i will try to fix that.

I can see this stack trace as well.  Capturing a bit more than your
own stack, this is crashing in the autovacuum worker while waiting on
a condition variable when processing a ProcessInterrupts().

That may point to a legit bug with condition variables in this
context, actually?  From what I can see, issuing a signal on a backend
process waiting with a condition variable is able to process the
interrupt correctly.
--
Michael

Commits

  1. Look up backend type in pg_signal_backend() more cheaply.

  2. Add tap test for pg_signal_autovacuum role

  3. Introduce pg_signal_autovacuum_worker.

  4. Add a slot synchronization function.

  5. Ban role pg_signal_backend from more superuser backend types.