Skip to content
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

[rtsan][tsan] Fix va_args handling in open functions #108291

Merged
merged 3 commits into from
Sep 23, 2024
Merged

Conversation

cjappl
Copy link
Contributor

@cjappl cjappl commented Sep 11, 2024

This PR is being opened in response to this comment

Check oflag to see if it contains O_CREAT before unpacking parameters

EDIT: please see comments below discussing whether or not this is necessary

@cjappl
Copy link
Contributor Author

cjappl commented Sep 11, 2024

CC for review @davidtrevelyan

@llvmbot
Copy link
Collaborator

llvmbot commented Sep 11, 2024

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

Author: Chris Apple (cjappl)

Changes

It is only valid to read from the variadic parameter if O_CREAT is specified in the input flags, otherwise we should pass nothing in.


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

1 Files Affected:

  • (modified) compiler-rt/lib/rtsan/rtsan_interceptors.cpp (+16-12)
diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
index 409e27c3ad3234..a9398cf284d827 100644
--- a/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_interceptors.cpp
@@ -64,13 +64,15 @@ INTERCEPTOR(int, open, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_expect_not_realtime("open");
 
-  va_list args;
-  va_start(args, oflag);
-  const mode_t mode = va_arg(args, int);
-  va_end(args);
+  if (oflag & O_CREAT) {
+    va_list args;
+    va_start(args, oflag);
+    const mode_t mode = va_arg(args, int);
+    va_end(args);
+    return REAL(open)(path, oflag, mode);
+  }
 
-  const int result = REAL(open)(path, oflag, mode);
-  return result;
+  return REAL(open)(path, oflag);
 }
 
 INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
@@ -78,13 +80,15 @@ INTERCEPTOR(int, openat, int fd, const char *path, int oflag, ...) {
   // O_NONBLOCK
   __rtsan_expect_not_realtime("openat");
 
-  va_list args;
-  va_start(args, oflag);
-  mode_t mode = va_arg(args, int);
-  va_end(args);
+  if (oflag & O_CREAT) {
+    va_list args;
+    va_start(args, oflag);
+    const mode_t mode = va_arg(args, int);
+    va_end(args);
+    return REAL(openat)(fd, path, oflag, mode);
+  }
 
-  const int result = REAL(openat)(fd, path, oflag, mode);
-  return result;
+  return REAL(openat)(fd, path, oflag);
 }
 
 INTERCEPTOR(int, creat, const char *path, mode_t mode) {

@cjappl
Copy link
Contributor Author

cjappl commented Sep 11, 2024

Hmm, as a counter-argument to this PR, it seems like tsan does the same thing that we do now, always unpacking the arg:

TSAN_INTERCEPTOR(int, open, const char *name, int oflag, ...) {
va_list ap;
va_start(ap, oflag);
mode_t mode = va_arg(ap, int);
va_end(ap);
SCOPED_TSAN_INTERCEPTOR(open, name, oflag, mode);
READ_STRING(thr, pc, name, 0);
int fd = REAL(open)(name, oflag, mode);
if (fd >= 0)
FdFileCreate(thr, pc, fd);
return fd;
}

If this flag is not O_CREAT, the underlying implementation should never touch the third argument, avoiding UB, right?

This is less important for these two functions, and more important to fcntl where the handling of all the cases would be crazy.

@cjappl
Copy link
Contributor Author

cjappl commented Sep 11, 2024

@kubamracek - could you weigh in on if this is necessary or not? I see you did the original work adding va_args to the tsan open interceptor.

Is there anything unsafe about the original way we were doing this?

@cjappl cjappl marked this pull request as draft September 11, 2024 21:32
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@vitalybuka
Copy link
Collaborator

I would expect it's unnecessary? it probably unpacks garbage, but it's not suppose to be used.

also seem O_TMPFILE can read mode?

Copy link
Collaborator

@vitalybuka vitalybuka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I'd suggest either not commit, or include TSAN as well.

@cjappl cjappl changed the title [rtsan] Fix va_args handling in open functions [rtsan][tsan] Fix va_args handling in open functions Sep 21, 2024
@cjappl cjappl marked this pull request as ready for review September 21, 2024 16:37
@llvmbot llvmbot added the compiler-rt:tsan Thread sanitizer label Sep 21, 2024
@cjappl cjappl requested review from dvyukov and kcc September 21, 2024 16:38
vitalybuka added a commit that referenced this pull request Sep 22, 2024
There is nothing Darwin or tsan specific in the test.

For #108291
vitalybuka added a commit that referenced this pull request Sep 22, 2024
@cjappl cjappl merged commit a4232dc into llvm:main Sep 23, 2024
10 checks passed
@cjappl cjappl deleted the fix_va_args branch September 23, 2024 13:55
@cjappl
Copy link
Contributor Author

cjappl commented Sep 23, 2024

Thanks for the additional tests and support vitalybuka

augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Sep 26, 2024
There is nothing Darwin or tsan specific in the test.

For llvm#108291
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Sep 26, 2024
augusto2112 pushed a commit to augusto2112/llvm-project that referenced this pull request Sep 26, 2024
Check oflag to see if it contains O_CREAT / O_TMPFILE before unpacking parameters to avoid UB
xgupta pushed a commit to xgupta/llvm-project that referenced this pull request Oct 4, 2024
There is nothing Darwin or tsan specific in the test.

For llvm#108291
xgupta pushed a commit to xgupta/llvm-project that referenced this pull request Oct 4, 2024
xgupta pushed a commit to xgupta/llvm-project that referenced this pull request Oct 4, 2024
Check oflag to see if it contains O_CREAT / O_TMPFILE before unpacking parameters to avoid UB
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.

4 participants