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

Stephen Frost <[email protected]> Tue, 14 Jan 2020 15:12:07 -0500
Newsgroups gmane.comp.db.postgresql.devel.general
Message-ID <[email protected]>
--B68axRlCqbKl+xol
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Greetings,

* Tom Lane ([email protected]) wrote:
> I wrote:
> > Here's a draft patch that cleans up all the logic errors I could find.
>=20
> 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:
>=20
> * 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

--B68axRlCqbKl+xol
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAEBCgAGBQJeHiCXAAoJEO1sijiDR2RVWzQP/3cNQCcrxQhduV1YuRateJ/n
sGqumrJyJuO+yaodhIIkZHAXsuRPwjIPrtO0XXdHTcwan57J7Qc4jfX7Hu2jvGmw
ua1dm8NQYxcBNrm03FO+Fw7rKPZ5yL7VgVLAJGMgIKEhdW8Wxw+VWpqvNZEm9CP1
MV14D6TH/CYJB9jEQEb0+KSKXXhvxPNa2A3rnrJ+w3xr51OENMwGPK0C4J3SkbmM
w8U3HmRx38Y3tYwNP7dJ0EMpVqsxBY4vgvBZER9KqRRUl8SOmwTWcXhi5ZxMYpxf
oc5pQxcB9n1lOPZGkXZ3xkK13oL6BX7gtCoYjMvqZc3AaTmL/YVf1jxilv0wCVa/
7H/R2Jk3vog5JSxIqKyhtTQSqMJaUL8bAldiqzPIobJJs8LdSpIaQZ+5T/l8izH3
+63Fi/alJcirpqKNHbVc7QEblhItBbrqPqwmJRFAQrg6jWv+yK2BKsd/ozdyKftS
Xp9SON3eeJDpSwmtcAJaM6vLfXPanRQxo3xztlD1IRu7i/NSyjrT8DdXlPoaVNGh
86mM/RwkprWx/CsqKwPFPLgQCend/yRM/y4LZq+2c+Bszq6z0xuZn8UtHYm08KN3
/nFB44v0ukvFTojpUSqME5gEdr/FU/EuPDwKZ3mXITcuhz7hv/BzCTj54bfWfSX3
gjnPBRa/Q7E9dIMaOIYk
=1SU2
-----END PGP SIGNATURE-----

--B68axRlCqbKl+xol--