forked from OSchip/llvm-project
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
This commit is contained in:
parent
eb08ec06d7
commit
70552c6f53
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue