diff options
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common_interceptors.inc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors.inc | 144 |
1 files changed, 112 insertions, 32 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 9f5a91ac99dc6..50e3558b52e87 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -36,6 +36,7 @@ // COMMON_INTERCEPTOR_MMAP_IMPL // COMMON_INTERCEPTOR_COPY_STRING // COMMON_INTERCEPTOR_STRNDUP_IMPL +// COMMON_INTERCEPTOR_STRERROR //===----------------------------------------------------------------------===// #include "interception/interception.h" @@ -301,6 +302,10 @@ bool PlatformHasDifferentMemcpyAndMemmove(); return new_mem; #endif +#ifndef COMMON_INTERCEPTOR_STRERROR +#define COMMON_INTERCEPTOR_STRERROR() {} +#endif + struct FileMetadata { // For open_memstream(). char **addr; @@ -317,11 +322,11 @@ struct CommonInterceptorMetadata { }; }; +#if SI_POSIX typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap; static MetadataHashMap *interceptor_metadata_map; -#if SI_POSIX UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr, const FileMetadata &file) { MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr); @@ -1241,8 +1246,9 @@ INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); - if (!SANITIZER_MAC || s) + if (!SANITIZER_MAC || s) { // `fputs(NULL, file)` is supported on Darwin. COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + } return REAL(fputs)(s, file); } #define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs) @@ -1255,8 +1261,9 @@ INTERCEPTOR(int, puts, char *s) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, puts, s); - if (!SANITIZER_MAC || s) + if (!SANITIZER_MAC || s) { // `puts(NULL)` is supported on Darwin. COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + } return REAL(puts)(s); } #define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts) @@ -1265,9 +1272,8 @@ INTERCEPTOR(int, puts, char *s) { #endif #if SANITIZER_INTERCEPT_PRCTL -INTERCEPTOR(int, prctl, int option, unsigned long arg2, - unsigned long arg3, // NOLINT - unsigned long arg4, unsigned long arg5) { // NOLINT +INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); static const int PR_SET_NAME = 15; @@ -1699,13 +1705,13 @@ INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size, FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format) #endif -INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT -FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT +INTERCEPTOR(int, sprintf, char *str, const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) #if SANITIZER_INTERCEPT___PRINTF_CHK INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to, - const char *format, ...) // NOLINT -FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT + const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) #endif INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) @@ -1713,8 +1719,8 @@ FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) #if SANITIZER_INTERCEPT___PRINTF_CHK INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, - SIZE_T size_to, const char *format, ...) // NOLINT -FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT + SIZE_T size_to, const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) #endif INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) @@ -3069,13 +3075,14 @@ INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); - if (res >= 0 && msgvec) + if (res >= 0 && msgvec) { for (int i = 0; i < res; ++i) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len)); if (common_flags()->intercept_send) read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); } + } return res; } #define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg); @@ -3206,20 +3213,21 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { __sanitizer_iovec local_iovec; if (data) { - if (request == ptrace_setregs) + if (request == ptrace_setregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); - else if (request == ptrace_setfpregs) + } else if (request == ptrace_setfpregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); - else if (request == ptrace_setfpxregs) + } else if (request == ptrace_setfpxregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); - else if (request == ptrace_setvfpregs) + } else if (request == ptrace_setvfpregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz); - else if (request == ptrace_setsiginfo) + } else if (request == ptrace_setsiginfo) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); + // Some kernel might zero the iovec::iov_base in case of invalid // write access. In this case copy the invalid address for further // inspection. - else if (request == ptrace_setregset || request == ptrace_getregset) { + } else if (request == ptrace_setregset || request == ptrace_getregset) { __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec)); local_iovec = *iovec; @@ -3236,19 +3244,19 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { if (!res && data) { // Note that PEEK* requests assign different meaning to the return value. // This function does not handle them (nor does it need to). - if (request == ptrace_getregs) + if (request == ptrace_getregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); - else if (request == ptrace_getfpregs) + } else if (request == ptrace_getfpregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); - else if (request == ptrace_getfpxregs) + } else if (request == ptrace_getfpxregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); - else if (request == ptrace_getvfpregs) + } else if (request == ptrace_getvfpregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz); - else if (request == ptrace_getsiginfo) + } else if (request == ptrace_getsiginfo) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); - else if (request == ptrace_geteventmsg) + } else if (request == ptrace_geteventmsg) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long)); - else if (request == ptrace_getregset) { + } else if (request == ptrace_getregset) { __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base, @@ -3674,6 +3682,7 @@ INTERCEPTOR(int, sched_getparam, int pid, void *param) { INTERCEPTOR(char *, strerror, int errnum) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); + COMMON_INTERCEPTOR_STRERROR(); char *res = REAL(strerror)(errnum); if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); return res; @@ -6714,7 +6723,7 @@ INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, (src_size + 1) * sizeof(wchar_t)); - return REAL(wcscat)(dst, src); // NOLINT + return REAL(wcscat)(dst, src); } INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { @@ -6727,7 +6736,7 @@ INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, (src_size + 1) * sizeof(wchar_t)); - return REAL(wcsncat)(dst, src, n); // NOLINT + return REAL(wcsncat)(dst, src, n); } #define INIT_WCSCAT \ COMMON_INTERCEPT_FUNCTION(wcscat); \ @@ -7841,10 +7850,11 @@ INTERCEPTOR(int, modctl, int operation, void *argp) { if (iov) COMMON_INTERCEPTOR_WRITE_RANGE( ctx, iov->iov_base, Min(iov_len, iov->iov_len)); - } else if (operation == modctl_exists) + } else if (operation == modctl_exists) { ret = REAL(modctl)(operation, argp); - else + } else { ret = REAL(modctl)(operation, argp); + } return ret; } @@ -9548,10 +9558,76 @@ INTERCEPTOR(void, sl_free, void *sl, int freeall) { #define INIT_SL_INIT #endif +#if SANITIZER_INTERCEPT_GETRANDOM +INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags); + SSIZE_T n = REAL(getrandom)(buf, buflen, flags); + if (n > 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n); + } + return n; +} +#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom) +#else +#define INIT_GETRANDOM +#endif + +#if SANITIZER_INTERCEPT_CRYPT +INTERCEPTOR(char *, crypt, char *key, char *salt) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt); + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); + char *res = REAL(crypt)(key, salt); + if (res != nullptr) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); + return res; +} +#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt); +#else +#define INIT_CRYPT +#endif + +#if SANITIZER_INTERCEPT_CRYPT_R +INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data); + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); + char *res = REAL(crypt_r)(key, salt, data); + if (res != nullptr) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, + __sanitizer::struct_crypt_data_sz); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); + } + return res; +} +#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r); +#else +#define INIT_CRYPT_R +#endif + +#if SANITIZER_INTERCEPT_GETENTROPY +INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen); + int r = REAL(getentropy)(buf, buflen); + if (r == 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); + } + return r; +} +#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy) +#else +#define INIT_GETENTROPY +#endif + static void InitializeCommonInterceptors() { +#if SI_POSIX static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; - interceptor_metadata_map = - new ((void *)&metadata_mem) MetadataHashMap(); // NOLINT + interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap(); +#endif INIT_MMAP; INIT_MMAP64; @@ -9844,6 +9920,10 @@ static void InitializeCommonInterceptors() { INIT_FDEVNAME; INIT_GETUSERSHELL; INIT_SL_INIT; + INIT_GETRANDOM; + INIT_CRYPT; + INIT_CRYPT_R; + INIT_GETENTROPY; INIT___PRINTF_CHK; } |