[MSan] Use COMMON_INTERCEPTOR_ENTER in libdl interceptors.

This fixes fails in test/msan/dlerror.cc - when real dlerror calls strcmp,
our strcmp interceptor now skips poison checking, since it's called in
interceptor context.  Strictly speaking, only the dlerror change is
necessary to fix the fail, but let's also change the other two just in case.

Differential Revision: http://reviews.llvm.org/D19499

llvm-svn: 267486
This commit is contained in:
Marcin Koscielnicki 2016-04-25 22:25:49 +00:00
parent 7de74af929
commit 9135ff9247
2 changed files with 60 additions and 62 deletions

View File

@ -1052,63 +1052,6 @@ INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
#define MSAN_MAYBE_INTERCEPT_MMAP64
#endif
struct dlinfo {
char *dli_fname;
void *dli_fbase;
char *dli_sname;
void *dli_saddr;
};
INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
ENSURE_MSAN_INITED();
int res = REAL(dladdr)(addr, info);
if (res != 0) {
__msan_unpoison(info, sizeof(*info));
if (info->dli_fname)
__msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
if (info->dli_sname)
__msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
}
return res;
}
INTERCEPTOR(char *, dlerror, int fake) {
ENSURE_MSAN_INITED();
char *res = REAL(dlerror)(fake);
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
void *data);
struct dl_iterate_phdr_data {
dl_iterate_phdr_cb callback;
void *data;
};
static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
void *data) {
if (info) {
__msan_unpoison(info, size);
if (info->dlpi_phdr && info->dlpi_phnum)
__msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
if (info->dlpi_name)
__msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
}
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
UnpoisonParam(3);
return cbdata->callback(info, size, cbdata->data);
}
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
ENSURE_MSAN_INITED();
dl_iterate_phdr_data cbdata;
cbdata.callback = callback;
cbdata.data = data;
int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
return res;
}
INTERCEPTOR(int, getrusage, int who, void *usage) {
ENSURE_MSAN_INITED();
int res = REAL(getrusage)(who, usage);
@ -1453,6 +1396,66 @@ int OnExit() {
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
#include "sanitizer_common/sanitizer_common_syscalls.inc"
struct dlinfo {
char *dli_fname;
void *dli_fbase;
char *dli_sname;
void *dli_saddr;
};
INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info);
int res = REAL(dladdr)(addr, info);
if (res != 0) {
__msan_unpoison(info, sizeof(*info));
if (info->dli_fname)
__msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
if (info->dli_sname)
__msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
}
return res;
}
INTERCEPTOR(char *, dlerror, int fake) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);
char *res = REAL(dlerror)(fake);
if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
return res;
}
typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
void *data);
struct dl_iterate_phdr_data {
dl_iterate_phdr_cb callback;
void *data;
};
static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
void *data) {
if (info) {
__msan_unpoison(info, size);
if (info->dlpi_phdr && info->dlpi_phnum)
__msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
if (info->dlpi_name)
__msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
}
dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
UnpoisonParam(3);
return cbdata->callback(info, size, cbdata->data);
}
INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);
dl_iterate_phdr_data cbdata;
cbdata.callback = callback;
cbdata.data = data;
int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
return res;
}
// These interface functions reside here so that they can use
// REAL(memset), etc.
void __msan_unpoison(const void *a, uptr size) {

View File

@ -1,9 +1,4 @@
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
//
// AArch64, MIPS64 shows fails with uninitialized bytes in __interceptor_strcmp from
// dlfcn/dlerror.c:107 (glibc).
// XFAIL: aarch64
// XFAIL: mips64
#include <assert.h>
#include <dlfcn.h>