git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH] packfile: Correct zlib buffer handling
@ 2018-05-25 22:56 Jeremy Linton
  2018-05-26  5:51 ` Duy Nguyen
  0 siblings, 1 reply; 10+ messages in thread
From: Jeremy Linton @ 2018-05-25 22:56 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, gitster, Jeremy Linton

The buffer being passed to zlib includes a null terminator that
git needs to keep in place. unpack_compressed_entry() attempts to
detect the case that the source buffer hasn't been fully consumed
by checking to see if the destination buffer has been over consumed.

This yields two problems, first a single byte overrun won't be detected
properly because the Z_STREAM_END will then be set, but the null
terminator will have been overwritten. The other problem is that
more recent zlib patches have been poisoning the unconsumed portions
of the buffers which also overwrites the null, while correctly
returning length and status.

Lets rely on the fact that the source buffer will only be fully
consumed when the when the destination buffer is inflated to the
correct size. We can do this by passing zlib the correct buffer size
and properly checking the return status. The latter check actually
already exists if the buffer size is correct.

Signed-off-by: Jeremy Linton <lintonrjeremy@gmail.com>
---
 packfile.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packfile.c b/packfile.c
index 7c1a2519f..245eb3204 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1416,7 +1416,7 @@ static void *unpack_compressed_entry(struct packed_git *p,
 		return NULL;
 	memset(&stream, 0, sizeof(stream));
 	stream.next_out = buffer;
-	stream.avail_out = size + 1;
+	stream.avail_out = size;
 
 	git_inflate_init(&stream);
 	do {
@@ -1424,7 +1424,7 @@ static void *unpack_compressed_entry(struct packed_git *p,
 		stream.next_in = in;
 		st = git_inflate(&stream, Z_FINISH);
 		if (!stream.avail_out)
-			break; /* the payload is larger than it should be */
+			break; /* done, st indicates if source fully consumed */
 		curpos += stream.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
 	git_inflate_end(&stream);
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH] packfile: Correct zlib buffer handling
@ 2018-05-25 23:17 Jeremy Linton
  2018-05-25 23:36 ` Eric Sunshine
  2018-05-26  1:06 ` Todd Zullinger
  0 siblings, 2 replies; 10+ messages in thread
From: Jeremy Linton @ 2018-05-25 23:17 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, gitster, Jeremy Linton

The buffer being passed to zlib includes a null terminator that
git needs to keep in place. unpack_compressed_entry() attempts to
detect the case that the source buffer hasn't been fully consumed
by checking to see if the destination buffer has been over consumed.

This yields two problems, first a single byte overrun won't be detected
properly because the Z_STREAM_END will then be set, but the null
terminator will have been overwritten. The other problem is that
more recent zlib patches have been poisoning the unconsumed portions
of the buffers which also overwrites the null, while correctly
returning length and status.

Lets rely on the fact that the source buffer will only be fully
consumed when the when the destination buffer is inflated to the
correct size. We can do this by passing zlib the correct buffer size
and properly checking the return status. The latter check actually
already exists if the buffer size is correct.

Signed-off-by: Jeremy Linton <lintonrjeremy@gmail.com>
---
 packfile.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packfile.c b/packfile.c
index 7c1a2519f..245eb3204 100644
--- a/packfile.c
+++ b/packfile.c
@@ -1416,7 +1416,7 @@ static void *unpack_compressed_entry(struct packed_git *p,
 		return NULL;
 	memset(&stream, 0, sizeof(stream));
 	stream.next_out = buffer;
-	stream.avail_out = size + 1;
+	stream.avail_out = size;
 
 	git_inflate_init(&stream);
 	do {
@@ -1424,7 +1424,7 @@ static void *unpack_compressed_entry(struct packed_git *p,
 		stream.next_in = in;
 		st = git_inflate(&stream, Z_FINISH);
 		if (!stream.avail_out)
-			break; /* the payload is larger than it should be */
+			break; /* done, st indicates if source fully consumed */
 		curpos += stream.next_in - in;
 	} while (st == Z_OK || st == Z_BUF_ERROR);
 	git_inflate_end(&stream);
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-06-13  1:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-25 22:56 [PATCH] packfile: Correct zlib buffer handling Jeremy Linton
2018-05-26  5:51 ` Duy Nguyen
2018-05-26 23:57   ` Junio C Hamano
2018-05-27  5:02     ` Duy Nguyen
2018-05-27 11:53       ` Junio C Hamano
2018-05-28  2:41         ` Junio C Hamano
2018-06-13  1:04           ` Jeremy Linton
  -- strict thread matches above, loose matches on Subject: below --
2018-05-25 23:17 Jeremy Linton
2018-05-25 23:36 ` Eric Sunshine
2018-05-26  1:06 ` Todd Zullinger

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).