[compiler-rt] compiler-rt: intercept fortified read/pread wrappers (PR #206228)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 27 00:57:09 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: maflcko
<details>
<summary>Changes</summary>
Add TSAN/common interceptors for glibc fortified read/pread calls, so that they follow the same blocking and signal-handling path as the plain libc symbols.
The regression test from https://github.com/llvm/llvm-project/pull/77789 for `read`, when compiled with `-D_FORTIFY_SOURCE=3` fails without the new interceptors.
I have a regression test for pread(64) as well, but I am not sure if there is much value in adding it.
---
Full diff: https://github.com/llvm/llvm-project/pull/206228.diff
3 Files Affected:
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc (+55)
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h (+3)
- (modified) compiler-rt/test/tsan/signal_in_read.c (+1)
``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index c76010e77d1fa..412d5f9b37923 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1026,6 +1026,23 @@ INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
#define INIT_READ
#endif
+#if SANITIZER_INTERCEPT___READ_CHK
+INTERCEPTOR(SSIZE_T, __read_chk, int fd, void *ptr, SIZE_T count,
+ SIZE_T buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __read_chk, fd, ptr, count, buflen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(__read_chk)(fd, ptr, count,
+ buflen);
+ if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+#define INIT___READ_CHK COMMON_INTERCEPT_FUNCTION(__read_chk)
+#else
+#define INIT___READ_CHK
+#endif
+
#if SANITIZER_INTERCEPT_FREAD
INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
// libc file streams can call user-supplied functions, see fopencookie.
@@ -1061,6 +1078,23 @@ INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
#define INIT_PREAD
#endif
+#if SANITIZER_INTERCEPT___PREAD_CHK
+INTERCEPTOR(SSIZE_T, __pread_chk, int fd, void *ptr, SIZE_T count,
+ OFF_T offset, SIZE_T buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __pread_chk, fd, ptr, count, offset, buflen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(__pread_chk)(fd, ptr, count,
+ offset, buflen);
+ if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+#define INIT___PREAD_CHK COMMON_INTERCEPT_FUNCTION(__pread_chk)
+#else
+#define INIT___PREAD_CHK
+#endif
+
#if SANITIZER_INTERCEPT_PREAD64
INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
void *ctx;
@@ -1079,6 +1113,24 @@ INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
#define INIT_PREAD64
#endif
+#if SANITIZER_INTERCEPT___PREAD64_CHK
+INTERCEPTOR(SSIZE_T, __pread64_chk, int fd, void *ptr, SIZE_T count,
+ OFF64_T offset, SIZE_T buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, __pread64_chk, fd, ptr, count, offset,
+ buflen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(__pread64_chk)(fd, ptr, count,
+ offset, buflen);
+ if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
+ if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ return res;
+}
+#define INIT___PREAD64_CHK COMMON_INTERCEPT_FUNCTION(__pread64_chk)
+#else
+#define INIT___PREAD64_CHK
+#endif
+
#if SANITIZER_INTERCEPT_READV
INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
int iovcnt) {
@@ -10431,9 +10483,12 @@ static void InitializeCommonInterceptors() {
INIT_MEMRCHR;
INIT_MEMMEM;
INIT_READ;
+ INIT___READ_CHK;
INIT_FREAD;
INIT_PREAD;
+ INIT___PREAD_CHK;
INIT_PREAD64;
+ INIT___PREAD64_CHK;
INIT_READV;
INIT_PREADV;
INIT_PREADV64;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 9f6fc4e9b9bfa..702c960434a0f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -201,6 +201,9 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
#define SANITIZER_INTERCEPT_READ SI_POSIX
#define SANITIZER_INTERCEPT_PREAD SI_POSIX
+#define SANITIZER_INTERCEPT___READ_CHK SI_GLIBC
+#define SANITIZER_INTERCEPT___PREAD_CHK SI_GLIBC
+#define SANITIZER_INTERCEPT___PREAD64_CHK SI_GLIBC
#define SANITIZER_INTERCEPT_WRITE SI_POSIX
#define SANITIZER_INTERCEPT_PWRITE SI_POSIX
diff --git a/compiler-rt/test/tsan/signal_in_read.c b/compiler-rt/test/tsan/signal_in_read.c
index ec50d9d021745..82f9a58e46da5 100644
--- a/compiler-rt/test/tsan/signal_in_read.c
+++ b/compiler-rt/test/tsan/signal_in_read.c
@@ -1,4 +1,5 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clang_tsan -O1 -D_FORTIFY_SOURCE=3 %s -o %t.fortify && %run %t.fortify 2>&1 | FileCheck %s
#include "test.h"
``````````
</details>
https://github.com/llvm/llvm-project/pull/206228
More information about the llvm-commits
mailing list