forked from OSchip/llvm-project
[sanitizer] Intercept realpath and canonicalize_file_name.
Handle realpath(path, NULL) form. llvm-svn: 185921
This commit is contained in:
parent
f60c75a644
commit
77ef78a0a5
|
@ -99,6 +99,9 @@ void SetThreadName(const char *name) {
|
|||
// ---------------------- Wrappers ---------------- {{{1
|
||||
using namespace __asan; // NOLINT
|
||||
|
||||
DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
|
||||
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
|
||||
|
||||
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
|
||||
ASAN_WRITE_RANGE(ptr, size)
|
||||
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size)
|
||||
|
|
|
@ -619,14 +619,6 @@ INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
|
|||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(char *, realpath, char *path, char *abspath) {
|
||||
ENSURE_MSAN_INITED();
|
||||
char *res = REAL(realpath)(path, abspath);
|
||||
if (res)
|
||||
__msan_unpoison(abspath, REAL(strlen)(abspath) + 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
|
||||
if (msan_init_is_running)
|
||||
return REAL(getrlimit)(resource, rlim);
|
||||
|
@ -1208,7 +1200,6 @@ void InitializeInterceptors() {
|
|||
INTERCEPT_FUNCTION(socketpair);
|
||||
INTERCEPT_FUNCTION(fgets);
|
||||
INTERCEPT_FUNCTION(fgets_unlocked);
|
||||
INTERCEPT_FUNCTION(realpath);
|
||||
INTERCEPT_FUNCTION(getrlimit);
|
||||
INTERCEPT_FUNCTION(getrlimit64);
|
||||
INTERCEPT_FUNCTION(statfs);
|
||||
|
|
|
@ -939,6 +939,23 @@ TEST(MemorySanitizer, realpath) {
|
|||
EXPECT_NOT_POISONED(path[0]);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizer, realpath_null) {
|
||||
const char* relpath = ".";
|
||||
char* res = realpath(relpath, NULL);
|
||||
printf("%d, %s\n", errno, strerror(errno));
|
||||
assert(res);
|
||||
EXPECT_NOT_POISONED(res[0]);
|
||||
free(res);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizer, canonicalize_file_name) {
|
||||
const char* relpath = ".";
|
||||
char* res = canonicalize_file_name(relpath);
|
||||
assert(res);
|
||||
EXPECT_NOT_POISONED(res[0]);
|
||||
free(res);
|
||||
}
|
||||
|
||||
TEST(MemorySanitizer, memcpy) {
|
||||
char* x = new char[2];
|
||||
char* y = new char[2];
|
||||
|
|
|
@ -1580,6 +1580,46 @@ INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
|
|||
#define INIT_TCGETATTR
|
||||
#endif
|
||||
|
||||
|
||||
#if SANITIZER_INTERCEPT_REALPATH
|
||||
INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
|
||||
|
||||
// Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
|
||||
// version of a versioned symbol. For realpath(), this gives us something
|
||||
// (called __old_realpath) that does not handle NULL in the second argument.
|
||||
// Handle it as part of the interceptor.
|
||||
char *allocated_path = 0;
|
||||
if (!resolved_path)
|
||||
allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
|
||||
|
||||
char *res = REAL(realpath)(path, resolved_path);
|
||||
if (allocated_path && !res)
|
||||
WRAP(free)(allocated_path);
|
||||
if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
|
||||
return res;
|
||||
}
|
||||
#define INIT_REALPATH INTERCEPT_FUNCTION(realpath);
|
||||
#else
|
||||
#define INIT_REALPATH
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
|
||||
INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
|
||||
if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
|
||||
char *res = REAL(canonicalize_file_name)(path);
|
||||
if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
|
||||
return res;
|
||||
}
|
||||
#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name);
|
||||
#else
|
||||
#define INIT_CANONICALIZE_FILE_NAME
|
||||
#endif
|
||||
|
||||
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
|
||||
INIT_STRCASECMP; \
|
||||
INIT_STRNCASECMP; \
|
||||
|
@ -1634,4 +1674,6 @@ INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
|
|||
INIT_MBSNRTOWCS; \
|
||||
INIT_WCSTOMBS; \
|
||||
INIT_WCSNRTOMBS; \
|
||||
INIT_TCGETATTR;
|
||||
INIT_TCGETATTR; \
|
||||
INIT_REALPATH; \
|
||||
INIT_CANONICALIZE_FILE_NAME;
|
||||
|
|
|
@ -106,5 +106,7 @@
|
|||
# define SANITIZER_INTERCEPT_WCSTOMBS SI_NOT_WINDOWS
|
||||
# define SANITIZER_INTERCEPT_WCSNRTOMBS SI_MAC || SI_LINUX_NOT_ANDROID
|
||||
# define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX
|
||||
# define SANITIZER_INTERCEPT_REALPATH SI_NOT_WINDOWS
|
||||
# define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME SI_LINUX_NOT_ANDROID
|
||||
|
||||
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <dirent.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/route.h>
|
||||
|
@ -194,6 +195,8 @@ namespace __sanitizer {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
unsigned path_max = PATH_MAX;
|
||||
|
||||
// ioctl arguments
|
||||
unsigned struct_arpreq_sz = sizeof(struct arpreq);
|
||||
unsigned struct_ifreq_sz = sizeof(struct ifreq);
|
||||
|
|
|
@ -195,6 +195,8 @@ namespace __sanitizer {
|
|||
extern int glob_nomatch;
|
||||
#endif
|
||||
|
||||
extern unsigned path_max;
|
||||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
|
||||
(defined(__i386) || defined (__x86_64))
|
||||
extern unsigned struct_user_regs_struct_sz;
|
||||
|
|
|
@ -349,6 +349,8 @@ void StatOutput(u64 *stat) {
|
|||
name[StatInt_wcsrtombs] = " wcsrtombs ";
|
||||
name[StatInt_wcsnrtombs] = " wcsnrtombs ";
|
||||
name[StatInt_tcgetattr] = " tcgetattr ";
|
||||
name[StatInt_realpath] = " realpath ";
|
||||
name[StatInt_canonicalize_file_name] = " canonicalize_file_name ";
|
||||
|
||||
name[StatAnnotation] = "Dynamic annotations ";
|
||||
name[StatAnnotateHappensBefore] = " HappensBefore ";
|
||||
|
|
|
@ -344,6 +344,8 @@ enum StatType {
|
|||
StatInt_wcsrtombs,
|
||||
StatInt_wcsnrtombs,
|
||||
StatInt_tcgetattr,
|
||||
StatInt_realpath,
|
||||
StatInt_canonicalize_file_name,
|
||||
|
||||
// Dynamic annotations.
|
||||
StatAnnotation,
|
||||
|
|
Loading…
Reference in New Issue