From bf3fff1a9ed39d005f36db43c9893697e0a006a3 Mon Sep 17 00:00:00 2001 From: Branislav Rankov Date: Thu, 12 Oct 2017 15:08:42 +0200 Subject: libutils: Fix bug in strstr16. In the original code when target is an empty string strlen16() would start reading the memory until a "terminating null" (that is, zero) character is found. This may happen because "*target++", at line 300, would increment the pointer beyond the actual string. Signed-off-by: Branislav Rankov Signed-off-by: Tamas Petz Test: libutils_tests --gtest_filter=UnicodeTest.strstr16* Change-Id: I213ffe061057c7fa8f34b68881e106a709557dcd --- libutils/tests/Unicode_test.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'libutils/tests') diff --git a/libutils/tests/Unicode_test.cpp b/libutils/tests/Unicode_test.cpp index d23e43a71..b92eef866 100644 --- a/libutils/tests/Unicode_test.cpp +++ b/libutils/tests/Unicode_test.cpp @@ -15,7 +15,11 @@ */ #define LOG_TAG "Unicode_test" -#include + +#include +#include + +#include #include #include @@ -119,6 +123,31 @@ TEST_F(UnicodeTest, strstr16EmptyTarget) { << "should return the original pointer"; } +TEST_F(UnicodeTest, strstr16EmptyTarget_bug) { + // In the original code when target is an empty string strlen16() would + // start reading the memory until a "terminating null" (that is, zero) + // character is found. This happens because "*target++" in the original + // code would increment the pointer beyond the actual string. + void* memptr; + const size_t alignment = sysconf(_SC_PAGESIZE); + const size_t size = 2 * alignment; + ASSERT_EQ(posix_memalign(&memptr, alignment, size), 0); + // Fill allocated memory. + memset(memptr, 'A', size); + // Create a pointer to an "empty" string on the first page. + char16_t* const emptyString = (char16_t* const)((char*)memptr + alignment - 4); + *emptyString = (char16_t)0; + // Protect the second page to show that strstr16() violates that. + ASSERT_EQ(mprotect((char*)memptr + alignment, alignment, PROT_NONE), 0); + // Test strstr16(): when bug is present a segmentation fault is raised. + ASSERT_EQ(strstr16((char16_t*)memptr, emptyString), (char16_t*)memptr) + << "should not read beyond the first char16_t."; + // Reset protection of the second page + ASSERT_EQ(mprotect((char*)memptr + alignment, alignment, PROT_READ | PROT_WRITE), 0); + // Free allocated memory. + free(memptr); +} + TEST_F(UnicodeTest, strstr16SameString) { const char16_t* result = strstr16(kSearchString, kSearchString); EXPECT_EQ(kSearchString, result) -- cgit v1.2.3