aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sanitizer_common/sanitizer_common_interceptors.inc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common_interceptors.inc')
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc144
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 9f5a91ac99dc..50e3558b52e8 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;
}