Commit af9692ba by Patrick Steinhardt Committed by Edward Thomson

strntol: fix out-of-bounds read when skipping leading spaces

The `git__strntol` family of functions accepts leading spaces and will
simply skip them. The skipping will not honor the provided buffer's
length, though, which may lead it to read outside of the provided
buffer's bounds if it is not a simple NUL-terminated string.
Furthermore, if leading space is trimmed, the function will further
advance the pointer but not update the number of remaining bytes, which
may also lead to out-of-bounds reads.

Fix the issue by properly paying attention to the buffer length and
updating it when stripping leading whitespace characters. Add a test
that verifies that we won't read past the provided buffer length.
parent 6daeb4fb
...@@ -83,8 +83,11 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha ...@@ -83,8 +83,11 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
/* /*
* White space * White space
*/ */
while (git__isspace(*p)) while (nptr_len && git__isspace(*p))
p++; p++, nptr_len--;
if (!nptr_len)
goto Return;
/* /*
* Sign * Sign
......
...@@ -76,6 +76,16 @@ void test_core_strtol__buffer_length_truncates(void) ...@@ -76,6 +76,16 @@ void test_core_strtol__buffer_length_truncates(void)
cl_assert_equal_i(i64, 1); cl_assert_equal_i(i64, 1);
} }
void test_core_strtol__buffer_length_with_leading_ws_truncates(void)
{
int64_t i64;
cl_git_fail(git__strntol64(&i64, " 1", 1, NULL, 10));
cl_git_pass(git__strntol64(&i64, " 11", 2, NULL, 10));
cl_assert_equal_i(i64, 1);
}
void test_core_strtol__error_message_cuts_off(void) void test_core_strtol__error_message_cuts_off(void)
{ {
assert_l32_fails("2147483657foobar", 10); assert_l32_fails("2147483657foobar", 10);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment