Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2777,6 +2777,29 @@ #define INIT_ACCEPT4 #endif +#if SANITIZER_INTERCEPT_PACCEPT +INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen, __sanitizer_sigset_t *set, int f) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f); + unsigned addrlen0 = 0; + if (addrlen) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); + addrlen0 = *addrlen; + } + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); + int fd2 = REAL(paccept)(fd, addr, addrlen, set, f); + if (fd2 >= 0) { + if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); + if (addr && addrlen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); + } + return fd2; +} +#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept); +#else +#define INIT_PACCEPT +#endif + #if SANITIZER_INTERCEPT_MODF INTERCEPTOR(double, modf, double x, double *iptr) { void *ctx; @@ -6687,6 +6710,7 @@ INIT_GETSOCKOPT; INIT_ACCEPT; INIT_ACCEPT4; + INIT_PACCEPT; INIT_MODF; INIT_RECVMSG; INIT_SENDMSG; Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -218,6 +218,7 @@ #define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID || SI_NETBSD +#define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD #define SANITIZER_INTERCEPT_MODF SI_POSIX #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX Index: test/sanitizer_common/TestCases/NetBSD/paccept.cc =================================================================== --- /dev/null +++ test/sanitizer_common/TestCases/NetBSD/paccept.cc @@ -0,0 +1,74 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t + +#include +#include +#include +#include +#include +#include + +int main(void) { + int child; + int fd, sfd; + socklen_t len; + struct sockaddr_in server = {}, client = {}; + sigset_t set; + + child = fork(); + if (child == 0) { + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + _exit(1); + + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons(2222); + + if (connect(fd, (struct sockaddr *)&server, sizeof(server)) == -1) + _exit(1); + + close(fd); + + _exit(0); + } + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) { + kill(child, SIGKILL); + wait(NULL); + exit(1); + } + + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons(2222); + + if (bind(fd, (const struct sockaddr *)&server, sizeof(server)) == -1) { + kill(child, SIGKILL); + wait(NULL); + exit(1); + } + + listen(fd, 3); + + if (sigemptyset(&set) == -1) { + kill(child, SIGKILL); + wait(NULL); + exit(1); + } + + len = sizeof(client); + sfd = paccept(fd, (struct sockaddr *)&client, &len, &set, SOCK_NONBLOCK); + if (sfd == -1) { + kill(child, SIGKILL); + wait(NULL); + exit(1); + } + + wait(NULL); + + close(sfd); + close(fd); + + return 0; +}