[compiler-rt] r186002 - [sanitizer] Fix handling of edge cases in mbstowcs-like interceptors.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Wed Jul 10 07:01:51 PDT 2013
Author: eugenis
Date: Wed Jul 10 09:01:51 2013
New Revision: 186002
URL: http://llvm.org/viewvc/llvm-project?rev=186002&view=rev
Log:
[sanitizer] Fix handling of edge cases in mbstowcs-like interceptors.
Modified:
compiler-rt/trunk/lib/msan/tests/msan_test.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=186002&r1=186001&r2=186002&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Wed Jul 10 09:01:51 2013
@@ -1230,6 +1230,8 @@ TEST(MemorySanitizer, wcsrtombs) {
EXPECT_EQ(buff[0], 'a');
EXPECT_EQ(buff[1], 'b');
EXPECT_EQ(buff[2], 'c');
+ EXPECT_EQ(buff[3], '\0');
+ EXPECT_POISONED(buff[4]);
}
TEST(MemorySanitizer, wcsnrtombs) {
@@ -1241,7 +1243,7 @@ TEST(MemorySanitizer, wcsnrtombs) {
EXPECT_EQ(res, 2);
EXPECT_EQ(buff[0], 'a');
EXPECT_EQ(buff[1], 'b');
- EXPECT_EQ(buff[2], 0);
+ EXPECT_POISONED(buff[2]);
}
TEST(MemorySanitizer, mbtowc) {
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=186002&r1=186001&r2=186002&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Wed Jul 10 09:01:51 2013
@@ -1542,8 +1542,10 @@ INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *d
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
SIZE_T res = REAL(mbstowcs)(dest, src, len);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ if (res != (SIZE_T) - 1 && dest) {
+ SIZE_T write_cnt = res + (res < len);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
return res;
}
@@ -1555,8 +1557,12 @@ INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
}
SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ if (res != (SIZE_T)(-1) && dest && src) {
+ // This function, and several others, may or may not write the terminating
+ // \0 character. They write it iff they clear *src.
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
return res;
}
@@ -1577,8 +1583,10 @@ INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t
if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
}
SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
+ if (res != (SIZE_T)(-1) && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
return res;
}
@@ -1592,8 +1600,10 @@ INTERCEPTOR(SIZE_T, wcstombs, char *dest
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
SIZE_T res = REAL(wcstombs)(dest, src, len);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ if (res != (SIZE_T) - 1 && dest) {
+ SIZE_T write_cnt = res + (res < len);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
return res;
}
@@ -1605,8 +1615,10 @@ INTERCEPTOR(SIZE_T, wcsrtombs, char *des
COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
}
SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ if (res != (SIZE_T) - 1 && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
return res;
}
@@ -1627,8 +1639,10 @@ INTERCEPTOR(SIZE_T, wcsnrtombs, char *de
if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
}
SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
- if (res != (SIZE_T) - 1 && dest)
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
+ if (res != (SIZE_T) - 1 && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
return res;
}
More information about the llvm-commits
mailing list