Thread: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
harukat@sraoss.co.jp
Date:
The following bug has been logged on the website: Bug reference: 11335 Logged by: invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'. Email address: harukat@sraoss.co.jp PostgreSQL version: 9.3.5 Operating system: CentOS 6.2 (64bit / gcc 4.4.7) Description: setting: log_statement = 'mod' # or 'ddl' reproduction client code: <?php require_once 'MDB2.php'; $con1 =& MDB2::connect("pgsql://postgres@localhost/db1"); if (PEAR::isError($con1)) { die($con1->getMessage()); } $sth = $con1->prepare(""); if (PEAR::isError($sth)) { die($sth->getMessage()); } $sth->execute(); ?> log messages: 2014-09-02 19:41:57 JST 9453 LOG: server process (PID 10372) was terminated by signal11: Segmentation fault 2014-09-02 19:41:57 JST 9453 DETAIL: Failed process was running: EXECUTE mdb2_statement_pgsql_9cc7dc53dfc30b3c2b937c650346f586 This occur in 9.3.5 and 9.1.14. (It probably occur at any versions.) I tested that the following fix prevent this crash. *** ./src/backend/tcop/utility.c 2014-09-02 19:32:44.735266203 +0900 --- ./src/backend/tcop/utility.c.ORG 2014-09-02 18:17:47.631854101 +0900 *************** *** 2307,2314 **** GetCommandLogLevel(Node *parsetree) { LogStmtLevel lev; - if (! parsetree) - return LOGSTMT_ALL; switch (nodeTag(parsetree)) { --- 2307,2312 ---- Though we should throw ERROR for empty prepared statement, I hope for a symptomatic treatment such as the above. Because an application package use such wrong query. ---------------------------------------------------------- Haruka Takatsuka harukat@sraoss.co.jp SRA OSS, Inc. http://www.sraoss.co.jp
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Fujii Masao
Date:
On Tue, Sep 2, 2014 at 8:16 PM, <harukat@sraoss.co.jp> wrote: > The following bug has been logged on the website: > > Bug reference: 11335 > Logged by: invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'. > Email address: harukat@sraoss.co.jp > PostgreSQL version: 9.3.5 > Operating system: CentOS 6.2 (64bit / gcc 4.4.7) > Description: > > > setting: > log_statement = 'mod' # or 'ddl' > > reproduction client code: > <?php > require_once 'MDB2.php'; > $con1 =& MDB2::connect("pgsql://postgres@localhost/db1"); > if (PEAR::isError($con1)) { die($con1->getMessage()); } > $sth = $con1->prepare(""); > if (PEAR::isError($sth)) { die($sth->getMessage()); } > $sth->execute(); > ?> > > log messages: > 2014-09-02 19:41:57 JST 9453 LOG: server process (PID 10372) was > terminated by signal11: Segmentation fault > 2014-09-02 19:41:57 JST 9453 DETAIL: Failed process was running: > EXECUTE mdb2_statement_pgsql_9cc7dc53dfc30b3c2b937c650346f586 > > This occur in 9.3.5 and 9.1.14. (It probably occur at any versions.) > I tested that the following fix prevent this crash. Thanks for reporting the bug! This segmentation fault could reproduce even on my machine. Barring any objection, I will apply the change that you suggested. Regards, -- Fujii Masao
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Fujii Masao
Date:
On Thu, Sep 4, 2014 at 3:55 AM, Fujii Masao <masao.fujii@gmail.com> wrote: > On Tue, Sep 2, 2014 at 8:16 PM, <harukat@sraoss.co.jp> wrote: >> The following bug has been logged on the website: >> >> Bug reference: 11335 >> Logged by: invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'. >> Email address: harukat@sraoss.co.jp >> PostgreSQL version: 9.3.5 >> Operating system: CentOS 6.2 (64bit / gcc 4.4.7) >> Description: >> >> >> setting: >> log_statement = 'mod' # or 'ddl' >> >> reproduction client code: >> <?php >> require_once 'MDB2.php'; >> $con1 =& MDB2::connect("pgsql://postgres@localhost/db1"); >> if (PEAR::isError($con1)) { die($con1->getMessage()); } >> $sth = $con1->prepare(""); >> if (PEAR::isError($sth)) { die($sth->getMessage()); } >> $sth->execute(); >> ?> >> >> log messages: >> 2014-09-02 19:41:57 JST 9453 LOG: server process (PID 10372) was >> terminated by signal11: Segmentation fault >> 2014-09-02 19:41:57 JST 9453 DETAIL: Failed process was running: >> EXECUTE mdb2_statement_pgsql_9cc7dc53dfc30b3c2b937c650346f586 >> >> This occur in 9.3.5 and 9.1.14. (It probably occur at any versions.) >> I tested that the following fix prevent this crash. > > Thanks for reporting the bug! This segmentation fault could reproduce > even on my machine. Barring any objection, I will apply the change that > you suggested. Done. Regards, -- Fujii Masao
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Tom Lane
Date:
Fujii Masao <masao.fujii@gmail.com> writes: > On Thu, Sep 4, 2014 at 3:55 AM, Fujii Masao <masao.fujii@gmail.com> wrote: >> Thanks for reporting the bug! This segmentation fault could reproduce >> even on my machine. Barring any objection, I will apply the change that >> you suggested. > Done. I don't think this fix is either appropriate or adequate. Stylistically, it's bogus that this function should be prepared for a null argument when similar command-tag-related functions right next to it are not. Moreover, what is the reasoning why the correct answer for a null argument is LOGSTMT_ALL and not something else? It'd be at least as legit to make it LOGSTMT_NONE, for instance. As far as adequacy goes, the actual bug seems to be that this bit of code is not expecting a plansource's raw_parse_tree to ever be NULL: /* Look through an EXECUTE to the referenced stmt */ ps = FetchPreparedStatement(stmt->name, false); if (ps) lev = GetCommandLogLevel(ps->plansource->raw_parse_tree); else lev = LOGSTMT_ALL; and it is not terribly hard to find other places making the same assumption, which is probably reasonable because the comments around the plansource files don't suggest it's legal either. So I don't think this has exhausted the number of ways to crash the backend after creating such a prepared statement. I think we should revert the patch as applied and instead think about whether it's really legit to have a null raw_parse_tree in a cached plan. If it is, the plansource comments need adjustment and so do several other places in the code. I'd also say that the right place to adjust GetCommandLogLevel is in the bit I quoted above, where we know that what we're talking about is EXECUTE on an empty prepared query, and so there's a more principled basis for determining what its logging level ought to be. It might be that we'd be better off inventing some kind of EmptyStmt parse tree for this case. Or maybe we should reconsider whether exec_parse_message should allow the case at all. It's not unreasonable that Parse should require exactly one SQL statement, not just "at most one". regards, tom lane
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Andres Freund
Date:
On 2014-09-06 16:25:28 -0400, Tom Lane wrote: > Fujii Masao <masao.fujii@gmail.com> writes: > > On Thu, Sep 4, 2014 at 3:55 AM, Fujii Masao <masao.fujii@gmail.com> wrote: > >> Thanks for reporting the bug! This segmentation fault could reproduce > >> even on my machine. Barring any objection, I will apply the change that > >> you suggested. > > > Done. > > I don't think this fix is either appropriate or adequate. Agreed (and commented offlist. Which probably was a mistake). > Or maybe we should reconsider whether > exec_parse_message should allow the case at all. It's not unreasonable > that Parse should require exactly one SQL statement, not just "at most > one". I think this is the best bet. There really doesn't seem much justification for the current "at most one" definition. At least not one that I could find or think of. The likelihood of leaving some places unfixed or new breakages creeping in seems non-nil; it's not what one would immediately expect. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Michael Paquier
Date:
On Sat, Sep 6, 2014 at 1:34 PM, Andres Freund <andres@2ndquadrant.com> wrote: > On 2014-09-06 16:25:28 -0400, Tom Lane wrote: >> Fujii Masao <masao.fujii@gmail.com> writes: >> > On Thu, Sep 4, 2014 at 3:55 AM, Fujii Masao <masao.fujii@gmail.com> wrote: >> >> Thanks for reporting the bug! This segmentation fault could reproduce >> >> even on my machine. Barring any objection, I will apply the change that >> >> you suggested. >> >> > Done. >> >> I don't think this fix is either appropriate or adequate. > > Agreed (and commented offlist. Which probably was a mistake). This has not been reverted yet. Wouldn't it be better to do that asap? This would improve chances of seeing any potential issues in this code path if it gets broken once again. >> Or maybe we should reconsider whether >> exec_parse_message should allow the case at all. It's not unreasonable >> that Parse should require exactly one SQL statement, not just "at most >> one". > > I think this is the best bet. There really doesn't seem much > justification for the current "at most one" definition. At least not one > that I could find or think of. The likelihood of leaving some places > unfixed or new breakages creeping in seems non-nil; it's not what one > would immediately expect. Looking at exec_parse_message, empty input string is allowed for a cached plan (16503e6f). This solution would break client applications/drivers using the extending query protocol and relying on this behavior. This EmptyStmt approach sounds like a good option. -- Michael
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Tom Lane
Date:
Michael Paquier <michael.paquier@gmail.com> writes: > On Sat, Sep 6, 2014 at 1:34 PM, Andres Freund <andres@2ndquadrant.com> wrote: >> On 2014-09-06 16:25:28 -0400, Tom Lane wrote: >>> I don't think this fix is either appropriate or adequate. >> Agreed (and commented offlist. Which probably was a mistake). > This has not been reverted yet. Wouldn't it be better to do that asap? Probably not until someone codes a better fix. I have it on my plate to look into a better fix, but I've been horribly busy lately. > Looking at exec_parse_message, empty input string is allowed for a > cached plan (16503e6f). This solution would break client > applications/drivers using the extending query protocol and relying on > this behavior. This EmptyStmt approach sounds like a good option. Yeah, on second thought I have doubts about the throw-error approach too. We've allowed this historically for a very long time, so I'm afraid we'd get a lot of pushback if we change the external behavior now. The realistic alternatives are either to fix the code to support having plansource->raw_parse_tree be NULL, or to invent a dummy node type to put there. Not sure which is better. regards, tom lane
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Andres Freund
Date:
On 2014-09-17 14:56:42 -0700, Tom Lane wrote: > Michael Paquier <michael.paquier@gmail.com> writes: > > On Sat, Sep 6, 2014 at 1:34 PM, Andres Freund <andres@2ndquadrant.com> wrote: > > Looking at exec_parse_message, empty input string is allowed for a > > cached plan (16503e6f). This solution would break client > > applications/drivers using the extending query protocol and relying on > > this behavior. This EmptyStmt approach sounds like a good option. > > Yeah, on second thought I have doubts about the throw-error approach too. > We've allowed this historically for a very long time, so I'm afraid we'd > get a lot of pushback if we change the external behavior now. I have a hard time believing this. Are we really believing that there's a significant number of clients preparing whitespace? We imo should at least change it in master. Unless I miss something there's really no reason for allowing it. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Tom Lane
Date:
Andres Freund <andres@2ndquadrant.com> writes: > On 2014-09-17 14:56:42 -0700, Tom Lane wrote: >> Yeah, on second thought I have doubts about the throw-error approach too. >> We've allowed this historically for a very long time, so I'm afraid we'd >> get a lot of pushback if we change the external behavior now. > I have a hard time believing this. Are we really believing that there's > a significant number of clients preparing whitespace? I don't know about "significant number", but the case is specifically called out as legal in the FE/BE protocol spec, for example here: Therefore, an Execute phase is always terminated by the appearance of exactly one of these messages: CommandComplete, EmptyQueryResponse (if the portal was created from an empty query string), ErrorResponse, or PortalSuspended. If we change it, that's a protocol break, and I don't think that being a tad cleaner is sufficient argument for that. regards, tom lane
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Tatsuo Ishii
Date:
>> I have a hard time believing this. Are we really believing that there's >> a significant number of clients preparing whitespace? > > I don't know about "significant number", but the case is specifically > called out as legal in the FE/BE protocol spec, for example here: > > Therefore, an Execute phase is always terminated by the appearance of > exactly one of these messages: CommandComplete, EmptyQueryResponse > (if the portal was created from an empty query string), ErrorResponse, > or PortalSuspended. > > If we change it, that's a protocol break, and I don't think that being a > tad cleaner is sufficient argument for that. Agreed. Thinking about that the simple protocol allows to use an empty query string, there's no reason to not allow it for the extended protocol. Best regards, -- Tatsuo Ishii SRA OSS, Inc. Japan English: http://www.sraoss.co.jp/index_en.php Japanese:http://www.sraoss.co.jp
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Bruce Momjian
Date:
On Wed, Sep 17, 2014 at 05:10:52PM -0700, Tom Lane wrote: > Andres Freund <andres@2ndquadrant.com> writes: > > On 2014-09-17 14:56:42 -0700, Tom Lane wrote: > >> Yeah, on second thought I have doubts about the throw-error approach too. > >> We've allowed this historically for a very long time, so I'm afraid we'd > >> get a lot of pushback if we change the external behavior now. > > > I have a hard time believing this. Are we really believing that there's > > a significant number of clients preparing whitespace? > > I don't know about "significant number", but the case is specifically > called out as legal in the FE/BE protocol spec, for example here: > > Therefore, an Execute phase is always terminated by the appearance of > exactly one of these messages: CommandComplete, EmptyQueryResponse > (if the portal was created from an empty query string), ErrorResponse, > or PortalSuspended. > > If we change it, that's a protocol break, and I don't think that being a > tad cleaner is sufficient argument for that. Where are we on this? -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + Everyone has their own god. +
Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.
From
Tom Lane
Date:
I wrote: > Michael Paquier <michael.paquier@gmail.com> writes: >> On Sat, Sep 6, 2014 at 1:34 PM, Andres Freund <andres@2ndquadrant.com> wrote: >>> On 2014-09-06 16:25:28 -0400, Tom Lane wrote: >>>> I don't think this fix is either appropriate or adequate. >>> Agreed (and commented offlist. Which probably was a mistake). >> This has not been reverted yet. Wouldn't it be better to do that asap? > Probably not until someone codes a better fix. I have it on my plate > to look into a better fix, but I've been horribly busy lately. I've applied a fix that takes the approach of explicitly testing for null plancache->raw_parse_tree whereever necessary. There were at least two places where there was no such test before; I think they are probably unreachable with an empty query (because no replanning could ever be needed) but it seems best to be consistent. regards, tom lane