Thread

Commits

  1. Extensive code review for GSSAPI encryption mechanism.

  1. 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Peter 'PMc' Much <pmc@citylink.dinoex.sub.org> — 2020-01-09T18:18:22Z

    Hi folks,
    
    with 12.1, after a couple of queries, at a random place, the clientlib
    does produce a failed query without giving reason or error-message [1].
    Then when retrying, the clientlib switches off signal handling and
    sits inactive in memory (needs kill -9).
    
    The server log shows no error or other hint.
    The behaviour happens rarely with trust access, and almost always when
    using Kerberos5 (Heimdal as included in FreeBSD).
    
    11.5 clientlib has none of this behaviour and seems to work fine, like
    10.10 did.
    
    Environment:
    	OS  	FreeBSD 11.3
    	Applic.	Ruby-on-Rails, ruby=2.5.7, gem 'pg'=1.2.2
    	        (it makes no difference if that one is compiled with
    		the 12.1 or the 10.10 library)
    	Server  12.1
    
    [1] the message from ruby is
        PG::ConnectionBad: PQconsumeInput() : <query>
    
    rgds,
    PMc
    
    
    
    
  2. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Adrian Klaver <adrian.klaver@aklaver.com> — 2020-01-09T18:47:00Z

    On 1/9/20 10:18 AM, Peter wrote:
    > Hi folks,
    > 
    > with 12.1, after a couple of queries, at a random place, the clientlib
    > does produce a failed query without giving reason or error-message [1].
    > Then when retrying, the clientlib switches off signal handling and
    > sits inactive in memory (needs kill -9).
    > 
    > The server log shows no error or other hint.
    > The behaviour happens rarely with trust access, and almost always when
    > using Kerberos5 (Heimdal as included in FreeBSD).
    > 
    > 11.5 clientlib has none of this behaviour and seems to work fine, like
    > 10.10 did.
    
    Might want to take at below:
    
    https://github.com/ged/ruby-pg/issues/311
    
    > 
    > Environment:
    > 	OS  	FreeBSD 11.3
    > 	Applic.	Ruby-on-Rails, ruby=2.5.7, gem 'pg'=1.2.2
    > 	        (it makes no difference if that one is compiled with
    > 		the 12.1 or the 10.10 library)
    > 	Server  12.1
    > 
    > [1] the message from ruby is
    >      PG::ConnectionBad: PQconsumeInput() : <query>
    > 
    > rgds,
    > PMc
    > 
    > 
    
    
    -- 
    Adrian Klaver
    adrian.klaver@aklaver.com
    
    
    
    
  3. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-09T18:48:01Z

    Peter <pmc@citylink.dinoex.sub.org> writes:
    > with 12.1, after a couple of queries, at a random place, the clientlib
    > does produce a failed query without giving reason or error-message [1].
    > Then when retrying, the clientlib switches off signal handling and
    > sits inactive in memory (needs kill -9).
    
    Seems like you'd better raise this with the author(s) of the "pg"
    Ruby gem.  Perhaps they read this mailing list, but more likely
    they have a specific bug reporting mechanism somewhere.
    
    			regards, tom lane
    
    
    
    
  4. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Peter 'PMc' Much <pmc@citylink.dinoex.sub.org> — 2020-01-09T20:53:17Z

    On Thu, Jan 09, 2020 at 10:47:00AM -0800, Adrian Klaver wrote:
    ! 
    ! Might want to take at below:
    ! 
    ! https://github.com/ged/ruby-pg/issues/311
    
    Thanks a lot! That option
    > gssencmode: "disable"
    seems to solve the issue.
    
    But I think the people there are concerned by a different issue: they
    are bothering about fork(), while my flaw appears also when I do *NOT*
    do fork. Also the picture is slightly different; they get segfaults, I
    get misbehaviour.
    
    rgds,
    PMc
    
    
    
    
  5. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Peter 'PMc' Much <pmc@citylink.dinoex.sub.org> — 2020-01-09T20:53:19Z

    On Thu, Jan 09, 2020 at 01:48:01PM -0500, Tom Lane wrote:
    ! Peter <pmc@citylink.dinoex.sub.org> writes:
    ! > with 12.1, after a couple of queries, at a random place, the clientlib
    ! > does produce a failed query without giving reason or error-message [1].
    ! > Then when retrying, the clientlib switches off signal handling and
    ! > sits inactive in memory (needs kill -9).
    ! 
    ! Seems like you'd better raise this with the author(s) of the "pg"
    ! Ruby gem.  Perhaps they read this mailing list, but more likely
    ! they have a specific bug reporting mechanism somewhere.
    
    Tom,
     I don't think this has anything to do with "pg". Just checked: I get
    garbage and misbehaviour on the "psql" command line tool also:
    
    $ psql -h myhost flowmdev
    psql (12.1)
    GSSAPI-encrypted connection
    Type "help" for help.
    
    flowmdev=> select * from flows;
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    flowmdev=> select * from flows;
    server sent data ("D" message) without prior row description ("T" message)
    flowmdev=> select * from flows;
    message type 0x54 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
    message type 0x44 arrived from server while idle
      id  |     name       |    ... <here finally starts the data as expected>
    
    
    To the contrary:
    
    $ PGGSSENCMODE="disable" psql -h myhost flowmdev
    psql (12.1)
    Type "help" for help.
    
    flowmdev=> select * from flows;
      id  |     name       |    ... <all working as normal>
    
    
    rgds,
    PMc
    
    
    
    
  6. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-09T21:31:44Z

    Peter <pmc@citylink.dinoex.sub.org> writes:
    >  I don't think this has anything to do with "pg". Just checked: I get
    > garbage and misbehaviour on the "psql" command line tool also:
    
    > $ psql -h myhost flowmdev
    > psql (12.1)
    > GSSAPI-encrypted connection
    > Type "help" for help.
    
    > flowmdev=> select * from flows;
    > message type 0x44 arrived from server while idle
    > message type 0x44 arrived from server while idle
    > message type 0x44 arrived from server while idle
    
    Oh ... that does look pretty broken.  However, we've had no other similar
    reports, so there must be something unique to your configuration.  Busted
    GSSAPI library, or some ABI inconsistency, perhaps?  What platform are you
    on, and how did you build or obtain this Postgres code?
    
    			regards, tom lane
    
    
    
    
  7. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Peter 'PMc' Much <pmc@citylink.dinoex.sub.org> — 2020-01-10T02:23:42Z

    On Thu, Jan 09, 2020 at 04:31:44PM -0500, Tom Lane wrote:
    ! Peter <pmc@citylink.dinoex.sub.org> writes:
    ! > flowmdev=> select * from flows;
    ! > message type 0x44 arrived from server while idle
    ! > message type 0x44 arrived from server while idle
    ! > message type 0x44 arrived from server while idle
    ! 
    ! Oh ... that does look pretty broken.  However, we've had no other similar
    ! reports, so there must be something unique to your configuration.  Busted
    ! GSSAPI library, or some ABI inconsistency, perhaps?  What platform are you
    ! on, and how did you build or obtain this Postgres code?
    
    This is a FreeBSD 11.3-p3 r351611 built from source. Postgres is built
    from
    https://svn0.eu.freebsd.org/ports/branches/2019Q4  (rel. 12r1)  or
    https://svn0.eu.freebsd.org/ports/branches/2020Q1  (rel. 12.1)
    with "make package install".
    I have a build environment for base&ports that forces recompiles on
    any change and should make ABI inconsistencies quite hard to create.
    
    All local patches are versioned and documented; there are none that
    I could imagine influencing this.
    There are no patches on postgres. Also no patches on the GSSAPI.
    There are a couple of patches on the Heimdal, to fix broken
    commandline parsing, broken pidfile handling and broken daemonization.
    None of them touches the core functionality (like key handling).
    
    But I just recognize something of interest (which I had taken for
    granted when importing the database): the flaw does NOT appear when
    accessing the database from the server's local system (with TCP and
    GSSAPI encryption active). Only from remote system.
    
    But then, if I go on the local system, and change the mtu:
    # ifconfig lo0 mtu 1500
    and restart the server, then I get the exact same errors locally.
    
    I don't get a clue of that, it doesn't make sense. With the default
    lo0 mtu of 16384 the packets go on the network with the full 8256
    bytes you send. With mtu 1500 they are split into 1448 byte pieces;
    but TCP is supposed to handle this transparently. And what difference
    would the encryption make with this?
    > net.inet.tcp.sendspace: 32768
    > net.inet.tcp.recvspace: 65536
    These are also bigger. No, I don't understand that.
    
    The only thing - these are all VIMAGE jails. VIMAGE was considered
    'experimental' some time ago, and went productive in FreeBSD 12.0, 
    and 11.3 is lower and later than 12.0 - whatever that concedes.
    
    Another thing I found out: the slower the network, the worse the
    errors. So might it be nobody complained just because those people
    usually having GSSAPI also have very fast machines and networks
    nowadays?
    
    When I go to packet-radio speed:
    # ipfw pipe 4 config bw 10kbit/s
    
    then I can see the query returning empty at the first received bytes:
    flowmdev=# select * from flows;
    flowmdev=# 
    
    and not even waiting the 8 seconds for the first block to arrive.
    
    
    rgds,
    PMc
    
    
    
    
  8. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-10T17:59:09Z

    [ redirecting to -hackers ]
    
    Peter <pmc@citylink.dinoex.sub.org> writes:
    > But I just recognize something of interest (which I had taken for
    > granted when importing the database): the flaw does NOT appear when
    > accessing the database from the server's local system (with TCP and
    > GSSAPI encryption active). Only from remote system.
    > But then, if I go on the local system, and change the mtu:
    > # ifconfig lo0 mtu 1500
    > and restart the server, then I get the exact same errors locally.
    
    Oh-ho, that is interesting.
    
    Looking at our regression tests for gssenc, I observe that they
    only try to transport a negligible amount of data (viz, single-row
    boolean results).  So we'd not notice any problem that involved
    multiple-packet messages.
    
    I modified the kerberos test so that it tries a query with a less
    negligible amount of data, and what I find is:
    
    * passes on Fedora 30, with either default or 1500 mtu
    * passes on FreeBSD 12.0 with default mtu
    * FAILS on FreeBSD 12.0 with mtu = 1500
    
    I haven't run it further to ground than that, but there's definitely
    something fishy here.  Based on just these results one would be hard
    pressed to say if it's our bug or FreeBSD's, but your report that you
    don't see the failure with PG 11 makes it sound like our problem.
    
    OTOH, I also find that there's some hysteresis in the behavior:
    once it's failed, reverting the mtu to the default setting doesn't
    necessarily make subsequent runs pass.  It's really hard to explain
    that behavior if it's our bug.
    
    I tested today's HEAD of our code with up-to-date FreeBSD 12.0-RELEASE-p12
    running on amd64 bare metal, no jails or emulators or VIMAGE or anything.
    
    Attached are proposed test patch, as well as client-side regression log
    output from a failure.  (There's no evidence of distress in the
    postmaster log, same as your report.)
    
    			regards, tom lane
    
    
  9. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-10T19:25:22Z

    I wrote:
    > I haven't run it further to ground than that, but there's definitely
    > something fishy here.  Based on just these results one would be hard
    > pressed to say if it's our bug or FreeBSD's, but your report that you
    > don't see the failure with PG 11 makes it sound like our problem.
    
    Ah, I have it: whoever wrote pg_GSS_read() failed to pay attention
    to the fact that setting errno is a critical part of its API.
    Sometimes it returns -1 while leaving errno in a state that causes
    pqReadData to draw the wrong conclusions.  In particular that can
    happen when it reads an incomplete packet, and that's very timing
    dependent, which is why this is so ticklish to reproduce.
    
    I'll have a patch in a little while.
    
    			regards, tom lane
    
    
    
    
  10. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Stephen Frost <sfrost@snowman.net> — 2020-01-10T20:38:07Z

    Greetings,
    
    * Tom Lane (tgl@sss.pgh.pa.us) wrote:
    > I wrote:
    > > I haven't run it further to ground than that, but there's definitely
    > > something fishy here.  Based on just these results one would be hard
    > > pressed to say if it's our bug or FreeBSD's, but your report that you
    > > don't see the failure with PG 11 makes it sound like our problem.
    > 
    > Ah, I have it: whoever wrote pg_GSS_read() failed to pay attention
    > to the fact that setting errno is a critical part of its API.
    > Sometimes it returns -1 while leaving errno in a state that causes
    > pqReadData to draw the wrong conclusions.  In particular that can
    > happen when it reads an incomplete packet, and that's very timing
    > dependent, which is why this is so ticklish to reproduce.
    
    Ah-hah.  Not sure if that was Robbie or myself (probably me, really,
    since I rewrote a great deal of that code).  I agree that the regression
    tests don't test with very much data, but I tested pushing quite a bit
    of data through and didn't see any issues with my testing.  Apparently I
    was getting pretty lucky. :/
    
    > I'll have a patch in a little while.
    
    That's fantastic, thanks!
    
    Stephen
    
  11. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-10T20:58:10Z

    Stephen Frost <sfrost@snowman.net> writes:
    > Ah-hah.  Not sure if that was Robbie or myself (probably me, really,
    > since I rewrote a great deal of that code).  I agree that the regression
    > tests don't test with very much data, but I tested pushing quite a bit
    > of data through and didn't see any issues with my testing.  Apparently I
    > was getting pretty lucky. :/
    
    You were *very* lucky, because this code is absolutely full of mistakes
    related to incomplete reads, inadequate or outright wrong error handling,
    etc.
    
    I was nearly done cleaning that up, when it sank into me that
    fe-secure-gssapi.c uses static buffers for partially-read or
    partially-encoded data.  That means that any client trying to use
    multiple GSSAPI-encrypted connections is very likely to see breakage
    due to different connections trying to use the same buffers concurrently.
    I wonder whether that doesn't explain the complaints mentioned upthread
    from the Ruby folks.
    
    (be-secure-gssapi.c is coded identically, but there it's OK since
    any backend only has one client connection to deal with.)
    
    >> I'll have a patch in a little while.
    
    > That's fantastic, thanks!
    
    This is gonna take longer than I thought.
    
    			regards, tom lane
    
    
    
    
  12. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Peter 'PMc' Much <pmc@citylink.dinoex.sub.org> — 2020-01-10T21:03:37Z

    On Fri, Jan 10, 2020 at 12:59:09PM -0500, Tom Lane wrote:
    ! [ redirecting to -hackers ]
    
    ! I modified the kerberos test so that it tries a query with a less
    ! negligible amount of data, and what I find is:
    ! 
    ! * passes on Fedora 30, with either default or 1500 mtu
    ! * passes on FreeBSD 12.0 with default mtu
    ! * FAILS on FreeBSD 12.0 with mtu = 1500
    
    So, it is not related to only VIMAGE @ R11.3, and -more important to
    me- it is not only happening in my kitchen. Thank You very much :)
    
    ! OTOH, I also find that there's some hysteresis in the behavior:
    ! once it's failed, reverting the mtu to the default setting doesn't
    ! necessarily make subsequent runs pass.  It's really hard to explain
    ! that behavior if it's our bug.
    
    That's affirmative. Made me go astray a few times when trying to
    isolate it.
    
    On Fri, Jan 10, 2020 at 02:25:22PM -0500, Tom Lane wrote:
    ! Ah, I have it: whoever wrote pg_GSS_read() failed to pay attention
    ! to the fact that setting errno is a critical part of its API.
    ! Sometimes it returns -1 while leaving errno in a state that causes
    
    Wow, that's fast. My probability-guess this morning was either some
    hard-coded 8192-byte buffer, or something taking an [EWOULDBLOCK] for
    OK. Then I decided to not look into the code, as You will be much
    faster anyway, and there are other pieces of software where I do
    not have such a competent peer to talk to...
    
    Anyway, thanks a lot!
    PMc
    
    
    
    
  13. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Stephen Frost <sfrost@snowman.net> — 2020-01-10T21:09:24Z

    Greetings,
    
    On Fri, Jan 10, 2020 at 15:58 Tom Lane <tgl@sss.pgh.pa.us> wrote:
    
    > Stephen Frost <sfrost@snowman.net> writes:
    > > Ah-hah.  Not sure if that was Robbie or myself (probably me, really,
    > > since I rewrote a great deal of that code).  I agree that the regression
    > > tests don't test with very much data, but I tested pushing quite a bit
    > > of data through and didn't see any issues with my testing.  Apparently I
    > > was getting pretty lucky. :/
    >
    > You were *very* lucky, because this code is absolutely full of mistakes
    > related to incomplete reads, inadequate or outright wrong error handling,
    > etc.
    
    
    I guess so..  I specifically remember running into problems transferring
    large data sets before I rewrote the code but after doing so it was
    reliable (for me anyway...).
    
    I was nearly done cleaning that up, when it sank into me that
    > fe-secure-gssapi.c uses static buffers for partially-read or
    > partially-encoded data.  That means that any client trying to use
    > multiple GSSAPI-encrypted connections is very likely to see breakage
    > due to different connections trying to use the same buffers concurrently.
    
    
    Ughhh. That’s a completely valid point and one I should have thought of.
    
    I wonder whether that doesn't explain the complaints mentioned upthread
    > from the Ruby folks.
    
    
    No- the segfault issue has been demonstrated to be able to reproduce
    without any PG code involved at all, and it also involved threads with only
    one connection, at least as I recall (on my phone atm).
    
    (be-secure-gssapi.c is coded identically, but there it's OK since
    > any backend only has one client connection to deal with.)
    
    
    Right...  I actually wrote the backend code first and then largely copied
    it to the front end, and then adjusted it, but obviously insufficiently as
    I had been thinking of just the one connection that the backend has to deal
    with.
    
    Thanks!
    
    Stephen
    
  14. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-11T03:51:50Z

    Here's a draft patch that cleans up all the logic errors I could find.
    
    I also expanded the previous patch for the kerberos test so that it
    verifies that we can upload a nontrivial amount of data to the server,
    as well as download.
    
    I also spent a fair amount of effort on removing cosmetic differences
    between the comparable logic in be-secure-gssapi.c and fe-secure-gssapi.c,
    such that the two files can now be diff'd to confirm that be_gssapi_write
    and be_gssapi_read implement identical logic to pg_GSS_write and
    pg_GSS_read.  (They did not, before :-(.)
    
    This does not deal with the problem that libpq shouldn't be using
    static data space for this purpose.  It seems reasonable to me to
    leave that for a separate patch.
    
    This passes tests for me, on my FreeBSD build with lo0 mtu = 1500.
    It wouldn't hurt to get some more mileage on it though.  Peter,
    I didn't follow how to set up the "packet radio speed" environment
    that you mentioned, but if you could beat on this with that setup
    it would surely be useful.
    
    			regards, tom lane
    
    
  15. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-11T15:28:15Z

    I wrote:
    > Here's a draft patch that cleans up all the logic errors I could find.
    
    So last night I was assuming that this problem just requires more careful
    attention to what to return in the error exit paths.  In the light of
    morning, though, I realize that the algorithms involved in
    be-secure-gssapi.c and fe-secure-gssapi.c are just fundamentally wrong:
    
    * On the read side, the code will keep looping until it gets a no-data
    error from the underlying socket call.  This is silly.  In every or
    almost every use, the caller's read length request corresponds to the
    size of a buffer that's meant to be larger than typical messages, so
    that betting that we're going to fill that buffer completely is the
    wrong way to bet.  Meanwhile, it's fairly likely that the incoming
    encrypted packet's length *does* correspond to some actual message
    boundary; that would only not happen if the sender is forced to break
    up a message, which ought to be a minority situation, else our buffer
    size choices are too small.  So it's very likely that the looping just
    results in doubling the number of read() calls that are made, with
    half of them failing with EWOULDBLOCK.  What we should do instead is
    return to the caller whenever we finish handing back the decrypted
    contents of a packet.  We can do the read() on the next call, after
    the caller's dealt with that data.
    
    * On the write side, if the code encrypts some data and then gets
    EWOULDBLOCK trying to write it, it will tell the caller that it
    successfully wrote that data.  If that was all the data the caller
    had to write (again, not so unlikely) this is a catastrophic
    mistake, because the caller will be satisfied and will go to sleep,
    rather than calling again to attempt another write.  What we *must*
    do is to reflect the write failure verbatim whether or not we
    encrypted some data.  We must remember how much data we encrypted
    and then discount that much of the caller's supplied data next time.
    There are hints in the existing comments that somebody understood
    this at one point, but the code isn't acting that way today.
    
    I expect that I can prove point B by hot-wiring pqsecure_raw_write
    to randomly return EWOULDBLOCK (instead of making any write attempt)
    every so often.  I think strace will be enough to confirm point A,
    but haven't tried it yet.
    
    			regards, tom lane
    
    
    
    
  16. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-11T20:37:43Z

    I wrote:
    > So last night I was assuming that this problem just requires more careful
    > attention to what to return in the error exit paths.  In the light of
    > morning, though, I realize that the algorithms involved in
    > be-secure-gssapi.c and fe-secure-gssapi.c are just fundamentally wrong:
    
    Here's a revised patch that attempts to deal with those issues.
    (Still doesn't touch the static-buffer issue, though.)
    
    The 0002 patch isn't meant for commit, but testing with that gives me
    a whole lot more confidence that the gssapi code deals with EWOULDBLOCK
    correctly.
    
    			regards, tom lane
    
    
  17. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-11T21:42:31Z

    I wrote:
    > (Still doesn't touch the static-buffer issue, though.)
    
    And here's a delta patch for that.  This fixes an additional portability
    hazard, which is that there were various places doing stuff like
    
    		input.length = ntohl(*(uint32 *) PqGSSRecvBuffer);
    
    That's a SIGBUS hazard on alignment-picky hardware, because there is
    no guarantee that a variable that's just declared "char ...[...]"
    will have any particular alignment.  But malloc'ing the space will
    provide maxaligned storage.
    
    My FreeBSD testing has now given me enough confidence in these patches
    that I'm just going to go ahead and push them.  But, if you'd like to
    do some more testing in advance of 12.2 release, please do.
    
    			regards, tom lane
    
    
  18. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Peter 'PMc' Much <pmc@citylink.dinoex.sub.org> — 2020-01-12T18:36:33Z

    On Fri, Jan 10, 2020 at 10:51:50PM -0500, Tom Lane wrote:
    ! Here's a draft patch that cleans up all the logic errors I could find.
    
    Okiee, thank You!
    Let's see (was a bit busy yesterday trying to upgrade pgadmin3 -
    difficult matter), now lets sort this out:
    
    With the first patch applied (as from Friday - applied only on the
    client side), the application did appear to work well.
    
    But then, when engaging bandwidth-limiting to some modem-speed, it did
    not work: psql would receive all (or most of) the data from a SELECT,
    but then somehow not recognize the end of it and sit there and wait for
    whatever:
    
    > flowmdev=> select * from flows;
    > ^CCancel request sent
    > ^CCancel request sent
    
    
    Now with the new patches 0001+0003 applied, on both server & client,
    all now running 12.1 release, on a first run I did not perceive
    a malfunction, bandwidth limited or not.
    I'll leave them applied, but this here will not experience serious
    loads; You'll need somebody else to test for that...
    
    
    rgds,
    PMc
    
    
    
    
  19. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-12T19:46:25Z

    Peter <pmc@citylink.dinoex.sub.org> writes:
    > With the first patch applied (as from Friday - applied only on the
    > client side), the application did appear to work well.
    > But then, when engaging bandwidth-limiting to some modem-speed, it did
    > not work: psql would receive all (or most of) the data from a SELECT,
    > but then somehow not recognize the end of it and sit there and wait for
    > whatever:
    
    Yeah, that's just the behavior I'd expect (and was able to reproduce
    here) because of the additional design problem.
    
    > Now with the new patches 0001+0003 applied, on both server & client,
    > all now running 12.1 release, on a first run I did not perceive
    > a malfunction, bandwidth limited or not.
    > I'll leave them applied, but this here will not experience serious
    > loads; You'll need somebody else to test for that...
    
    Cool, let us know if you do see any problems.
    
    			regards, tom lane
    
    
    
    
  20. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Stephen Frost <sfrost@snowman.net> — 2020-01-14T20:12:07Z

    Greetings,
    
    * Tom Lane (tgl@sss.pgh.pa.us) wrote:
    > I wrote:
    > > Here's a draft patch that cleans up all the logic errors I could find.
    > 
    > So last night I was assuming that this problem just requires more careful
    > attention to what to return in the error exit paths.  In the light of
    > morning, though, I realize that the algorithms involved in
    > be-secure-gssapi.c and fe-secure-gssapi.c are just fundamentally wrong:
    > 
    > * On the read side, the code will keep looping until it gets a no-data
    > error from the underlying socket call.  This is silly.  In every or
    > almost every use, the caller's read length request corresponds to the
    > size of a buffer that's meant to be larger than typical messages, so
    > that betting that we're going to fill that buffer completely is the
    > wrong way to bet.  Meanwhile, it's fairly likely that the incoming
    > encrypted packet's length *does* correspond to some actual message
    > boundary; that would only not happen if the sender is forced to break
    > up a message, which ought to be a minority situation, else our buffer
    > size choices are too small.  So it's very likely that the looping just
    > results in doubling the number of read() calls that are made, with
    > half of them failing with EWOULDBLOCK.  What we should do instead is
    > return to the caller whenever we finish handing back the decrypted
    > contents of a packet.  We can do the read() on the next call, after
    > the caller's dealt with that data.
    
    Yeah, I agree that this is a better approach.  Doing unnecessary
    read()'s certainly isn't ideal but beyond being silly it doesn't sound
    like this was fundamentally broken..? (yes, the error cases certainly
    weren't properly being handled, I understand that)
    
    > * On the write side, if the code encrypts some data and then gets
    > EWOULDBLOCK trying to write it, it will tell the caller that it
    > successfully wrote that data.  If that was all the data the caller
    > had to write (again, not so unlikely) this is a catastrophic
    > mistake, because the caller will be satisfied and will go to sleep,
    > rather than calling again to attempt another write.  What we *must*
    > do is to reflect the write failure verbatim whether or not we
    > encrypted some data.  We must remember how much data we encrypted
    > and then discount that much of the caller's supplied data next time.
    > There are hints in the existing comments that somebody understood
    > this at one point, but the code isn't acting that way today.
    
    That's a case I hadn't considered and you're right- the algorithm
    certainly wouldn't work in such a case.  I don't recall specifically if
    the code had handled it better previously, or not, but I do recall there
    was something previously about being given a buffer and then having the
    API defined as "give me back the exact same buffer because I had to
    stop" and I recall finding that to ugly, but I get it now, seeing this
    issue.  I'd certainly be happier if there was a better alternative but I
    don't know that there really is.
    
    Thanks,
    
    Stephen
    
  21. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Tom Lane <tgl@sss.pgh.pa.us> — 2020-01-14T20:22:00Z

    Stephen Frost <sfrost@snowman.net> writes:
    > * Tom Lane (tgl@sss.pgh.pa.us) wrote:
    >> ... We must remember how much data we encrypted
    >> and then discount that much of the caller's supplied data next time.
    >> There are hints in the existing comments that somebody understood
    >> this at one point, but the code isn't acting that way today.
    
    > That's a case I hadn't considered and you're right- the algorithm
    > certainly wouldn't work in such a case.  I don't recall specifically if
    > the code had handled it better previously, or not, but I do recall there
    > was something previously about being given a buffer and then having the
    > API defined as "give me back the exact same buffer because I had to
    > stop" and I recall finding that to ugly, but I get it now, seeing this
    > issue.  I'd certainly be happier if there was a better alternative but I
    > don't know that there really is.
    
    Yeah.  The only bright spot is that there's no reason for the caller
    to change its mind about what it wants to write, so that this restriction
    doesn't really affect anything.  (The next call might potentially add
    *more* data at the end, but that's fine.)
    
    I realized when I got into it that my sketch above also considered only
    part of the problem.  In the general case, we might've encrypted some data
    from the current write request and successfully sent it, and then
    encrypted some more data but been unable to (fully) send that packet.
    In this situation, it's best to report that we wrote however much data
    corresponds to the fully sent packet(s).  That way the caller can discard
    that data from its buffer.  We can't report the data corresponding to the
    in-progress packet as being written, though, or we have the
    might-not-get-another-call problem.  Fortunately the API already has the
    notion of a partial write, since the underlying socket calls do.
    
    			regards, tom lane
    
    
    
    
  22. Re: 12.1 not useable: clientlib fails after a dozen queries (GSSAPI ?)

    Stephen Frost <sfrost@snowman.net> — 2020-01-14T20:45:17Z

    Greetings,
    
    * Tom Lane (tgl@sss.pgh.pa.us) wrote:
    > Stephen Frost <sfrost@snowman.net> writes:
    > > * Tom Lane (tgl@sss.pgh.pa.us) wrote:
    > >> ... We must remember how much data we encrypted
    > >> and then discount that much of the caller's supplied data next time.
    > >> There are hints in the existing comments that somebody understood
    > >> this at one point, but the code isn't acting that way today.
    > 
    > > That's a case I hadn't considered and you're right- the algorithm
    > > certainly wouldn't work in such a case.  I don't recall specifically if
    > > the code had handled it better previously, or not, but I do recall there
    > > was something previously about being given a buffer and then having the
    > > API defined as "give me back the exact same buffer because I had to
    > > stop" and I recall finding that to ugly, but I get it now, seeing this
    > > issue.  I'd certainly be happier if there was a better alternative but I
    > > don't know that there really is.
    > 
    > Yeah.  The only bright spot is that there's no reason for the caller
    > to change its mind about what it wants to write, so that this restriction
    > doesn't really affect anything.  (The next call might potentially add
    > *more* data at the end, but that's fine.)
    
    Right, makes sense.
    
    > I realized when I got into it that my sketch above also considered only
    > part of the problem.  In the general case, we might've encrypted some data
    > from the current write request and successfully sent it, and then
    > encrypted some more data but been unable to (fully) send that packet.
    > In this situation, it's best to report that we wrote however much data
    > corresponds to the fully sent packet(s).  That way the caller can discard
    > that data from its buffer.  We can't report the data corresponding to the
    > in-progress packet as being written, though, or we have the
    > might-not-get-another-call problem.  Fortunately the API already has the
    > notion of a partial write, since the underlying socket calls do.
    
    Yeah, I see how that's also an issue and agree that it makes sense to
    report back what's been written and sent as a partial write, and not
    report back everything we've "consumed" since we might not get called
    again in that case.
    
    Thanks!
    
    Stephen