Skip to content

Commit 4155387

Browse files
authored
Preadv2 pwritev2 san reapply (#99089)
1 parent 898c116 commit 4155387

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10264,6 +10264,38 @@ INTERCEPTOR(int, cpuset_getaffinity, int level, int which, __int64_t id, SIZE_T
1026410264
#define INIT_CPUSET_GETAFFINITY
1026510265
#endif
1026610266

10267+
#if SANITIZER_INTERCEPT_PREADV2
10268+
INTERCEPTOR(SSIZE_T, preadv2, int fd, __sanitizer_iovec *iov, int iovcnt,
10269+
OFF_T offset, int flags) {
10270+
void *ctx;
10271+
COMMON_INTERCEPTOR_ENTER(ctx, preadv2, fd, iov, iovcnt, offset, flags);
10272+
COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10273+
SSIZE_T res = REAL(preadv2)(fd, iov, iovcnt, offset, flags);
10274+
if (res > 0) write_iovec(ctx, iov, iovcnt, res);
10275+
if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
10276+
return res;
10277+
}
10278+
#define INIT_PREADV2 COMMON_INTERCEPT_FUNCTION(preadv2)
10279+
#else
10280+
#define INIT_PREADV2
10281+
#endif
10282+
10283+
#if SANITIZER_INTERCEPT_PWRITEV2
10284+
INTERCEPTOR(SSIZE_T, pwritev2, int fd, __sanitizer_iovec *iov, int iovcnt,
10285+
OFF_T offset, int flags) {
10286+
void *ctx;
10287+
COMMON_INTERCEPTOR_ENTER(ctx, pwritev2, fd, iov, iovcnt, offset, flags);
10288+
COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10289+
if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
10290+
SSIZE_T res = REAL(pwritev2)(fd, iov, iovcnt, offset, flags);
10291+
if (res > 0) read_iovec(ctx, iov, iovcnt, res);
10292+
return res;
10293+
}
10294+
#define INIT_PWRITEV2 COMMON_INTERCEPT_FUNCTION(pwritev2)
10295+
#else
10296+
#define INIT_PWRITEV2
10297+
#endif
10298+
1026710299
#include "sanitizer_common_interceptors_netbsd_compat.inc"
1026810300

1026910301
namespace __sanitizer {
@@ -10583,6 +10615,8 @@ static void InitializeCommonInterceptors() {
1058310615
INIT___XUNAME;
1058410616
INIT_ARGP_PARSE;
1058510617
INIT_CPUSET_GETAFFINITY;
10618+
INIT_PREADV2;
10619+
INIT_PWRITEV2;
1058610620

1058710621
INIT___PRINTF_CHK;
1058810622
}

compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@
598598
#define SANITIZER_INTERCEPT_PROCCTL SI_FREEBSD
599599
#define SANITIZER_INTERCEPT_ARGP_PARSE SI_GLIBC
600600
#define SANITIZER_INTERCEPT_CPUSET_GETAFFINITY SI_FREEBSD
601+
// FIXME: also available from musl 1.2.5
602+
#define SANITIZER_INTERCEPT_PREADV2 (SI_LINUX && __GLIBC_PREREQ(2, 26))
603+
#define SANITIZER_INTERCEPT_PWRITEV2 (SI_LINUX && __GLIBC_PREREQ(2, 26))
601604

602605
// This macro gives a way for downstream users to override the above
603606
// interceptor macros irrespective of the platform they are on. They have
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clangxx -O0 %s -o %t
2+
3+
// REQUIRES: glibc
4+
5+
#include <assert.h>
6+
#include <fcntl.h>
7+
#include <sys/uio.h>
8+
#include <unistd.h>
9+
10+
#if !defined(__GLIBC_PREREQ)
11+
#define __GLIBC_PREREQ(a, b) 0
12+
#endif
13+
14+
#if !__GLIBC_PREREQ(2, 26)
15+
#define preadv2(a, b, c, d, e) preadv(a, b, c, d)
16+
#endif
17+
18+
int main(void) {
19+
int fd = open("/proc/self/stat", O_RDONLY);
20+
char bufa[7];
21+
char bufb[7];
22+
struct iovec vec[2];
23+
vec[0].iov_base = bufa + 4;
24+
vec[0].iov_len = 1;
25+
vec[1].iov_base = bufb;
26+
vec[1].iov_len = sizeof(bufb);
27+
ssize_t rd = preadv2(fd, vec, 2, 0, 0);
28+
assert(rd > 0);
29+
vec[0].iov_base = bufa;
30+
rd = preadv2(fd, vec, 2, 0, 0);
31+
assert(rd > 0);
32+
rd = preadv2(fd, vec, 5, -25, 0);
33+
assert(rd < 0);
34+
close(fd);
35+
return 0;
36+
}

0 commit comments

Comments
 (0)