[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
This commit is contained in:
Justin Cady 2021-08-24 12:34:41 -07:00 committed by Vitaly Buka
parent 4d235bf75d
commit d568e5325c
4 changed files with 25 additions and 3 deletions

View File

@ -3760,6 +3760,18 @@ TEST(MemorySanitizer, wordexp) {
ASSERT_STREQ("c", w.we_wordv[2]);
}
TEST(MemorySanitizer, wordexp_initial_offset) {
wordexp_t w;
w.we_offs = 1;
int res = wordexp("a b c", &w, WRDE_DOOFFS);
ASSERT_EQ(0, res);
ASSERT_EQ(3U, w.we_wordc);
ASSERT_EQ(nullptr, w.we_wordv[0]);
ASSERT_STREQ("a", w.we_wordv[1]);
ASSERT_STREQ("b", w.we_wordv[2]);
ASSERT_STREQ("c", w.we_wordv[3]);
}
template<class T>
static bool applySlt(T value, T shadow) {
__msan_partial_poison(&value, &shadow, sizeof(T));

View File

@ -3996,10 +3996,12 @@ INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
int res = REAL(wordexp)(s, p, flags);
if (!res && p) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
if (p->we_wordc)
uptr we_wordc =
((flags & wordexp_wrde_dooffs) ? p->we_wordc : 0) + p->we_wordc;
if (we_wordc)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
sizeof(*p->we_wordv) * p->we_wordc);
for (uptr i = 0; i < p->we_wordc; ++i) {
sizeof(*p->we_wordv) * we_wordc);
for (uptr i = 0; i < we_wordc; ++i) {
char *w = p->we_wordv[i];
if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);
}

View File

@ -313,6 +313,10 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
int glob_altdirfunc = GLOB_ALTDIRFUNC;
#endif
# if !SANITIZER_ANDROID
const int wordexp_wrde_dooffs = WRDE_DOOFFS;
# endif // !SANITIZER_ANDROID
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \

View File

@ -776,6 +776,10 @@ extern int glob_altdirfunc;
extern unsigned path_max;
# if !SANITIZER_ANDROID
extern const int wordexp_wrde_dooffs;
# endif // !SANITIZER_ANDROID
struct __sanitizer_wordexp_t {
uptr we_wordc;
char **we_wordv;