From fdfcfce7c6392d32f95a9f776ecd13da205b906c Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Wed, 23 Sep 2015 22:09:09 -0700 Subject: Fix over read in strcpy/stpcpy/strcat. This bug will happen when these circumstances are met: - Destination address & 0x7 == 1, strlen of src is 11, 12, 13. - Destination address & 0x7 == 2, strlen of src is 10, 11, 12. - Destination address & 0x7 == 3, strlen of src is 9, 10, 11. - Destination address & 0x7 == 4, strlen of src is 8, 9, 10. In these cases, the dest alignment code does a ldr which reads 4 bytes, and it will read past the end of the source. In most cases, this is probably benign, but if this crosses into a new page it could cause a crash. Fix the labels in the cortex-a9 strcat. Modify the overread test to vary the dst alignment to expost this bug. Also, shrink the strcat/strlcat overread cases since the dst alignment variation increases the runtime too much. Bug: 24345899 Change-Id: Ib34a559bfcebd89861985b29cae6c1e47b5b5855 --- tests/string_test.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'tests/string_test.cpp') diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 80190d7d7..842e1c7ee 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -1174,7 +1174,7 @@ static size_t LargeSetIncrement(size_t len) { return 1; } -#define STRCAT_DST_LEN 128 +#define STRCAT_DST_LEN 64 static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) { if (len >= 1) { @@ -1189,7 +1189,7 @@ static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) { int value2 = 32 + (value + 2) % 96; memset(cmp_buf, value2, sizeof(cmp_buf)); - for (size_t i = 1; i <= STRCAT_DST_LEN; i++) { + for (size_t i = 1; i <= STRCAT_DST_LEN;) { memset(dst, value2, i-1); memset(dst+i-1, 0, len-i); src[len-i] = '\0'; @@ -1197,6 +1197,13 @@ static void DoStrcatTest(uint8_t* src, uint8_t* dst, size_t len) { reinterpret_cast(src)))); ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0); ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0); + // This is an expensive loop, so don't loop through every value, + // get to a certain size and then start doubling. + if (i < 16) { + i++; + } else { + i <<= 1; + } } } else { dst[0] = '\0'; @@ -1229,7 +1236,7 @@ static void DoStrlcatTest(uint8_t* src, uint8_t* dst, size_t len) { int value2 = 32 + (value + 2) % 96; memset(cmp_buf, value2, sizeof(cmp_buf)); - for (size_t i = 1; i <= STRCAT_DST_LEN; i++) { + for (size_t i = 1; i <= STRCAT_DST_LEN;) { memset(dst, value2, i-1); memset(dst+i-1, 0, len-i); src[len-i] = '\0'; @@ -1237,6 +1244,13 @@ static void DoStrlcatTest(uint8_t* src, uint8_t* dst, size_t len) { reinterpret_cast(src), len)); ASSERT_TRUE(memcmp(dst, cmp_buf, i-1) == 0); ASSERT_TRUE(memcmp(src, dst+i-1, len-i+1) == 0); + // This is an expensive loop, so don't loop through every value, + // get to a certain size and then start doubling. + if (i < 16) { + i++; + } else { + i <<= 1; + } } } else { dst[0] = '\0'; -- cgit v1.2.3