Thread

Commits

  1. Avoid crash in rare case of concurrent DROP

  1. BUG #17126: Server crashes on dropping user while enumerating owned objects that are droppped concurrently

    The Post Office <noreply@postgresql.org> — 2021-07-28T18:00:00Z

    The following bug has been logged on the website:
    
    Bug reference:      17126
    Logged by:          Alexander Lakhin
    Email address:      exclusion@gmail.com
    PostgreSQL version: Unsupported/Unknown
    Operating system:   Ubuntu 20.04
    Description:        
    
    Dropping a user that owns a number of procedures, while some of them are
    being dropped, can cause the server crash:
    
    Core was generated by `postgres: law regression [local] DROP ROLE           
                            '.
    Program terminated with signal SIGABRT, Aborted.
    #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
    50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
    (gdb) bt
    #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
    #1  0x00007f268882b859 in __GI_abort () at abort.c:79
    #2  0x000055a23a628276 in ExceptionalCondition
    (conditionName=conditionName@entry=0x55a23a77fd4d "pointer != NULL", 
        errorType=errorType@entry=0x55a23a68700b "FailedAssertion",
    fileName=0x7ffdf4459470 "W\202b:\242U", 
        fileName@entry=0x55a23a7886b0
    "../../../../src/include/utils/memutils.h",
    lineNumber=lineNumber@entry=123)
        at assert.c:69
    #3  0x000055a23a65b46e in GetMemoryChunkContext (pointer=0x0) at
    ../../../../src/include/utils/memutils.h:123
    #4  pfree (pointer=pointer@entry=0x0) at mcxt.c:1171
    #5  0x000055a23a23254f in storeObjectDescription
    (descs=descs@entry=0x7ffdf44598b0, type=LOCAL_OBJECT, 
        object=object@entry=0x55a23b5efe10, deptype=SHARED_DEPENDENCY_OWNER,
    count=count@entry=0) at pg_shdepend.c:1267
    #6  0x000055a23a232955 in checkSharedDependencies
    (classId=classId@entry=1260, objectId=objectId@entry=16385, 
        detail_msg=detail_msg@entry=0x7ffdf44599f0,
    detail_log_msg=detail_log_msg@entry=0x7ffdf44599f8) at pg_shdepend.c:771
    #7  0x000055a23a310c51 in DropRole (stmt=stmt@entry=0x55a23b5c7ee8) at
    user.c:1028
    #8  0x000055a23a4ed922 in standard_ProcessUtility (pstmt=0x55a23b5c81f8,
    queryString=0x55a23b5c7450 "DROP USER u;", 
        readOnlyTree=<optimized out>, context=PROCESS_UTILITY_TOPLEVEL,
    params=0x0, queryEnv=0x0, dest=0x55a23b5c82c8, 
        qc=0x7ffdf4459d90) at utility.c:901
    #9  0x000055a23a4edd31 in ProcessUtility (pstmt=pstmt@entry=0x55a23b5c81f8,
    queryString=<optimized out>, 
        readOnlyTree=<optimized out>,
    context=context@entry=PROCESS_UTILITY_TOPLEVEL, params=<optimized out>, 
        queryEnv=<optimized out>, dest=0x55a23b5c82c8, qc=0x7ffdf4459d90) at
    utility.c:527
    #10 0x000055a23a4eb251 in PortalRunUtility
    (portal=portal@entry=0x55a23b629090, pstmt=pstmt@entry=0x55a23b5c81f8, 
        isTopLevel=isTopLevel@entry=true,
    setHoldSnapshot=setHoldSnapshot@entry=false, dest=dest@entry=0x55a23b5c82c8,
    
        qc=qc@entry=0x7ffdf4459d90) at pquery.c:1147
    #11 0x000055a23a4eb553 in PortalRunMulti
    (portal=portal@entry=0x55a23b629090, isTopLevel=isTopLevel@entry=true, 
        setHoldSnapshot=setHoldSnapshot@entry=false,
    dest=dest@entry=0x55a23b5c82c8, altdest=altdest@entry=0x55a23b5c82c8, 
        qc=qc@entry=0x7ffdf4459d90) at pquery.c:1304
    #12 0x000055a23a4eb987 in PortalRun (portal=portal@entry=0x55a23b629090,
    count=count@entry=9223372036854775807, 
        isTopLevel=isTopLevel@entry=true, run_once=run_once@entry=true,
    dest=dest@entry=0x55a23b5c82c8, 
        altdest=altdest@entry=0x55a23b5c82c8, qc=0x7ffdf4459d90) at
    pquery.c:786
    #13 0x000055a23a4e7bd4 in exec_simple_query
    (query_string=query_string@entry=0x55a23b5c7450 "DROP USER u;")
        at postgres.c:1214
    #14 0x000055a23a4e9ba6 in PostgresMain (argc=argc@entry=1,
    argv=argv@entry=0x7ffdf4459f80, dbname=<optimized out>, 
        username=<optimized out>) at postgres.c:4486
    #15 0x000055a23a442f19 in BackendRun (port=port@entry=0x55a23b5ea870) at
    postmaster.c:4506
    #16 0x000055a23a44612e in BackendStartup (port=port@entry=0x55a23b5ea870) at
    postmaster.c:4228
    #17 0x000055a23a446375 in ServerLoop () at postmaster.c:1745
    #18 0x000055a23a4478c2 in PostmasterMain (argc=3, argv=<optimized out>) at
    postmaster.c:1417
    #19 0x000055a23a388291 in main (argc=3, argv=0x55a23b5c14c0) at main.c:209
    (gdb) frame 5
    (gdb) print -elements unlimited -- descs.data
    $7 = 0x55a23b6ef1c0 "owner of function p1()\n...owner of function
    p88()\nowner of (null)"
    
    The reproducing script:
    rm /tmp/c.sql
    for i in `seq 90`; do echo "CREATE OR REPLACE PROCEDURE p$i() LANGUAGE SQL
    AS 'SELECT 1';" >>/tmp/c.sql; done
    rm /tmp/d.sql
    for i in `seq 90 -1 2`; do echo "DROP PROCEDURE IF EXISTS p$i();"
    >>/tmp/d.sql; done
    
    psql -c "CREATE USER u";
    psql -U u -f /tmp/c.sql >psql0.log 2>&1
    for n in `seq 100`; do
      echo "iteration $n"
      ( { for f in `seq 100`; do echo "DROP USER u; SELECT pg_sleep(0.001);";
    done } | psql ) >psql1.log 2>&1 &
      ( { for f in `seq 10`; do cat /tmp/c.sql; done } | psql -U u ) >psql2.log
    2>&1 &
      ( { for f in `seq 10`; do cat /tmp/d.sql; done } | psql -U u ) >psql3.log
    2>&1 &
      wait
      sleep 1
      coredumpctl --no-pager && break;
    done
    
    (Turning fsync off helps in reproducing for me.)
    Interestingly enough, the crash does not occur with tables (but occurs with
    functions):
    (
    ...
    for i in `seq 90`; do echo "CREATE TABLE t$i(i int);" >>/tmp/c.sql; done
    ...
    for i in `seq 90 -1 2`; do echo "DROP TABLE IF EXISTS t$i;" >>/tmp/d.sql;
    done
    ...
    )
    
    Reproduced on master (after 3779ac62).
    
    
  2. Re: BUG #17126: Server crashes on dropping user while enumerating owned objects that are droppped concurrently

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2021-07-28T20:01:01Z

    On 2021-Jul-28, PG Bug reporting form wrote:
    
    > Dropping a user that owns a number of procedures, while some of them are
    > being dropped, can cause the server crash:
    > 
    > Core was generated by `postgres: law regression [local] DROP ROLE           
    >                         '.
    > Program terminated with signal SIGABRT, Aborted.
    > #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
    > 50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
    > (gdb) bt
    > #0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
    > #1  0x00007f268882b859 in __GI_abort () at abort.c:79
    > #2  0x000055a23a628276 in ExceptionalCondition (conditionName=conditionName@entry=0x55a23a77fd4d "pointer != NULL", 
    >     errorType=errorType@entry=0x55a23a68700b "FailedAssertion", fileName=0x7ffdf4459470 "W\202b:\242U", 
    >     fileName@entry=0x55a23a7886b0 "../../../../src/include/utils/memutils.h", lineNumber=lineNumber@entry=123)
    >     at assert.c:69
    > #3  0x000055a23a65b46e in GetMemoryChunkContext (pointer=0x0) at ../../../../src/include/utils/memutils.h:123
    > #4  pfree (pointer=pointer@entry=0x0) at mcxt.c:1171
    > #5  0x000055a23a23254f in storeObjectDescription (descs=descs@entry=0x7ffdf44598b0, type=LOCAL_OBJECT, 
    >     object=object@entry=0x55a23b5efe10, deptype=SHARED_DEPENDENCY_OWNER, count=count@entry=0) at pg_shdepend.c:1267
    
    There's many places that deal correctly with the possibility that
    getObjectDescription() would return NULL, but I found two places that
    don't.
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    
  3. Re: BUG #17126: Server crashes on dropping user while enumerating owned objects that are droppped concurrently

    Alexander Law <exclusion@gmail.com> — 2021-09-02T04:00:01Z

    Hello Alvaro,
    28.07.2021 23:01, Alvaro Herrera wrote:
    > On 2021-Jul-28, PG Bug reporting form wrote:
    >
    >> Dropping a user that owns a number of procedures, while some of them are
    >> being dropped, can cause the server crash:
    >> There's many places that deal correctly with the possibility that
    >> getObjectDescription() would return NULL, but I found two places that
    >> don't.
    I've found another one in dependency.c:
    
            else if (behavior == DROP_RESTRICT)
            {
                char       *otherDesc = getObjectDescription(&extra->dependee,
                                                             false);
    ...
                pfree(otherDesc);
    I couldn't trigger a failure at this place yet, but maybe it's worth to
    fix here too.
    
    Best regards,
    Alexander
    
    
    
    
  4. Re: BUG #17126: Server crashes on dropping user while enumerating owned objects that are droppped concurrently

    Alvaro Herrera <alvherre@alvh.no-ip.org> — 2021-11-05T15:35:04Z

    On 2021-Sep-02, Alexander Lakhin wrote:
    
    > I've found another one in dependency.c:
    > 
    >         else if (behavior == DROP_RESTRICT)
    >         {
    >             char       *otherDesc = getObjectDescription(&extra->dependee,
    >                                                          false);
    > ...
    >             pfree(otherDesc);
    > I couldn't trigger a failure at this place yet, but maybe it's worth to
    > fix here too.
    
    Thank you, I patched this one as well.  Fix is now pushed to all branches.
    
    -- 
    Álvaro Herrera         PostgreSQL Developer  —  https://www.EnterpriseDB.com/
    "Cada quien es cada cual y baja las escaleras como quiere" (JMSerrat)