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 @@ -3092,6 +3092,32 @@ #define INIT_SENDMMSG #endif +#if SANITIZER_INTERCEPT_SYSMSG +INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz, int msgflg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg); + if (msgp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz); + int res = REAL(msgsnd)(msqid, msgp, msgsz, msgflg); + return res; +} + +INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz, long msgtyp, int msgflg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); + SSIZE_T len = REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg); + if (len != -1) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len); + return len; +} + +#define INIT_SYSMSG \ + COMMON_INTERCEPT_FUNCTION(msgsnd); \ + COMMON_INTERCEPT_FUNCTION(msgrcv); +#else +#define INIT_SYSMSG +#endif + #if SANITIZER_INTERCEPT_GETPEERNAME INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { void *ctx; @@ -9879,6 +9905,7 @@ INIT_SENDMSG; INIT_RECVMMSG; INIT_SENDMMSG; + INIT_SYSMSG; INIT_GETPEERNAME; INIT_IOCTL; INIT_INET_ATON; 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 @@ -270,6 +270,7 @@ #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX #define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX #define SANITIZER_INTERCEPT_SENDMMSG SI_LINUX +#define SANITIZER_INTERCEPT_SYSMSG SI_LINUX #define SANITIZER_INTERCEPT_GETPEERNAME SI_POSIX #define SANITIZER_INTERCEPT_IOCTL SI_POSIX #define SANITIZER_INTERCEPT_INET_ATON SI_POSIX diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/sysmsg.c b/compiler-rt/test/sanitizer_common/TestCases/Linux/sysmsg.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/sysmsg.c @@ -0,0 +1,35 @@ +// RUN: %clang -O1 %s -o %t && %run %t +#include +#include +#include +#include +#include + +#define CHECK_STRING "hello, world!" +#define MSG_BUFLEN 0x100 + +int main() { + int msgq = msgget(IPC_PRIVATE, 0666); + assert(msgq != -1); + + struct msg_s { + long mtype; + char string[MSG_BUFLEN]; + }; + + struct msg_s msg = { + .mtype = 1}; + strcpy(msg.string, CHECK_STRING); + int res = msgsnd(msgq, &msg, MSG_BUFLEN, IPC_NOWAIT); + if (res) { + fprintf(stderr, "Error sending message! %s\n", strerror(errno)); + return -1; + } + + struct msg_s rcv_msg; + ssize_t len = msgrcv(msgq, &rcv_msg, MSG_BUFLEN, msg.mtype, IPC_NOWAIT); + assert(len == MSG_BUFLEN); + assert(msg.mtype == rcv_msg.mtype); + assert(!memcmp(msg.string, rcv_msg.string, MSG_BUFLEN)); + return 0; +}