Commit 868526138e131601c69f0949c58976700501881f

Patrick Steinhardt 2019-12-13T12:13:05

smart_pkt: fix overflow resulting in OOB read/write of one byte When parsing OK packets, we copy any information after the initial "ok " prefix into the resulting packet. As newlines act as packet boundaries, we also strip the trailing newline if there is any. We do not check whether there is any data left after the initial "ok " prefix though, which leads to a pointer overflow in that case as `len == 0`: if (line[len - 1] == '\n') --len; This out-of-bounds read is a rather useless gadget, as we can only deduce whether at some offset there is a newline character. In case there accidentally is one, we overflow `len` to `SIZE_MAX` and then write a NUL byte into an array indexed by it: pkt->ref[len] = '\0'; Again, this doesn't seem like something that's possible to be exploited in any meaningful way, but it may surely lead to inconsistencies or DoS. Fix the issue by checking whether there is any trailing data after the packet prefix.

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index 9bc273e..56b680d 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -273,7 +273,7 @@ static int ok_pkt(git_pkt **out, const char *line, size_t len)
 	line += 3;
 	len -= 3;
 
-	if (line[len - 1] == '\n')
+	if (len && line[len - 1] == '\n')
 		--len;
 
 	GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, len, 1);