From e4606ed2d03d4bab20eca2a95ed73b622fdf54ab Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 30 Jun 2024 15:29:17 +0100 Subject: [PATCH 1/3] [compiler-rt] adding preadv2/pwritev2 interceptions. --- .../sanitizer_common_interceptors.inc | 34 +++++++++++++++++++ .../sanitizer_platform_interceptors.h | 3 ++ 2 files changed, 37 insertions(+) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 1df61e79f7d84..eae0e8ebba1f7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -10259,6 +10259,38 @@ INTERCEPTOR(int, cpuset_getaffinity, int level, int which, __int64_t id, SIZE_T #define INIT_CPUSET_GETAFFINITY #endif +#if SANITIZER_INTERCEPT_PREADV2 +INTERCEPTOR(SSIZE_T, preadv2, int fd, __sanitizer_iovec *iov, int iovcnt, + OFF_T offset, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, preadv2, fd, iov, iovcnt, offset, flags); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + SSIZE_T res = REAL(preadv2)(fd, iov, iovcnt, offset, flags); + if (res > 0) write_iovec(ctx, iov, iovcnt, res); + if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + return res; +} +#define INIT_PREADV2 COMMON_INTERCEPT_FUNCTION(preadv2) +#else +#define INIT_PREADV2 +#endif + +#if SANITIZER_INTERCEPT_PWRITEV2 +INTERCEPTOR(SSIZE_T, pwritev2, int fd, __sanitizer_iovec *iov, int iovcnt, + OFF_T offset, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pwritev2, fd, iov, iovcnt, offset, flags); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); + SSIZE_T res = REAL(pwritev2)(fd, iov, iovcnt, offset, flags); + if (res > 0) read_iovec(ctx, iov, iovcnt, res); + return res; +} +#define INIT_PWRITEV2 COMMON_INTERCEPT_FUNCTION(pwritev2) +#else +#define INIT_PWRITEV2 +#endif + #include "sanitizer_common_interceptors_netbsd_compat.inc" namespace __sanitizer { @@ -10578,6 +10610,8 @@ static void InitializeCommonInterceptors() { INIT___XUNAME; INIT_ARGP_PARSE; INIT_CPUSET_GETAFFINITY; + INIT_PREADV2; + INIT_PWRITEV2; INIT___PRINTF_CHK; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index de55c736d0e14..c94368b6b0ebb 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -598,6 +598,9 @@ #define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD #define SANITIZER_INTERCEPT_ARGP_PARSE SI_GLIBC #define SANITIZER_INTERCEPT_CPUSET_GETAFFINITY SI_FREEBSD +// FIXME: also available from musl 1.2.5 +#define SANITIZER_INTERCEPT_PREADV2 SI_GLIBC +#define SANITIZER_INTERCEPT_PWRITEV2 SI_GLIBC // This macro gives a way for downstream users to override the above // interceptor macros irrespective of the platform they are on. They have From 47894f169572af29db14d501a67660ea7cbe5c87 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 11 Jul 2024 23:05:01 +0100 Subject: [PATCH 2/3] add tests --- .../TestCases/Linux/preadv2.cpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp new file mode 100644 index 0000000000000..56452118cf502 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp @@ -0,0 +1,28 @@ +// RUN: %clangxx -O0 %s -o %t + +// UNSUPPORTED: android + +#include +#include +#include +#include + +int main(void) { + int fd = open("/proc/self/stat", O_RDONLY); + char bufa[7]; + char bufb[7]; + struct iovec vec[2]; + vec[0].iov_base = bufa + 4; + vec[0].iov_len = 1; + vec[1].iov_base = bufb; + vec[1].iov_len = sizeof(bufb); + ssize_t rd = preadv2(fd, vec, 2, 0, 0); + assert(rd > 0); + vec[0].iov_base = bufa; + rd = preadv2(fd, vec, 2, 0, 0); + assert(rd > 0); + rd = preadv2(fd, vec, 5, -25, 0); + assert(rd < 0); + close(fd); + return 0; +} From ccf1df8a2ade7413e6f133865afe9b81ba906b9a Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 15 Jul 2024 15:21:22 -0700 Subject: [PATCH 3/3] REQUIRES: glibc --- compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp index 56452118cf502..176347f78ecdc 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/preadv2.cpp @@ -1,6 +1,6 @@ // RUN: %clangxx -O0 %s -o %t -// UNSUPPORTED: android +// REQUIRES: glibc #include #include