Skip to content

Commit d568e53

Browse files
justincadyvitalybuka
authored andcommitted
[MSAN] Fix wordexp interception when WRDE_DOOFFS is used
Handle the case of wordexp being invoked with WRDE_DOOFFS and we.we_offs set to a positive value, which will result in NULL entries prepended to the result. With this change the entire result, containing both NULL and actual entries, is unpoisoned. Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D108646
1 parent 4d235bf commit d568e53

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed

compiler-rt/lib/msan/tests/msan_test.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3760,6 +3760,18 @@ TEST(MemorySanitizer, wordexp) {
37603760
ASSERT_STREQ("c", w.we_wordv[2]);
37613761
}
37623762

3763+
TEST(MemorySanitizer, wordexp_initial_offset) {
3764+
wordexp_t w;
3765+
w.we_offs = 1;
3766+
int res = wordexp("a b c", &w, WRDE_DOOFFS);
3767+
ASSERT_EQ(0, res);
3768+
ASSERT_EQ(3U, w.we_wordc);
3769+
ASSERT_EQ(nullptr, w.we_wordv[0]);
3770+
ASSERT_STREQ("a", w.we_wordv[1]);
3771+
ASSERT_STREQ("b", w.we_wordv[2]);
3772+
ASSERT_STREQ("c", w.we_wordv[3]);
3773+
}
3774+
37633775
template<class T>
37643776
static bool applySlt(T value, T shadow) {
37653777
__msan_partial_poison(&value, &shadow, sizeof(T));

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3996,10 +3996,12 @@ INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
39963996
int res = REAL(wordexp)(s, p, flags);
39973997
if (!res && p) {
39983998
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
3999-
if (p->we_wordc)
3999+
uptr we_wordc =
4000+
((flags & wordexp_wrde_dooffs) ? p->we_wordc : 0) + p->we_wordc;
4001+
if (we_wordc)
40004002
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
4001-
sizeof(*p->we_wordv) * p->we_wordc);
4002-
for (uptr i = 0; i < p->we_wordc; ++i) {
4003+
sizeof(*p->we_wordv) * we_wordc);
4004+
for (uptr i = 0; i < we_wordc; ++i) {
40034005
char *w = p->we_wordv[i];
40044006
if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);
40054007
}

compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
313313
int glob_altdirfunc = GLOB_ALTDIRFUNC;
314314
#endif
315315

316+
# if !SANITIZER_ANDROID
317+
const int wordexp_wrde_dooffs = WRDE_DOOFFS;
318+
# endif // !SANITIZER_ANDROID
319+
316320
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
317321
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
318322
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \

compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,10 @@ extern int glob_altdirfunc;
776776

777777
extern unsigned path_max;
778778

779+
# if !SANITIZER_ANDROID
780+
extern const int wordexp_wrde_dooffs;
781+
# endif // !SANITIZER_ANDROID
782+
779783
struct __sanitizer_wordexp_t {
780784
uptr we_wordc;
781785
char **we_wordv;

0 commit comments

Comments
 (0)