Skip to content

[compiler-rt][rtsan] intercept setbuf, setvbuf, setlinebuf and setbuffer #121616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 4, 2025

Conversation

devnexen
Copy link
Member

@devnexen devnexen commented Jan 4, 2025

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Jan 4, 2025

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: David CARLIER (devnexen)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/121616.diff

2 Files Affected:

  • (modified) compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp (+35)
  • (modified) compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp (+50)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
index 9f89ab6bf1fc7d..227d077290af71 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
@@ -325,6 +325,37 @@ INTERCEPTOR(FILE *, fmemopen, void *buf, size_t size, const char *mode) {
 #define RTSAN_MAYBE_INTERCEPT_FMEMOPEN
 #endif
 
+#if SANITIZER_INTERCEPT_SETVBUF
+INTERCEPTOR(void, setbuf, FILE *stream, char *buf) {
+  __rtsan_notify_intercepted_call("setbuf");
+  return REAL(setbuf)(stream, buf);
+}
+
+INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, size_t size) {
+  __rtsan_notify_intercepted_call("setbuffer");
+  return REAL(setbuffer)(stream, buf, size);
+}
+
+INTERCEPTOR(void, setlinebuf, FILE *stream) {
+  __rtsan_notify_intercepted_call("setlinebuf");
+  return REAL(setlinebuf)(stream);
+}
+
+INTERCEPTOR(int, setvbuf, FILE *stream, char *buf, int mode, size_t size) {
+  __rtsan_notify_intercepted_call("setvbuf");
+  return REAL(setvbuf)(stream, buf, mode, size);
+}
+#define RTSAN_MAYBE_INTERCEPT_SETBUF INTERCEPT_FUNCTION(setbuf)
+#define RTSAN_MAYBE_INTERCEPT_SETBUFFER INTERCEPT_FUNCTION(setbuffer)
+#define RTSAN_MAYBE_INTERCEPT_SETLINEBUF INTERCEPT_FUNCTION(setlinebuf)
+#define RTSAN_MAYBE_INTERCEPT_SETVBUF INTERCEPT_FUNCTION(setvbuf)
+#else
+#define RTSAN_MAYBE_INTERCEPT_SETBUF
+#define RTSAN_MAYBE_INTERCEPT_SETBUFFER
+#define RTSAN_MAYBE_INTERCEPT_SETLINEBUF
+#define RTSAN_MAYBE_INTERCEPT_SETVBUF
+#endif
+
 INTERCEPTOR(int, puts, const char *s) {
   __rtsan_notify_intercepted_call("puts");
   return REAL(puts)(s);
@@ -986,6 +1017,10 @@ void __rtsan::InitializeInterceptors() {
   RTSAN_MAYBE_INTERCEPT_FOPENCOOKIE;
   RTSAN_MAYBE_INTERCEPT_OPEN_MEMSTREAM;
   RTSAN_MAYBE_INTERCEPT_FMEMOPEN;
+  RTSAN_MAYBE_INTERCEPT_SETBUF;
+  RTSAN_MAYBE_INTERCEPT_SETBUFFER;
+  RTSAN_MAYBE_INTERCEPT_SETLINEBUF;
+  RTSAN_MAYBE_INTERCEPT_SETVBUF;
   INTERCEPT_FUNCTION(lseek);
   RTSAN_MAYBE_INTERCEPT_LSEEK64;
   INTERCEPT_FUNCTION(dup);
diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
index 5adbf0fb63de80..2947510b2cfde8 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp
@@ -403,6 +403,56 @@ TEST_F(RtsanFileTest, FmemOpenDiesWhenRealtime) {
 }
 #endif
 
+#if SANITIZER_INTERCEPT_SETVBUF
+TEST_F(RtsanFileTest, SetbufDieWhenRealtime) {
+  char buffer[BUFSIZ];
+  FILE *f = fopen(GetTemporaryFilePath(), "w");
+  EXPECT_THAT(f, Ne(nullptr));
+
+  auto Func = [&f, &buffer]() { setbuf(f, buffer); };
+
+  ExpectRealtimeDeath(Func, "setbuf");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanFileTest, SetbufferDieWhenRealtime) {
+  char buffer[1024];
+  size_t size = sizeof(buffer);
+  FILE *f = fopen(GetTemporaryFilePath(), "w");
+  EXPECT_THAT(f, Ne(nullptr));
+
+  auto Func = [&f, &buffer, &size]() { setbuffer(f, buffer, size); };
+
+  ExpectRealtimeDeath(Func, "setbuffer");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanFileTest, SetvbufDieWhenRealtime) {
+  char buffer[1024];
+  size_t size = sizeof(buffer);
+  FILE *f = fopen(GetTemporaryFilePath(), "w");
+  EXPECT_THAT(f, Ne(nullptr));
+
+  auto Func = [&f, &buffer, &size]() {
+    int r = setvbuf(f, buffer, _IOFBF, size);
+    EXPECT_THAT(r, Eq(0));
+  };
+
+  ExpectRealtimeDeath(Func, "setvbuf");
+  ExpectNonRealtimeSurvival(Func);
+}
+
+TEST_F(RtsanFileTest, SetlinebufDieWhenRealtime) {
+  FILE *f = fopen(GetTemporaryFilePath(), "w");
+  EXPECT_THAT(f, Ne(nullptr));
+
+  auto Func = [&f]() { setlinebuf(f); };
+
+  ExpectRealtimeDeath(Func, "setlinebuf");
+  ExpectNonRealtimeSurvival(Func);
+}
+#endif
+
 class RtsanOpenedFileTest : public RtsanFileTest {
 protected:
   void SetUp() override {

@davidtrevelyan
Copy link
Contributor

Thanks for the continued contributions @devnexen 👍

@devnexen devnexen merged commit 95db111 into llvm:main Jan 4, 2025
10 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jan 4, 2025

LLVM Buildbot has detected a new failure on builder openmp-offload-sles-build-only running on rocm-worker-hw-04-sles while building compiler-rt at step 8 "Add check check-llvm".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/14009

Here is the relevant piece of the build log for the reference
Step 8 (Add check check-llvm) failure: test (failure)
******************** TEST 'LLVM :: ExecutionEngine/JITLink/x86-64/MachO_unnamed_external.yaml' FAILED ********************
Exit Code: 1

Command Output (stderr):
--
RUN: at line 1: /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/yaml2obj /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_unnamed_external.yaml -o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/test/ExecutionEngine/JITLink/x86-64/Output/MachO_unnamed_external.yaml.tmp
+ /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/yaml2obj /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_unnamed_external.yaml -o /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/test/ExecutionEngine/JITLink/x86-64/Output/MachO_unnamed_external.yaml.tmp
RUN: at line 2: not /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/llvm-jitlink -noexec -entry _anchor /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/test/ExecutionEngine/JITLink/x86-64/Output/MachO_unnamed_external.yaml.tmp 2>&1 | /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_unnamed_external.yaml
+ not /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/llvm-jitlink -noexec -entry _anchor /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/test/ExecutionEngine/JITLink/x86-64/Output/MachO_unnamed_external.yaml.tmp
+ /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_unnamed_external.yaml

--

********************


@cjappl
Copy link
Contributor

cjappl commented Jan 4, 2025

@devnexen - I'd love to keep being added to these reviews alongside @davidtrevelyan :)

Thank you!!

@Zentrik
Copy link
Contributor

Zentrik commented Jan 4, 2025

I get the following error when cross compiling for aarch64 mac os

[11:06:34] ninja: job failed: /opt/bin/aarch64-apple-darwin20-libgfortran5-cxx11/aarch64-apple-darwin20-clang++ --target=arm64-apple-darwin20 --sysroot=/opt/aarch64-apple-darwin20/aarch64-apple-darwin20/sys-root -D_DEBUG -D_GLIBCXX_ASSERTIONS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/workspace/build/projects/compiler-rt/lib/rtsan -I/workspace/srcdir/llvm-project/compiler-rt/lib/rtsan -I/workspace/build/include -I/workspace/srcdir/llvm-project/llvm/include -I/workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/.. -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -Wall -Wno-unused-parameter -O3 -DNDEBUG -arch arm64 -stdlib=libc++ -mmacosx-version-min=11.0 -isysroot /opt/aarch64-apple-darwin20/aarch64-apple-darwin20/sys-root -fPIC -fno-builtin -fno-exceptions -funwind-tables -fno-stack-protector -fno-sanitize=safe-stack -fvisibility=hidden -fno-lto -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta -O3 -g -Wno-gnu -Wno-variadic-macros -Wno-c99-extensions -ftrivial-auto-var-init=pattern -DSANITIZER_COMMON_NO_REDEFINE_BUILTINS -fno-rtti -std=c++17 -MD -MT projects/compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.osx.dir/rtsan_interceptors_posix.cpp.o -MF projects/compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.osx.dir/rtsan_interceptors_posix.cpp.o.d -o projects/compiler-rt/lib/rtsan/CMakeFiles/RTRtsan.osx.dir/rtsan_interceptors_posix.cpp.o -c /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:334:19: error: conflicting types for 'setbuffer'
[11:06:34] INTERCEPTOR(void, setbuffer, FILE *stream, char *buf, size_t size) {
[11:06:34]                   ^
[11:06:34] /opt/aarch64-apple-darwin20/aarch64-apple-darwin20/sys-root/usr/include/stdio.h:375:7: note: previous declaration is here
[11:06:34] void     setbuffer(FILE *, char *, int);
[11:06:34]          ^
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:339:19: error: functions that differ only in their return type cannot be overloaded
[11:06:34] INTERCEPTOR(void, setlinebuf, FILE *stream) {
[11:06:34]             ~~~~  ^
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/../interception/interception.h:332:53: note: expanded from macro 'INTERCEPTOR'
[11:06:34]   INTERCEPTOR_ZZZ(/*no symbol variants*/, ret_type, func, __VA_ARGS__)
[11:06:34]                                           ~~~~~~~~  ^
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/../interception/interception.h:326:23: note: expanded from macro 'INTERCEPTOR_ZZZ'
[11:06:34]   extern "C" ret_type func(__VA_ARGS__) suffix;       \
[11:06:34]              ~~~~~~~~ ^
[11:06:34] /opt/aarch64-apple-darwin20/aarch64-apple-darwin20/sys-root/usr/include/stdio.h:376:6: note: previous declaration is here
[11:06:34] int      setlinebuf(FILE *);
[11:06:34] ~~~      ^
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:341:15: error: call to 'setlinebuf' is ambiguous
[11:06:34]   return REAL(setlinebuf)(stream);
[11:06:34]               ^~~~~~~~~~
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/../interception/interception.h:266:18: note: expanded from macro 'REAL'
[11:06:34] # define REAL(x) x
[11:06:34]                  ^
[11:06:34] /opt/aarch64-apple-darwin20/aarch64-apple-darwin20/sys-root/usr/include/stdio.h:376:6: note: candidate function
[11:06:34] int      setlinebuf(FILE *);
[11:06:34]          ^
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:339:19: note: candidate function
[11:06:34] INTERCEPTOR(void, setlinebuf, FILE *stream) {
[11:06:34]                   ^
[11:06:34] /workspace/srcdir/llvm-project/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp:341:3: error: void function 'wrap_setlinebuf' should not return a value [-Wreturn-type]
[11:06:34]   return REAL(setlinebuf)(stream);
[11:06:34]   ^      ~~~~~~~~~~~~~~~~~~~~~~~~
[11:06:34] 4 errors generated.

It looks like these functions have different declarations on darwin, e.g. https://github.com/alexey-lysiuk/macos-sdk/blob/0efb06490f664d335a4fdff9198df7d03e87deda/MacOSX15.2.sdk/usr/include/_stdio.h#L472-L473?
Looks like openbsd has a similar problem, https://github.com/openbsd/src/blob/54e45245a3816722a38ebb90c176c2eef1f561c2/include/stdio.h#L364-L365?
Freebsd as well, https://man.freebsd.org/cgi/man.cgi?query=setbuffer&sektion=3&apropos=0&manpath=FreeBSD+13.1-RELEASE+and+Ports.

@devnexen
Copy link
Member Author

devnexen commented Jan 4, 2025

Might be fair to assume only linux case 1 then bsd/macos case 2 (note openbsd does not support sanitizers at all).

@devnexen
Copy link
Member Author

devnexen commented Jan 4, 2025

Going to revert, will reapply later.

devnexen added a commit to devnexen/llvm-project that referenced this pull request Jan 4, 2025
devnexen added a commit that referenced this pull request Jan 4, 2025
@devnexen
Copy link
Member Author

devnexen commented Jan 4, 2025

@devnexen - I'd love to keep being added to these reviews alongside @davidtrevelyan :)

Thank you!!

I ll for next sorry :)

@cjappl
Copy link
Contributor

cjappl commented Jan 4, 2025

@devnexen - I'd love to keep being added to these reviews alongside @davidtrevelyan :)
Thank you!!

I ll for next sorry :)

Thank you :) No apology necessary

devnexen added a commit to devnexen/llvm-project that referenced this pull request Jan 4, 2025
devnexen added a commit to devnexen/llvm-project that referenced this pull request Jan 6, 2025
devnexen added a commit to devnexen/llvm-project that referenced this pull request Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants