diff options
author | Patrick Steinhardt <ps@pks.im> | 2018-10-19 10:29:19 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2018-10-25 12:52:54 +0200 |
commit | 7655b2d89e8275853d9921dd903dcdad9b3d4a7b (patch) | |
tree | bf0d287bfb216311c1a479e51a5c91d905bded77 | |
parent | c2e3d8ef699f310d353c2e378f12ea99ea4e0c67 (diff) | |
download | libgit2-7655b2d89e8275853d9921dd903dcdad9b3d4a7b.tar.gz |
commit: fix reading out of bounds when parsing encoding
The commit message encoding is currently being parsed by the
`git__prefixcmp` function. As this function does not accept a buffer
length, it will happily skip over a buffer's end if it is not `NUL`
terminated.
Fix the issue by using `git__prefixncmp` instead. Add a test that
verifies that we are unable to parse the encoding field if it's cut off
by the supplied buffer length.
-rw-r--r-- | src/commit.c | 2 | ||||
-rw-r--r-- | tests/object/commit/parse.c | 19 |
2 files changed, 20 insertions, 1 deletions
diff --git a/src/commit.c b/src/commit.c index 97ac2a189..bda5a8b42 100644 --- a/src/commit.c +++ b/src/commit.c @@ -444,7 +444,7 @@ int git_commit__parse_raw(void *_commit, const char *data, size_t size) while (eoln < buffer_end && *eoln != '\n') ++eoln; - if (git__prefixcmp(buffer, "encoding ") == 0) { + if (git__prefixncmp(buffer, buffer_end - buffer, "encoding ") == 0) { buffer += strlen("encoding "); commit->message_encoding = git__strndup(buffer, eoln - buffer); diff --git a/tests/object/commit/parse.c b/tests/object/commit/parse.c index 9ba8767cc..a99110f18 100644 --- a/tests/object/commit/parse.c +++ b/tests/object/commit/parse.c @@ -211,3 +211,22 @@ void test_object_commit_parse__parsing_commit_without_committer_fails(void) "Message"; assert_commit_fails(commit, 0); } + +void test_object_commit_parse__parsing_encoding_will_not_cause_oob_read(void) +{ + const char *commit = + "tree 3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8\n" + "author <>\n" + "committer <>\n" + "encoding foo\n"; + /* + * As we ignore unknown fields, the cut-off encoding field will be + * parsed just fine. + */ + assert_commit_parses(commit, strlen(commit) - strlen("ncoding foo\n"), + "3e7ac388cadacccdf1c6c5f3445895b71d9cb0f8", + "<>", + "<>", + NULL, + "", 0); +} |