return REAL(strncpy)(to, from, size);
}
+#if ASAN_INTERCEPT__FORTIFY_SOURCE
+INTERCEPTOR(char*, __strcpy_chk, char *to, const char *from,
+ uptr to_size) { // NOLINT
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, __strcpy_chk); // NOLINT
+#if SANITIZER_MAC
+ if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT
+#endif
+ // strcpy is called from malloc_default_purgeable_zone()
+ // in __asan::ReplaceSystemAlloc() on Mac.
+ if (asan_init_is_running) {
+ return REAL(strcpy)(to, from); // NOLINT
+ }
+ ENSURE_ASAN_INITED();
+ if (flags()->replace_str) {
+ uptr from_size = REAL(strlen)(from) + 1;
+ CHECK_RANGES_OVERLAP("__strcpy_chk", to, to_size, from, from_size);
+ ASAN_READ_RANGE(ctx, from, from_size);
+ ASAN_WRITE_RANGE(ctx, to, from_size);
+ }
+ return REAL(strcpy)(to, from); // NOLINT
+}
+
+INTERCEPTOR(char*, __strncpy_chk, char *to, const char *from, uptr size,
+ uptr to_size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, __strncpy_chk);
+ ENSURE_ASAN_INITED();
+ if (flags()->replace_str) {
+ uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
+ CHECK_RANGES_OVERLAP("__strncpy_chk", to, to_size, from, from_size);
+ ASAN_READ_RANGE(ctx, from, from_size);
+ ASAN_WRITE_RANGE(ctx, to, size);
+ }
+ return REAL(strncpy)(to, from, size);
+}
+
+INTERCEPTOR(char*, __strcat_chk, char *to, const char *from, uptr to_size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, __strcat_chk); // NOLINT
+ ENSURE_ASAN_INITED();
+ if (flags()->replace_str) {
+ uptr from_length = REAL(strlen)(from);
+ ASAN_READ_RANGE(ctx, from, from_length + 1);
+ uptr to_length = REAL(strlen)(to);
+ ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
+ ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
+ // If the copying actually happens, the |from| string should not overlap
+ // with the resulting string starting at |to|, which has a length of
+ // to_length + from_length + 1.
+ if (from_length > 0) {
+ CHECK_RANGES_OVERLAP("__strcat_chk", to, to_size,
+ from, from_length + 1);
+ }
+ }
+ return REAL(strcat)(to, from); // NOLINT
+}
+
+INTERCEPTOR(char*, __strncat_chk, char *to, const char *from, uptr size,
+ uptr to_size) {
+ void *ctx;
+ ASAN_INTERCEPTOR_ENTER(ctx, __strncat_chk);
+ ENSURE_ASAN_INITED();
+ if (flags()->replace_str) {
+ uptr from_length = MaybeRealStrnlen(from, size);
+ uptr copy_length = Min(size, from_length + 1);
+ ASAN_READ_RANGE(ctx, from, copy_length);
+ uptr to_length = REAL(strlen)(to);
+ ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
+ ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
+ if (from_length > 0) {
+ CHECK_RANGES_OVERLAP("__strncat_chk", to, to_size,
+ from, copy_length);
+ }
+ }
+ return REAL(strncat)(to, from, size);
+}
+#endif //ASAN_INTERCEPT__FORTIFY_SOURCE
+
INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
char **endptr, int base) {
void *ctx;
ASAN_INTERCEPT_FUNC(strncat);
ASAN_INTERCEPT_FUNC(strncpy);
ASAN_INTERCEPT_FUNC(strdup);
+
+#if ASAN_INTERCEPT__FORTIFY_SOURCE
+ ASAN_INTERCEPT_FUNC(__strcat_chk);
+ ASAN_INTERCEPT_FUNC(__strncat_chk);
+ ASAN_INTERCEPT_FUNC(__strcpy_chk);
+ ASAN_INTERCEPT_FUNC(__strncpy_chk);
+#endif
+
#if ASAN_INTERCEPT___STRDUP
ASAN_INTERCEPT_FUNC(__strdup);
#endif
#define INIT_READ
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SSIZE_T, __read_chk, int fd, void *ptr, SIZE_T count,
+ SIZE_T bufflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __read_chk, fd, ptr, count, bufflen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SSIZE_T res = REAL(read)(fd, ptr, count);
+ if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+#define INIT___READ_CHK COMMON_INTERCEPT_FUNCTION(__read_chk)
+#else
+#define INIT___READ_CHK
+#endif
+
#if SANITIZER_INTERCEPT_PREAD
INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
void *ctx;
#define INIT_PREAD
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SSIZE_T, __pread_chk, int fd, void *ptr, SIZE_T count,
+ OFF_T offset, SIZE_T buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __pread_chk, fd, ptr, count, offset, buflen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
+ if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+#define INIT___PREAD_CHK COMMON_INTERCEPT_FUNCTION(__pread_chk)
+#else
+#define INIT___PREAD_CHK
+#endif
+
#if SANITIZER_INTERCEPT_PREAD64
INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
void *ctx;
#define INIT_PREAD64
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SSIZE_T, __pread64_chk, int fd, void *ptr, SIZE_T count,
+ OFF64_T offset, SIZE_T buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __pread64_chk, fd, ptr, count, offset,
+ buflen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
+ if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+#define INIT___PREAD64_CHK COMMON_INTERCEPT_FUNCTION(__pread64_chk)
+#else
+#define INIT___PREAD64_CHK
+#endif
+
#if SANITIZER_INTERCEPT_READV
INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
int iovcnt) {
#define INIT_GETCWD
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(char *, __getcwd_chk, char *buf, SIZE_T size, SIZE_T buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __getcwd_chk, buf, size, buflen);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ char *res = REAL(getcwd)(buf, size);
+ if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ return res;
+}
+#define INIT___GETCWD_CHK COMMON_INTERCEPT_FUNCTION(__getcwd_chk);
+#else
+#define INIT___GETCWD_CHK
+#endif
+
#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
INTERCEPTOR(char *, get_current_dir_name, int fake) {
void *ctx;
#define INIT_MBSTOWCS
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SIZE_T, __mbstowcs_chk, wchar_t *dest, const char *src,
+ SIZE_T len, SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __mbstowcs_chk, dest, src, len, destlen);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(mbstowcs)(dest, src, len);
+ if (res != (SIZE_T) - 1 && dest) {
+ SIZE_T write_cnt = res + (res < len);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
+ return res;
+}
+
+INTERCEPTOR(SIZE_T, __mbsrtowcs_chk, wchar_t *dest, const char **src,
+ SIZE_T len, void *ps, SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __mbsrtowcs_chk, dest, src, len, ps, destlen);
+ if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
+ if (res != (SIZE_T)(-1) && dest && src) {
+ // This function, and several others, may or may not write the terminating
+ // \0 character. They write it iff they clear *src.
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
+ return res;
+}
+
+#define INIT___MBSTOWCS_CHK \
+ COMMON_INTERCEPT_FUNCTION(__mbstowcs_chk); \
+ COMMON_INTERCEPT_FUNCTION(__mbsrtowcs_chk);
+#else
+#define INIT___MBSTOWCS_CHK
+#endif
+
#if SANITIZER_INTERCEPT_MBSNRTOWCS
INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
SIZE_T len, void *ps) {
#define INIT_MBSNRTOWCS
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SIZE_T, __mbsnrtowcs_chk, wchar_t *dest, const char **src,
+ SIZE_T nms, SIZE_T len, void *ps, SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __mbsnrtowcs_chk, dest, src, nms, len, ps,
+ destlen);
+ if (src) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
+ }
+ if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
+ if (res != (SIZE_T)(-1) && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
+ }
+ return res;
+}
+
+#define INIT___MBSNRTOWCS_CHK COMMON_INTERCEPT_FUNCTION(__mbsnrtowcs_chk);
+#else
+#define INIT___MBSNRTOWCS_CHK
+#endif
+
#if SANITIZER_INTERCEPT_WCSTOMBS
INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
void *ctx;
#define INIT_WCSTOMBS
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SIZE_T, __wcstombs_chk, char *dest, const wchar_t *src,
+ SIZE_T len, SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __wcstombs_chk, dest, src, len, destlen);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(wcstombs)(dest, src, len);
+ if (res != (SIZE_T) - 1 && dest) {
+ SIZE_T write_cnt = res + (res < len);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
+ return res;
+}
+
+INTERCEPTOR(SIZE_T, __wcsrtombs_chk, char *dest, const wchar_t **src,
+ SIZE_T len, void *ps, SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __wcsrtombs_chk, dest, src, len, ps,
+ destlen);
+ if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
+ if (res != (SIZE_T) - 1 && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
+ return res;
+}
+
+#define INIT___WCSTOMBS_CHK \
+ COMMON_INTERCEPT_FUNCTION(__wcstombs_chk); \
+ COMMON_INTERCEPT_FUNCTION(__wcsrtombs_chk);
+#else
+#define INIT___WCSTOMBS_CHK
+#endif
+
#if SANITIZER_INTERCEPT_WCSNRTOMBS
INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
SIZE_T len, void *ps) {
#define INIT_WCSNRTOMBS
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SIZE_T, __wcsnrtombs_chk, char *dest, const wchar_t **src,
+ SIZE_T nms, SIZE_T len, void *ps, SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __wcsnrtombs_chk, dest, src, nms, len, ps,
+ destlen);
+ if (src) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+ if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
+ }
+ if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
+ if (res != ((SIZE_T)-1) && dest && src) {
+ SIZE_T write_cnt = res + !*src;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
+ return res;
+}
+
+#define INIT___WCSNRTOMBS_CHK COMMON_INTERCEPT_FUNCTION(__wcsnrtombs_chk);
+#else
+#define INIT___WCSNRTOMBS_CHK
+#endif
#if SANITIZER_INTERCEPT_WCRTOMB
INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
#define INIT_WCRTOMB
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SIZE_T, __wcrtomb_chk, char *dest, wchar_t src, void *ps,
+ SIZE_T destlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __wcrtomb_chk, dest, src, ps, destlen);
+ if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(wcrtomb)(dest, src, ps);
+ if (res != ((SIZE_T)-1) && dest) {
+ SIZE_T write_cnt = res;
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+ }
+ return res;
+}
+
+#define INIT___WCRTOMB_CHK COMMON_INTERCEPT_FUNCTION(__wcrtomb_chk);
+#else
+#define INIT___WCRTOMB_CHK
+#endif
+
#if SANITIZER_INTERCEPT_TCGETATTR
INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
void *ctx;
#define INIT_REALPATH
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(char *, __realpath_chk, const char *path, char *resolved_path,
+ SIZE_T resolvedlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __realpath_chk, path, resolved_path,
+ resolvedlen);
+ 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 = nullptr;
+ 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_CHK COMMON_INTERCEPT_FUNCTION(__realpath_chk);
+#else
+#define INIT___REALPATH_CHK
+#endif
+
#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
void *ctx;
#define INIT_CONFSTR
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SIZE_T, __confstr_chk, int name, char *buf, SIZE_T len,
+ SIZE_T bufflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __confstr_chk, name, buf, len, bufflen);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ SIZE_T res = REAL(confstr)(name, buf, len);
+ if (buf && res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
+ return res;
+}
+#define INIT___CONFSTR_CHK COMMON_INTERCEPT_FUNCTION(__confstr_chk);
+#else
+#define INIT___CONFSTR_CHK
+#endif
+
#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
void *ctx;
#define INIT_GETGROUPS
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(int, __getgroups_chk, int size, u32 *lst, SIZE_T lstsize) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __getgroups_chk, size, lst, lstsize);
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ int res = REAL(getgroups)(size, lst);
+ if (res >= 0 && lst && size > 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
+ return res;
+}
+#define INIT___GETGROUPS_CHK COMMON_INTERCEPT_FUNCTION(__getgroups_chk);
+#else
+#define INIT___GETGROUPS_CHK
+#endif
+
#if SANITIZER_INTERCEPT_POLL
static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
__sanitizer_nfds_t nfds) {
#define INIT_PPOLL
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(int, __poll_chk, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
+ int timeout, SIZE_T fdslen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __poll_chk, fds, nfds, timeout, fdslen);
+ if (fds && nfds) read_pollfd(ctx, fds, nfds);
+ int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
+ if (fds && nfds) write_pollfd(ctx, fds, nfds);
+ return res;
+}
+#define INIT___POLL_CHK COMMON_INTERCEPT_FUNCTION(__poll_chk);
+#else
+#define INIT___POLL_CHK
+#endif
+
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(int, __ppoll_chk, __sanitizer_pollfd *fds,
+ __sanitizer_nfds_t nfds, void *timeout_ts,
+ __sanitizer_sigset_t *sigmask, SIZE_T fdslen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __ppoll_chk, fds, nfds, timeout_ts,
+ sigmask, fdslen);
+ if (fds && nfds) read_pollfd(ctx, fds, nfds);
+ if (timeout_ts)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
+ // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
+ int res =
+ COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
+ if (fds && nfds) write_pollfd(ctx, fds, nfds);
+ return res;
+}
+#define INIT___PPOLL_CHK COMMON_INTERCEPT_FUNCTION(__ppoll_chk);
+#else
+#define INIT___PPOLL_CHK
+#endif
+
#if SANITIZER_INTERCEPT_WORDEXP
INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
void *ctx;
#define INIT_TTYNAME_R
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(int, __ttyname_r_chk, int fd, char *name, SIZE_T namesize,
+ SIZE_T namelen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __ttyname_r_chk, fd, name, namesize, namelen);
+ int res = REAL(ttyname_r)(fd, name, namesize);
+ if (res == 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, namelen + 1);
+ return res;
+}
+#define INIT___TTYNAME_R_CHK COMMON_INTERCEPT_FUNCTION(__ttyname_r_chk);
+#else
+#define INIT___TTYNAME_R_CHK
+#endif
+
#if SANITIZER_INTERCEPT_TEMPNAM
INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
void *ctx;
#define INIT_RECV_RECVFROM
#endif
+#if SANITIZER_INTERCEPT_FORTIFY_SOURCE
+INTERCEPTOR(SSIZE_T, __recv_chk, int fd, void *buf, SIZE_T len, SIZE_T buflen,
+ int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __recv_chk, fd, buf, len, buflen, flags);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ SSIZE_T res = REAL(recv)(fd, buf, len, flags);
+ if (res > 0) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
+ }
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+
+INTERCEPTOR(SSIZE_T, __recvfrom_chk, int fd, void *buf, SIZE_T len,
+ SIZE_T buflen, int flags, void *srcaddr, int *addrlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __recvfrom_chk, fd, buf, len, buflen, flags,
+ srcaddr, addrlen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ SIZE_T srcaddr_sz;
+ if (srcaddr) srcaddr_sz = *addrlen;
+ (void)srcaddr_sz; // prevent "set but not used" warning
+ SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
+ if (res > 0) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
+ if (srcaddr)
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
+ Min((SIZE_T)*addrlen, srcaddr_sz));
+ }
+ return res;
+}
+#define INIT___RECV_RECVFROM_CHK \
+ COMMON_INTERCEPT_FUNCTION(__recv_chk); \
+ COMMON_INTERCEPT_FUNCTION(__recvfrom_chk);
+#else
+#define INIT___RECV_RECVFROM_CHK
+#endif
+
#if SANITIZER_INTERCEPT_SEND_SENDTO
INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
void *ctx;
INIT___XSTAT64;
INIT___LXSTAT;
INIT___LXSTAT64;
- // FIXME: add other *stat interceptors.
+ INIT___READ_CHK;
+ INIT___POLL_CHK;
+ INIT___PPOLL_CHK;
+ INIT___RECV_RECVFROM_CHK;
+ INIT___PREAD_CHK;
+ INIT___PREAD64_CHK;
+ INIT___CONFSTR_CHK;
+ INIT___GETCWD_CHK;
+ INIT___GETGROUPS_CHK;
+ INIT___REALPATH_CHK;
+ INIT___MBSTOWCS_CHK;
+ INIT___MBSNRTOWCS_CHK;
+ INIT___WCSTOMBS_CHK;
+ INIT___WCSNRTOMBS_CHK;
+ INIT___WCRTOMB_CHK;
+ INIT___TTYNAME_R_CHK;
INIT___PRINTF_CHK;
INIT_MCHECK;
INIT_MCHECK_PEDANTIC;