-
Notifications
You must be signed in to change notification settings - Fork 12k
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
Conversation
CC for review @davidtrevelyan |
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Chris Apple (cjappl) ChangesIt 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:
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) {
|
Hmm, as a counter-argument to this PR, it seems like tsan does the same thing that we do now, always unpacking the arg: llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp Lines 1664 to 1675 in c2b93e0
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. |
@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 Is there anything unsafe about the original way we were doing this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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? |
There was a problem hiding this 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.
There is nothing Darwin or tsan specific in the test. For #108291
Thanks for the additional tests and support vitalybuka |
There is nothing Darwin or tsan specific in the test. For llvm#108291
Check oflag to see if it contains O_CREAT / O_TMPFILE before unpacking parameters to avoid UB
There is nothing Darwin or tsan specific in the test. For llvm#108291
Check oflag to see if it contains O_CREAT / O_TMPFILE before unpacking parameters to avoid UB
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