[compiler-rt] e9c8d0f - [MSAN] add __b64_pton and __b64_ntop intercepts

Kevin Athey via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 8 15:22:41 PDT 2022


Author: Kevin Athey
Date: 2022-04-08T15:22:37-07:00
New Revision: e9c8d0ff71baba2702765d6cd173421d54883fee

URL: https://github.com/llvm/llvm-project/commit/e9c8d0ff71baba2702765d6cd173421d54883fee
DIFF: https://github.com/llvm/llvm-project/commit/e9c8d0ff71baba2702765d6cd173421d54883fee.diff

LOG: [MSAN] add __b64_pton and __b64_ntop intercepts

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D122849

Added: 
    compiler-rt/test/msan/Linux/b64.cpp
    compiler-rt/test/sanitizer_common/TestCases/Linux/b64.cpp

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 9b98261b0d0f5..43296e6c1f6a7 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2496,6 +2496,34 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
 #define INIT_GLOB64
 #endif  // SANITIZER_INTERCEPT_GLOB64
 
+#if SANITIZER_INTERCEPT___B64_TO
+INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,
+            char *target, SIZE_T targsize) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength);
+  int res = REAL(__b64_ntop)(src, srclength, target, targsize);
+  if (res >= 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1);
+  return res;
+}
+INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
+  int res = REAL(__b64_pton)(src, target, targsize);
+  if (res >= 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);
+  return res;
+}
+#  define INIT___B64_TO                    \
+    COMMON_INTERCEPT_FUNCTION(__b64_ntop); \
+    COMMON_INTERCEPT_FUNCTION(__b64_pton);
+#else  // SANITIZER_INTERCEPT___B64_TO
+#define INIT___B64_TO
+#endif  // SANITIZER_INTERCEPT___B64_TO
+
+
 #if SANITIZER_INTERCEPT_POSIX_SPAWN
 
 template <class RealSpawnPtr>
@@ -10396,6 +10424,7 @@ static void InitializeCommonInterceptors() {
   INIT_TIME;
   INIT_GLOB;
   INIT_GLOB64;
+  INIT___B64_TO;
   INIT_POSIX_SPAWN;
   INIT_WAIT;
   INIT_WAIT4;

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 4c9677d20c088..d46b41322ac7d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -235,6 +235,7 @@
 #define SANITIZER_INTERCEPT_TIME SI_POSIX
 #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC
+#define SANITIZER_INTERCEPT___B64_TO SI_LINUX
 #define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX
 #define SANITIZER_INTERCEPT_WAIT SI_POSIX
 #define SANITIZER_INTERCEPT_INET SI_POSIX

diff  --git a/compiler-rt/test/msan/Linux/b64.cpp b/compiler-rt/test/msan/Linux/b64.cpp
new file mode 100644
index 0000000000000..1eb72800af203
--- /dev/null
+++ b/compiler-rt/test/msan/Linux/b64.cpp
@@ -0,0 +1,81 @@
+// RUN: %clangxx_msan -O0 %s -o %t -lresolv && %run %t
+// RUN: not %run %t NTOP_READ 2>&1 | FileCheck %s --check-prefix=NTOP_READ
+// RUN: not %run %t PTON_READ 2>&1 | FileCheck %s --check-prefix=PTON_READ
+
+#include <assert.h>
+#include <resolv.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <sanitizer/msan_interface.h>
+
+int main(int iArgc, char *szArgv[]) {
+  char* test = nullptr;
+  if (iArgc > 1) {
+    test = szArgv[1];
+  }
+
+  if (test == nullptr) {
+    // Check NTOP writing
+    const char *src = "base64 test data";
+    size_t src_len = strlen(src);
+    size_t dst_len = ((src_len + 2) / 3) * 4 + 1;
+    char dst[dst_len];
+    int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
+                       dst, dst_len);
+    assert(res >= 0);
+    __msan_check_mem_is_initialized(dst, res);
+
+    // Check PTON writing
+    unsigned char target[dst_len];
+    res = b64_pton(dst, target, dst_len);
+    assert(res >= 0);
+    __msan_check_mem_is_initialized(target, res);
+
+    // Check NTOP writing for zero length src
+    src = "";
+    src_len = strlen(src);
+    assert(((src_len + 2) / 3) * 4 + 1 < dst_len);
+    res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
+                       dst, dst_len);
+    assert(res >= 0);
+    __msan_check_mem_is_initialized(dst, res);
+
+    // Check PTON writing for zero length src
+    dst[0] = '\0';
+    res = b64_pton(dst, target, dst_len);
+    assert(res >= 0);
+    __msan_check_mem_is_initialized(target, res);
+
+    return 0;
+  }
+
+  if (strcmp(test, "NTOP_READ") == 0) {
+    // Check NTOP reading
+    size_t src_len = 80;
+    char src[src_len];
+    __msan_poison(src, src_len);
+    size_t dst_len = ((src_len + 2) / 3) * 4 + 1;
+    char dst[dst_len];
+    int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
+                       dst, dst_len);
+    // NTOP_READ: Uninitialized bytes in __interceptor___b64_ntop
+    return 0;
+  }
+
+  if (strcmp(test, "PTON_READ") == 0) {
+    // Check PTON reading
+    size_t src_len = 80;
+    char src[src_len];
+    strcpy(src, "junk longer than zero");
+    // pretend it is uninitialized
+    __msan_poison(src, src_len);
+    unsigned char target[src_len];
+    int res = b64_pton(src, target, src_len);
+    // PTON_READ: Uninitialized bytes in __interceptor___b64_pton
+    return 0;
+  }
+
+  return 0;
+}

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/b64.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/b64.cpp
new file mode 100644
index 0000000000000..ae0867e98d1d9
--- /dev/null
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/b64.cpp
@@ -0,0 +1,42 @@
+// RUN: %clangxx %s -o %t -lresolv && %run %t %p
+
+#include <assert.h>
+#include <resolv.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+int main(int iArgc, char *szArgv[]) {
+  // Check NTOP writing
+  const char *src = "base64 test data";
+  size_t src_len = strlen(src);
+  size_t dst_len = ((src_len + 2) / 3) * 4 + 1;
+  char dst[dst_len];
+  int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len, dst,
+                     dst_len);
+  assert(res >= 0);
+  assert(strcmp(dst, "YmFzZTY0IHRlc3QgZGF0YQ==") == 0);
+
+  // Check PTON writing
+  unsigned char target[dst_len];
+  res = b64_pton(dst, target, dst_len);
+  assert(res >= 0);
+  assert(strncmp(reinterpret_cast<const char *>(target), src, res) == 0);
+
+  // Check NTOP writing for zero length src
+  src = "";
+  src_len = strlen(src);
+  assert(((src_len + 2) / 3) * 4 + 1 < dst_len);
+  res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len, dst,
+                 dst_len);
+  assert(res >= 0);
+  assert(strcmp(dst, "") == 0);
+
+  // Check PTON writing for zero length src
+  dst[0] = '\0';
+  res = b64_pton(dst, target, dst_len);
+  assert(res >= 0);
+  assert(strncmp(reinterpret_cast<const char *>(target), src, res) == 0);
+
+  return 0;
+}


        


More information about the llvm-commits mailing list