summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2018-01-23 22:41:47 +0000
committerKamil Rytarowski <n54@gmx.com>2018-01-23 22:41:47 +0000
commit70552c6f53c65e1a74b613eb13a1f62256c4a1dd (patch)
treed8008c7254ab93707dc8fbbb087c26c9ceadaa6e /compiler-rt
parenteb08ec06d7bb6c7794c8707de7d7fe73caf69db0 (diff)
downloadbcm5719-llvm-70552c6f53c65e1a74b613eb13a1f62256c4a1dd.tar.gz
bcm5719-llvm-70552c6f53c65e1a74b613eb13a1f62256c4a1dd.zip
Add a new interceptor: paccept(2)
Summary: paccept(2) is a NetBSD-specific variation of accept(2). Sponsored by <The NetBSD Foundation> Reviewers: joerg, vitalybuka, eugenis Reviewed By: vitalybuka Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D42052 llvm-svn: 323273
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc24
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/NetBSD/paccept.cc74
3 files changed, 99 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 45b38a0bbf8..76a97ba0d19 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2777,6 +2777,29 @@ INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
#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 @@ static void InitializeCommonInterceptors() {
INIT_GETSOCKOPT;
INIT_ACCEPT;
INIT_ACCEPT4;
+ INIT_PACCEPT;
INIT_MODF;
INIT_RECVMSG;
INIT_SENDMSG;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index a019d5d90c9..cb578624005 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/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
diff --git a/compiler-rt/test/sanitizer_common/TestCases/NetBSD/paccept.cc b/compiler-rt/test/sanitizer_common/TestCases/NetBSD/paccept.cc
new file mode 100644
index 00000000000..7d2eb4e8559
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/NetBSD/paccept.cc
@@ -0,0 +1,74 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+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;
+}
OpenPOWER on IntegriCloud