Thread

  1. BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    TAKATSUKA Haruka <harukat@sraoss.co.jp> — 2014-09-02T11:16:53Z

    The following bug has been logged on the website:
    
    Bug reference:      11335
    Logged by:          invalid prepare statement causes crash at log_statement = &#39;mod&#39; or &#39;ddl&#39;.
    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
    
    
    
  2. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Fujii Masao <masao.fujii@gmail.com> — 2014-09-03T18:55:42Z

    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 = &#39;mod&#39; or &#39;ddl&#39;.
    > 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
    
    
    
  3. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Fujii Masao <masao.fujii@gmail.com> — 2014-09-04T17:33:48Z

    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 = &#39;mod&#39; or &#39;ddl&#39;.
    >> 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
    
    
    
  4. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Tom Lane <tgl@sss.pgh.pa.us> — 2014-09-06T20:25:28Z

    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
    
    
    
  5. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Andres Freund <andres@2ndquadrant.com> — 2014-09-06T20:34:10Z

    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
    
    
    
  6. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Michael Paquier <michael.paquier@gmail.com> — 2014-09-17T16:54:08Z

    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
    
    
    
  7. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Tom Lane <tgl@sss.pgh.pa.us> — 2014-09-17T21:56:42Z

    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
    
    
    
  8. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Andres Freund <andres@2ndquadrant.com> — 2014-09-17T21:58:57Z

    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
    
    
    
  9. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Tom Lane <tgl@sss.pgh.pa.us> — 2014-09-18T00:10:52Z

    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
    
    
    
  10. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Tatsuo Ishii <ishii@postgresql.org> — 2014-09-18T00:29:13Z

    >> 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
    
    
    
  11. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Bruce Momjian <bruce@momjian.us> — 2014-10-13T20:14:59Z

    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. +
    
    
    
  12. Re: BUG #11335: an invalid prepare statement causes crash at log_statement = 'mod' or 'ddl'.

    Tom Lane <tgl@sss.pgh.pa.us> — 2014-11-12T21:04:13Z

    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