Skip to content

[sanitizer_common] Intercept timespec_get except for hwasan #117080

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 4 commits into from
Nov 21, 2024

Conversation

thurstond
Copy link
Contributor

Intercept timespec_get for all sanitizers except for hwasan

Intercept timespec_get for all sanitizers except for hwasan
@llvmbot
Copy link
Member

llvmbot commented Nov 21, 2024

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

Author: Thurston Dang (thurstond)

Changes

Intercept timespec_get for all sanitizers except for hwasan


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

3 Files Affected:

  • (modified) compiler-rt/lib/hwasan/hwasan_platform_interceptors.h (+3)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc (+19)
  • (modified) compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h (+1-2)
diff --git a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
index e8011014c2331d..8a653d83dec651 100644
--- a/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
+++ b/compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
@@ -209,6 +209,9 @@
 #undef SANITIZER_INTERCEPT_TIME
 #define SANITIZER_INTERCEPT_TIME 0
 
+#undef SANITIZER_INTERCEPT_TIMESPEC_GET
+#define SANITIZER_INTERCEPT_TIMESPEC_GET 0
+
 #undef SANITIZER_INTERCEPT_GLOB
 #define SANITIZER_INTERCEPT_GLOB 0
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 99fa737adfaf26..07b65a1f0c15ee 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2389,6 +2389,24 @@ INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
 #define INIT_GETITIMER
 #endif
 
+#if SANITIZER_INTERCEPT_TIMESPEC_GET
+INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, timespec_get, ts, base);
+  // FIXME: under ASan the call below may write to freed memory and corrupt
+  // its metadata. See
+  // https://github.com/google/sanitizers/issues/321.
+  int res = REAL(timespec_get)(ts, base);
+  if (res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ts, sizeof(struct __sanitizer_timespec));
+  }
+  return res;
+}
+#define INIT_TIMESPEC_GET COMMON_INTERCEPT_FUNCTION(timespec_get);
+#else
+#define INIT_TIMESPEC_GET
+#endif
+
 #if SANITIZER_INTERCEPT_GLOB
 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
@@ -10324,6 +10342,7 @@ static void InitializeCommonInterceptors() {
   INIT_TIMER_CREATE;
   INIT_GETITIMER;
   INIT_TIME;
+  INIT_TIMESPEC_GET;
   INIT_GLOB;
   INIT_GLOB64;
   INIT___B64_TO;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 1f78b1af8e2c6f..36f18acc15fe14 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -210,8 +210,6 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_PREAD64 (SI_GLIBC || SI_SOLARIS32)
 #define SANITIZER_INTERCEPT_PWRITE64 (SI_GLIBC || SI_SOLARIS32)
 
-#define SANITIZER_INTERCEPT_LSEEK64 (SI_GLIBC || SI_SOLARIS32)
-
 #define SANITIZER_INTERCEPT_READV SI_POSIX
 #define SANITIZER_INTERCEPT_WRITEV SI_POSIX
 
@@ -263,6 +261,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_TIMER_CREATE SI_GLIBC
 #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX
 #define SANITIZER_INTERCEPT_TIME SI_POSIX
+#define SANITIZER_INTERCEPT_TIMESPEC_GET SI_LINUX
 #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC
 #define SANITIZER_INTERCEPT___B64_TO SI_LINUX_NOT_ANDROID

Copy link

github-actions bot commented Nov 21, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, timespec_get, ts, base);
// FIXME: under ASan the call below may write to freed memory and corrupt
Copy link
Contributor

Choose a reason for hiding this comment

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

confirming: if this is a uaf, then asan might corrupt the metadata? is that correct?

Copy link
Contributor Author

@thurstond thurstond Nov 21, 2024

Choose a reason for hiding this comment

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

With this test:

  struct timespec* tp = (struct timespec*)malloc(sizeof(struct timespec));
  free (tp);
  int res = timespec_get(tp, TIME_UTC);

and 6865d0a, ASan gives an error message something like this:

==2764516==ERROR: AddressSanitizer: heap-use-after-free on address 0x7bdeeae20010 at pc 0x55fe6d1f968d bp 0x7ffefcc6ad30 sp 0x7ffefcc6a508
WRITE of size 16 at 0x7bdeeae20010 thread T0
    #0 0x55fe6d1f968c  (/tmp/t-uaf+0x5b68c)
    #1 0x55fe6d2ae3c3  (/tmp/t-uaf+0x1103c3)
...

0x7bdeeae20010 is located 0 bytes inside of 16-byte region [0x7bdeeae20010,0x7bdeeae20020)
freed by thread T0 here:
AddressSanitizer: CHECK failed: asan_descriptions.cpp:178 "((res.trace)) != (0)" (0x0, 0x0) (tid=2764516)
    #0 0x55fe6d275691  (/tmp/t-uaf+0xd7691)
    #1 0x55fe6d290712  (/tmp/t-uaf+0xf2712)
...

which is not the usual backtrace / sanitizer report. (I think the corruption is relatively mild - it still showed "heap-use-after-free" - because timespec_get only writes 16 bytes.)

In any case, I've fixed the issue in 97834fa:

==2773902==ERROR: AddressSanitizer: heap-use-after-free on address 0x7bc8d0e20010 at pc 0x5646802e96da bp 0x7ffc27901ec0 sp 0x7ffc27901678
WRITE of size 16 at 0x7bc8d0e20010 thread T0
    #0 0x5646802e96d9  (/tmp/t-uaf+0x5b6d9)
    #1 0x56468039e403  (/tmp/t-uaf+0x110403)
    #2 0x7fa8d1d43b89  (/lib/x86_64-linux-gnu/libc.so.6+0x27b89) (BuildId: 3ddd476a0eddfeb6390b2791bd945afaa13978ff)
    #3 0x7fa8d1d43c44  (/lib/x86_64-linux-gnu/libc.so.6+0x27c44) (BuildId: 3ddd476a0eddfeb6390b2791bd945afaa13978ff)
    #4 0x5646802ba360  (/tmp/t-uaf+0x2c360)

0x7bc8d0e20010 is located 0 bytes inside of 16-byte region [0x7bc8d0e20010,0x7bc8d0e20020)
freed by thread T0 here:
    #0 0x5646803599d6  (/tmp/t-uaf+0xcb9d6)
    #1 0x56468039e3f5  (/tmp/t-uaf+0x1103f5)
    #2 0x7fa8d1d43b89  (/lib/x86_64-linux-gnu/libc.so.6+0x27b89) (BuildId: 3ddd476a0eddfeb6390b2791bd945afaa13978ff)

previously allocated by thread T0 here:
    #0 0x564680359c74  (/tmp/t-uaf+0xcbc74)
    #1 0x56468039e3e8  (/tmp/t-uaf+0x1103e8)
    #2 0x7fa8d1d43b89  (/lib/x86_64-linux-gnu/libc.so.6+0x27b89) (BuildId: 3ddd476a0eddfeb6390b2791bd945afaa13978ff)

SUMMARY: AddressSanitizer: heap-use-after-free (/tmp/t-uaf+0x5b6d9) 
Shadow bytes around the buggy address:
  0x7bc8d0e1fd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bc8d0e1fe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bc8d0e1fe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bc8d0e1ff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bc8d0e1ff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7bc8d0e20000: fa fa[fd]fd fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bc8d0e20080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bc8d0e20100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bc8d0e20180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bc8d0e20200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bc8d0e20280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==2773902==ABORTING

@thurstond thurstond requested a review from fmayer November 21, 2024 18:20
@thurstond thurstond merged commit 9ba6672 into llvm:main Nov 21, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants