summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_common_interceptors.inc
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2019-04-08 08:39:50 +0000
committerPavel Labath <pavel@labath.sk>2019-04-08 08:39:50 +0000
commitb68b25d43742155cb20177597d970ebeeb0e3dda (patch)
tree9f8a1ac13f37c5cf28e5925f35ff182fc3237c12 /lib/sanitizer_common/sanitizer_common_interceptors.inc
parent761390f20ad424b7f9793ff56e58634f78925002 (diff)
downloadcompiler-rt-b68b25d43742155cb20177597d970ebeeb0e3dda.tar.gz
[Sanitizer] Fix a possible write to freed memory in the wcrtomb interceptor
Summary: r357240 added an interceptor for wctomb, which uses a temporary local buffer to make sure we don't write to unallocated memory. This patch applies the same technique to wcrtomb, and adds some additional tests for this function. Reviewers: vitalybuka, eugenis Subscribers: kubamracek, delcypher, llvm-commits, #sanitizers Tags: #llvm, #sanitizers Differential Revision: https://reviews.llvm.org/D59984 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@357889 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common_interceptors.inc')
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc17
1 files changed, 10 insertions, 7 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index b3be48d75..bdecf7b0f 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -3524,13 +3524,16 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
- // FIXME: under ASan the call below may write to freed memory and corrupt
- // its metadata. See
- // https://github.com/google/sanitizers/issues/321.
- SIZE_T res = REAL(wcrtomb)(dest, src, ps);
- if (res != ((SIZE_T)-1) && dest) {
- SIZE_T write_cnt = res;
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+
+ if (!dest)
+ return REAL(wcrtomb)(dest, src, ps);
+
+ char local_dest[32];
+ SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);
+ if (res != ((SIZE_T)-1)) {
+ CHECK_LE(res, sizeof(local_dest));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
+ REAL(memcpy)(dest, local_dest, res);
}
return res;
}