Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mOyrr-0002o8-IU for pgsql-bugs@arkaria.postgresql.org; Sat, 11 Sep 2021 09:00:11 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mOyro-0004TI-Q7 for pgsql-bugs@arkaria.postgresql.org; Sat, 11 Sep 2021 09:00:08 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mOyro-0004T8-Gg for pgsql-bugs@lists.postgresql.org; Sat, 11 Sep 2021 09:00:08 +0000 Received: from mail-lj1-x22a.google.com ([2a00:1450:4864:20::22a]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1mOyrk-0000LC-9D for pgsql-bugs@lists.postgresql.org; Sat, 11 Sep 2021 09:00:07 +0000 Received: by mail-lj1-x22a.google.com with SMTP id h1so7304556ljl.9 for ; Sat, 11 Sep 2021 02:00:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=khBBqxlXywJ2/AZg25tqr7lg27BtnIlcctkMvbd6FMI=; b=DfcIZwGU+sOK6SgPpkZudDE/bWr/5iYedpiVvRg8DVWY78fxnLLY4oJhlBUwyDQT0Q yki2hJeT/6yqOrPAohMCdelVXffl0YGXSt78vQ02hbq/zizWKoa6EfBBLRd3g2celHx0 kDzYBU2sqh76ELs9hHtUwW2fb7TPm5gefvVUMmcW/EsJNdhpTRosSDAMs3OeprvKapI8 QopsEvaLUmDLQYBixB9d9OkBmhFQnW34WSfKosfqeTJm5MYyPAmeHmq+OAl1degtUOCX 4deoo/eqCf1PvhnU7TE/pqnTKC8RX0/rSzatnFlwft0Wjx/aI16WfIItFZRj4+SuYORT y38w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=khBBqxlXywJ2/AZg25tqr7lg27BtnIlcctkMvbd6FMI=; b=EiZKdL6/CiC43AXWK+U/EMEve//bnO9/AVbjyqfoKAtETXv4B1ernZ+bfWt0JGQ9cW BehN3n6SW0ZMaoVDrDvAiUCZXDk+XOH1u5KeCBqDykRoQ8FysGifAbvlGXxqM63dnWA0 rHOxNi25grPkgDLf35URCdxP5liFhdK7wnmANnSrTWswlz7r2XRrTWfOC011mewQeCBi jz8I8d7SOtMymofzoQpNx3K+5uQOnKYcag3qJnes7HRQDwt7Jx6eozianUsmhACM7WBx YPPdWe1wJ7EYHXr7iYLEmIJxfXltRdgmZ5DH5jGtSK+F+paXdCd3oaTXGeVKbK5g7mV7 JLig== X-Gm-Message-State: AOAM531bFLM9tSxXJq2RoJ9WifRonAPE3goz8qGP1OjWPNzmTFysVL7f qKl0wrSRC3jUHys9drIyo6Cv7aaMp4U= X-Google-Smtp-Source: ABdhPJzRtKXEXWp4GooRLtpQa3aFMsq8yhNXipfOpBztUYmIrPcaR6NXy22G3qBOQtT/SLgdmBWhdA== X-Received: by 2002:a2e:b53a:: with SMTP id z26mr1397592ljm.95.1631350802897; Sat, 11 Sep 2021 02:00:02 -0700 (PDT) Received: from [1.0.0.7] ([178.155.6.166]) by smtp.gmail.com with ESMTPSA id t11sm138400lfc.54.2021.09.11.02.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 11 Sep 2021 02:00:02 -0700 (PDT) Subject: Re: BUG #17182: Race condition on concurrent DROP and CREATE of dependent object To: Tom Lane Cc: pgsql-bugs@lists.postgresql.org References: <17182-a6baa001dd1784be@postgresql.org> <2872252.1630851337@sss.pgh.pa.us> From: Alexander Lakhin Message-ID: Date: Sat, 11 Sep 2021 12:00:00 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 MIME-Version: 1.0 In-Reply-To: <2872252.1630851337@sss.pgh.pa.us> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hello Tom, 05.09.2021 17:15, Tom Lane wrote: >> I get several broken functions with the invalid return type: >> SELECT f1() >> ERROR: cache lookup failed for type 16519 >> CONTEXT: SQL function "f1" during inlining > I don't find this particularly surprising, and I'm unwilling to add the > amount of locking overhead it'd take to prevent it. > > The generic problem is that a newly-created dependent object is not > protected against deletion of its referenced object(s) until we commit > its new pg_depend entries; before that, a concurrent DROP won't see > the dependencies. I recall some discussion of trying to take an > anti-deletion lock in recordDependency, but that's too late: the > deletion might have committed and released its own lock since we > looked up the type (or other referenced object). So the only real fix > for this would be to make every object lookup in the entire system do > the sort of dance that's done in RangeVarGetRelidExtended. We have > agreed that the cost is worth it for tables (though I don't think > that that was without controversy, nor am I 100% convinced that > RangeVarGetRelidExtended is correct). But I'm not excited about > extending the principle to other object types. > Thanks for the detailed explanation! So if that is an acceptable behaviour, then it seems that to prevent not an accidental, but malicious exploitation of it, postgres should be hardened enough to stand up to the attempts to access such invalid objects (e.g. objects with non-existing schemas). (Maybe there are other ways for an unprivileged user to produce such objects, so fixing follow-up crashes is beneficial anyway.) For example, the following script produces functions with invalid schemas: for i in `seq 100`; do ( { for n in `seq 20`; do echo "DROP SCHEMA s;"; done } | psql ) >psql2.log 2>&1 & ( { for n in `seq 1`; do echo " CREATE SCHEMA s; CREATE FUNCTION s.func1() RETURNS int LANGUAGE SQL AS 'SELECT 1;'; CREATE FUNCTION s.func2() RETURNS int LANGUAGE SQL AS 'SELECT 2;'; CREATE FUNCTION s.func3() RETURNS int LANGUAGE SQL AS 'SELECT 3;'; CREATE FUNCTION s.func4() RETURNS int LANGUAGE SQL AS 'SELECT 4;'; CREATE FUNCTION s.func5() RETURNS int LANGUAGE SQL AS 'SELECT 5;'; ";  done } | psql ) >psql1.log 2>&1 & wait psql -c "DROP SCHEMA s CASCADE" >psql3.log done and then the following query crashes the server: SELECT pg_identify_object('pg_proc'::regclass, pp.oid, 0), pp.oid FROM pg_proc pp LEFT JOIN pg_namespace pn ON pp.pronamespace = pn.oid WHERE pn.oid IS NULL Core was generated by `postgres: law regression [local] SELECT                                         '. Program terminated with signal SIGSEGV, Segmentation fault. #0  quote_identifier (ident=0x0) at ruleutils.c:11357 11357           safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_'); (gdb) bt #0  quote_identifier (ident=0x0) at ruleutils.c:11357 #1  0x00005585a5dcee76 in pg_identify_object (fcinfo=) at objectaddress.c:4215 #2  0x00005585a5ed1291 in ExecInterpExpr (state=0x5585a67b1e80, econtext=0x5585a67a8b00, isnull=0x7ffcfbee9e5f)     at execExprInterp.c:749 #3  0x00005585a5ecdb05 in ExecInterpExprStillValid (state=0x5585a67b1e80, econtext=0x5585a67a8b00,     isNull=0x7ffcfbee9e5f) at execExprInterp.c:1824 So the quote_identifier(schema) construction seems unsafe in the circumstances. My colleagues Alexander Kozhemyakin and Sergey Shinderuk discovered similar crash case with OCLASS_DEFACL in getObjectIdentityParts(), that drove me to study this issue additionally. Best regards, Alexander