git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/7] pkt-line: prepare buffer before handling ERR packets

From
Jeff King <peff@peff.net>
Date
Apr 13, 2019, 05:54 UTC
Message-ID
<20190413055401.GD19495@sigill.intra.peff.net>
In-Reply-To
<20190413055127.GA32340@sigill.intra.peff.net>

Since 2d103c31c2 (pack-protocol.txt: accept error packets in any context, 2018-12-29), the pktline code will detect an ERR packet and die automatically, saving the caller from dealing with it. But we do so too early in the function, before we have terminated the buffer with a NUL.

As a result, passing the ERR message to die() may result in us printing random cruft from a previous packet. This doesn't trigger memory tools like ASan because we reuse the same buffer over and over (so the contents are valid and initialized; they're just stale).

We can see demonstrate this by tightening the regex we use to match the error message in t5516; without this patch, git-fetch will accidentally print the capabilities from the (much longer) initial packet we received.

By moving the ERR code later in the function we get a few other benefits, too:

  - we'll now chomp any newline sent by the other side (which is what we
    want, since die() will add its own newline)
  - we'll now mention the ERR packet with GIT_TRACE_PACKET
Signed-off-by: Jeff King <peff@peff.net>
---
 pkt-line.c            | 9 +++++----
 t/t5516-fetch-push.sh | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/pkt-line.c b/pkt-line.c
index ffd7220544..c9ed780d0b 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -350,16 +350,17 @@ enum packet_read_status packet_read_with_status(int fd, char **src_buffer,
 		return PACKET_READ_EOF;
 	}
 
-	if ((options & PACKET_READ_DIE_ON_ERR_PACKET) &&
-	    starts_with(buffer, "ERR "))
-		die(_("remote error: %s"), buffer + 4);
-
 	if ((options & PACKET_READ_CHOMP_NEWLINE) &&
 	    len && buffer[len-1] == '\n')
 		len--;
 
 	buffer[len] = 0;
 	packet_trace(buffer, len, 0);
+
+	if ((options & PACKET_READ_DIE_ON_ERR_PACKET) &&
+	    starts_with(buffer, "ERR "))
+		die(_("remote error: %s"), buffer + 4);
+
 	*pktlen = len;
 	return PACKET_READ_NORMAL;
 }
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 747dc4c31d..98ef71b48c 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1241,7 +1241,7 @@ do
 			git fetch ../testrepo/.git $SHA1_2 &&
 			git cat-file commit $SHA1_2 &&
 			test_must_fail git fetch ../testrepo/.git $SHA1_3 2>err &&
-			test_i18ngrep "remote error:.*not our ref" err
+			test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
 		)
 	'
 done
-- 
2.21.0.931.gd0bc72a411
Previous: Jeff KingNext: Jeff King
Message 5 of 9 in “some fetch reachability-error fixes”
  1. 0/7 some fetch reachability-error fixesJeff King, Apr 13, 2019
  2. 1/7 t5516: drop ok=sigpipe from unreachable-want testsJeff King, Apr 13, 2019
  3. 2/7 t5530: check protocol response for "not our ref"Jeff King, Apr 13, 2019
  4. 3/7 upload-pack: send ERR packet for non-tip objectsJeff King, Apr 13, 2019
  5. 4/7 pkt-line: prepare buffer before handling ERR packetsJeff King, Apr 13, 2019
  6. 5/7 fetch: use free_refs()Jeff King, Apr 13, 2019
  7. 6/7 remote.c: make singular free_ref() publicJeff King, Apr 13, 2019
  8. 7/7 fetch: do not consider peeled tags as advertised tipsJeff King, Apr 13, 2019
  9. Jonathan TanApr 15, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.