diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -774,6 +774,20 @@ #define INIT_STRPBRK #endif +#if SANITIZER_INTERCEPT_STRSIGNAL +INTERCEPTOR(char *, strsignal, int signal) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsignal, signal); + char *r = REAL(strsignal)(signal); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, REAL(strlen)(r)); + return r; +} + +#define INIT_STRSIGNAL COMMON_INTERCEPT_FUNCTION(strsignal); +#else +#define INIT_STRSIGNAL +#endif + #if SANITIZER_INTERCEPT_MEMSET INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { void *ctx; @@ -2176,6 +2190,15 @@ } return res; } +INTERCEPTOR(int, timespec_get, void *tp, int base) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, timespec_get, tp, base); + int res = REAL(timespec_get)(tp, base); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); + } + return res; +} namespace __sanitizer { extern "C" { int real_clock_gettime(u32 clk_id, void *tp) { @@ -2194,7 +2217,8 @@ #define INIT_CLOCK_GETTIME \ COMMON_INTERCEPT_FUNCTION(clock_getres); \ COMMON_INTERCEPT_FUNCTION(clock_gettime); \ - COMMON_INTERCEPT_FUNCTION(clock_settime); + COMMON_INTERCEPT_FUNCTION(clock_settime); \ + COMMON_INTERCEPT_FUNCTION(timespec_get); #else #define INIT_CLOCK_GETTIME #endif @@ -7298,22 +7322,26 @@ #endif #if SANITIZER_INTERCEPT_PROTOENT +static void write_protoent(void *ctx, struct __sanitizer_protoent *p) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); + + SIZE_T pp_size = 1; // One handles the trailing \0 + + for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, + pp_size * sizeof(char **)); +} + INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); struct __sanitizer_protoent *p = REAL(getprotoent)(); if (p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); - - SIZE_T pp_size = 1; // One handles the trailing \0 - - for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); + write_protoent(ctx, p); } return p; } @@ -7325,17 +7353,7 @@ COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); struct __sanitizer_protoent *p = REAL(getprotobyname)(name); if (p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); - - SIZE_T pp_size = 1; // One handles the trailing \0 - - for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); + write_protoent(ctx, p); } return p; } @@ -7345,17 +7363,7 @@ COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto); struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto); if (p) { - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); - - SIZE_T pp_size = 1; // One handles the trailing \0 - - for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); - - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, - pp_size * sizeof(char **)); + write_protoent(ctx, p); } return p; } @@ -7367,6 +7375,56 @@ #define INIT_PROTOENT #endif +#if SANITIZER_INTERCEPT_PROTOENT_R +INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen, result); + int res = REAL(getprotoent_r)(result_buf, buf, buflen, result); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); + if (!res && *result) { + struct __sanitizer_protoent *p = *result; + write_protoent(ctx, p); + } + return res; +} + +INTERCEPTOR(int, getprotobyname_r, const char *name, struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf, buflen, result); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); + if (!res && *result) { + struct __sanitizer_protoent *p = *result; + write_protoent(ctx, p); + } + return res; +} + +INTERCEPTOR(int, getprotobynumber_r, int num, struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf, buflen, result); + int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); + if (!res && *result) { + struct __sanitizer_protoent *p = *result; + write_protoent(ctx, p); + } + return res; +} + +#define INIT_PROTOENT_R \ + COMMON_INTERCEPT_FUNCTION(getprotoent_r); \ + COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \ + COMMON_INTERCEPT_FUNCTION(getprotobynumber_r); +#else +#define INIT_PROTOENT_R +#endif + #if SANITIZER_INTERCEPT_NETENT INTERCEPTOR(struct __sanitizer_netent *, getnetent) { void *ctx; @@ -9836,6 +9894,7 @@ INIT_STRPBRK; INIT_STRXFRM; INIT___STRXFRM_L; + INIT_STRSIGNAL; INIT_MEMSET; INIT_MEMMOVE; INIT_MEMCPY; @@ -10070,6 +10129,7 @@ INIT_STRMODE; INIT_TTYENT; INIT_PROTOENT; + INIT_PROTOENT_R; INIT_NETENT; INIT_GETMNTINFO; INIT_MI_VECTOR_HASH; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -155,6 +155,7 @@ #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA +#define SANITIZER_INTERCEPT_STRSIGNAL SI_POSIX #define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX #define SANITIZER_INTERCEPT_MEMSET 1 @@ -545,7 +546,8 @@ #define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_TTYENT SI_NETBSD -#define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD +#define SANITIZER_INTERCEPT_PROTOENT (SI_NETBSD || SI_LINUX) +#define SANITIZER_INTERCEPT_PROTOENT_R (SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_NETENT SI_NETBSD #define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \ SI_LINUX || SI_MAC) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -129,12 +129,6 @@ void *_shm_internal; }; -struct __sanitizer_protoent { - char *p_name; - char **p_aliases; - int p_proto; -}; - struct __sanitizer_netent { char *n_name; char **n_aliases; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -704,6 +704,12 @@ extern unsigned struct_ElfW_Phdr_sz; #endif +struct __sanitizer_protoent { + char *p_name; + char **p_aliases; + int p_proto; +}; + struct __sanitizer_addrinfo { int ai_flags; int ai_family; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/protoent.cpp @@ -0,0 +1,62 @@ +// RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s + +#include +#include +#include +#include + +void print_protoent(protoent *curr_entry) { + fprintf(stderr, "%s (%d)\n", curr_entry->p_name, curr_entry->p_proto); + + char **aliases = curr_entry->p_aliases; + while (char *alias = *aliases++) { + fprintf(stderr, " alias %s\n", alias); + } +} + +void print_all_protoent() { + protoent entry; + char buf[1024]; + protoent *curr_entry; + + while (getprotoent_r(&entry, buf, sizeof(buf), &curr_entry) != ENOENT && curr_entry) { + print_protoent(curr_entry); + } +} + +void print_protoent_by_name(const char *name) { + protoent entry; + char buf[1024]; + protoent *curr_entry; + + int res = getprotobyname_r(name, &entry, buf, sizeof(buf), &curr_entry); + assert(!res && curr_entry); + print_protoent(curr_entry); +} + +void print_protoent_by_num(int num) { + protoent entry; + char buf[1024]; + protoent *curr_entry; + + int res = getprotobynumber_r(num, &entry, buf, sizeof(buf), &curr_entry); + assert(!res && curr_entry); + print_protoent(curr_entry); +} + +int main() { + // CHECK: ip (0) + // CHECK-NEXT: alias IP + // CHECK: ipv6 (41) + // CHECK-NEXT: alias IPv6 + print_all_protoent(); + + // CHECK: rdp (27) + // CHECK-NEXT: alias RDP + print_protoent_by_name("rdp"); + + // CHECK: udp (17) + // CHECK-NEXT: alias UDP + print_protoent_by_num(17); + return 0; +}