summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2018-10-19 09:47:50 +0200
committerPatrick Steinhardt <ps@pks.im>2018-10-25 12:56:06 +0200
commit53fd88739e355f54796ebd7f36430b5a62fa80e0 (patch)
tree8a55818ae910ab62665e3100a262a2e23feb6e59
parent74a1557b6cc6c7c7f888a9d394317a4ebb0674d3 (diff)
downloadlibgit2-53fd88739e355f54796ebd7f36430b5a62fa80e0.tar.gz
tag: fix out of bounds read when searching for tag message
When parsing tags, we skip all unknown fields that appear before the tag message. This skipping is done by using a plain `strstr(buffer, "\n\n")` to search for the two newlines that separate tag fields from tag message. As it is not possible to supply a buffer length to `strstr`, this call may skip over the buffer's end and thus result in an out of bounds read. As `strstr` may return a pointer that is out of bounds, the following computation of `buffer_end - buffer` will overflow and result in an allocation of an invalid length. Fix the issue by using `git__memmem` instead. Add a test that verifies parsing the tag fails not due to the allocation failure but due to the tag having no message. (cherry picked from commit ee11d47e3d907b66eeff99e0ba1e1c71e05164b7)
-rw-r--r--src/tag.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/tag.c b/src/tag.c
index 2bf23fc3c..a0e968f38 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -70,10 +70,9 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
static const char *tag_types[] = {
NULL, "commit\n", "tree\n", "blob\n", "tag\n"
};
-
- unsigned int i;
size_t text_len, alloc_len;
- char *search;
+ const char *search;
+ unsigned int i;
if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0)
return tag_error("object field invalid");
@@ -138,8 +137,9 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
tag->message = NULL;
if (buffer < buffer_end) {
/* If we're not at the end of the header, search for it */
- if( *buffer != '\n' ) {
- search = strstr(buffer, "\n\n");
+ if(*buffer != '\n') {
+ search = git__memmem(buffer, buffer_end - buffer,
+ "\n\n", 2);
if (search)
buffer = search + 1;
else