diff options
author | Patrick Steinhardt <ps@pks.im> | 2018-10-19 09:47:50 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2018-10-26 14:20:35 +0200 |
commit | 6e40bb3add388860eaf7b2cfec984cf396f10e30 (patch) | |
tree | 63380371e04cd49783ceac379a39e107b54e4c5c | |
parent | ab0d9fb2a8f2e9fd477c41922dfb56af19bb9027 (diff) | |
download | libgit2-6e40bb3add388860eaf7b2cfec984cf396f10e30.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.c | 10 |
1 files changed, 5 insertions, 5 deletions
@@ -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 |