pg.ddx.io  pgsql-bugs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Jacob Champion <jacob.champion@enterprisedb.com>
Cc: BATBAATAR Dorjpalam <htgn.dbat.95@gmail.com>
Cc: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #18907: SSL error: bad length failure during transfer data in pipeline mode with libpq
Date: Mon, 09 Jun 2025 20:40:38 -0400
Message-ID: <652538.1749516038@sss.pgh.pa.us> (raw)
In-Reply-To: <495420.1749488572@sss.pgh.pa.us>
References: <18907-d41b9bcf6f29edda@postgresql.org>
	<1055821.1745949960@sss.pgh.pa.us>
	<CAOYmi+kPBjLcHqbY1PK2bnvVJ90dBbJAp0vBfrDNHTdmscxvbg@mail.gmail.com>
	<1ba0f64a-9f35-4fb4-83b0-6c11a1b88740@gmail.com>
	<474412.1749479193@sss.pgh.pa.us>
	<495420.1749488572@sss.pgh.pa.us>

I wrote:
> Indeed, it looks like we'd better disable the round-down for GSSAPI
> too, because pg_GSS_write has exactly this same API requirement that
> caller has to pass at least as much data as last time.

So in short, I propose the attached patch.  I chose to disable the
round-down behavior for all TCP connections, including ones that
use neither SSL nor GSSAPI.  I'm not sure if it's worth worrying
too much about that case.

			regards, tom lane

Attachments:

  [text/x-diff] v1-fix-bug-18907.patch (3.5K, ../652538.1749516038@sss.pgh.pa.us/2-v1-fix-bug-18907.patch)
  download | inline diff:
diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c
index 3534f0b8111..5d98c58ffa8 100644
--- a/src/backend/libpq/be-secure-gssapi.c
+++ b/src/backend/libpq/be-secure-gssapi.c
@@ -121,9 +121,9 @@ be_gssapi_write(Port *port, const void *ptr, size_t len)
 	 * again, so if it offers a len less than that, something is wrong.
 	 *
 	 * Note: it may seem attractive to report partial write completion once
-	 * we've successfully sent any encrypted packets.  However, that can cause
-	 * problems for callers; notably, pqPutMsgEnd's heuristic to send only
-	 * full 8K blocks interacts badly with such a hack.  We won't save much,
+	 * we've successfully sent any encrypted packets.  However, doing that
+	 * expands the state space of this processing and has been responsible for
+	 * bugs in the past (cf. commit d053a879b).  We won't save much,
 	 * typically, by letting callers discard data early, so don't risk it.
 	 */
 	if (len < PqGSSSendConsumed)
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index c14e3c95250..dca44fdc5d2 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -553,9 +553,35 @@ pqPutMsgEnd(PGconn *conn)
 	/* Make message eligible to send */
 	conn->outCount = conn->outMsgEnd;
 
+	/* If appropriate, try to push out some data */
 	if (conn->outCount >= 8192)
 	{
-		int			toSend = conn->outCount - (conn->outCount % 8192);
+		int			toSend = conn->outCount;
+
+		/*
+		 * On Unix-pipe connections, it seems profitable to prefer sending
+		 * pipe-buffer-sized packets not randomly-sized ones, so retain the
+		 * last partial-8K chunk in our buffer for now.  On TCP connections,
+		 * the advantage of that is far less clear.  Moreover, it flat out
+		 * isn't safe when using SSL or GSSAPI, because those code paths have
+		 * API stipulations that if they fail to send all the data that was
+		 * offered in the previous write attempt, we mustn't offer less data
+		 * in this write attempt.  The previous write attempt might've been
+		 * pqFlush attempting to send everything in the buffer, so we mustn't
+		 * offer less now.  (Presently, we won't try to use SSL or GSSAPI on
+		 * Unix connections, so those checks are just Asserts.  They'll have
+		 * to become part of the regular if-test if we ever change that.)
+		 */
+		if (conn->raddr.addr.ss_family == AF_UNIX)
+		{
+#ifdef USE_SSL
+			Assert(!conn->ssl_in_use);
+#endif
+#ifdef ENABLE_GSS
+			Assert(!conn->gssenc);
+#endif
+			toSend -= toSend % 8192;
+		}
 
 		if (pqSendSome(conn, toSend) < 0)
 			return EOF;
diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c
index 62d05f68496..bc9e1ce06fa 100644
--- a/src/interfaces/libpq/fe-secure-gssapi.c
+++ b/src/interfaces/libpq/fe-secure-gssapi.c
@@ -112,9 +112,9 @@ pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
 	 * again, so if it offers a len less than that, something is wrong.
 	 *
 	 * Note: it may seem attractive to report partial write completion once
-	 * we've successfully sent any encrypted packets.  However, that can cause
-	 * problems for callers; notably, pqPutMsgEnd's heuristic to send only
-	 * full 8K blocks interacts badly with such a hack.  We won't save much,
+	 * we've successfully sent any encrypted packets.  However, doing that
+	 * expands the state space of this processing and has been responsible for
+	 * bugs in the past (cf. commit d053a879b).  We won't save much,
 	 * typically, by letting callers discard data early, so don't risk it.
 	 */
 	if (len < PqGSSSendConsumed)

view thread (8+ messages)

Message-ID: <652538.1749516038@sss.pgh.pa.us>
Permalink:  ../652538.1749516038@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/652538.1749516038@sss.pgh.pa.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-bugs@postgresql.org
  Cc: tgl@sss.pgh.pa.us, jacob.champion@enterprisedb.com, htgn.dbat.95@gmail.com, pgsql-bugs@lists.postgresql.org
  Subject: Re: BUG #18907: SSL error: bad length failure during transfer data in pipeline mode with libpq
  In-Reply-To: <652538.1749516038@sss.pgh.pa.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox