[compiler-rt] ec5ed66 - [dfsan] Add origin ABI wrappers

Jianzhou Zhao via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 16 19:23:28 PDT 2021


Author: Jianzhou Zhao
Date: 2021-03-17T02:22:35Z
New Revision: ec5ed66cee102c612e30ef34fa574491459875c6

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

LOG: [dfsan] Add origin ABI wrappers

supported: bcmp, fstat, memcmp, stat, strcasecmp, strchr, strcmp,
strncasecmp, strncp, strpbrk

This is a part of https://reviews.llvm.org/D95835.

Reviewed By: morehouse

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

Added: 
    

Modified: 
    compiler-rt/lib/dfsan/dfsan_custom.cpp
    compiler-rt/test/dfsan/custom.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/dfsan/dfsan_custom.cpp b/compiler-rt/lib/dfsan/dfsan_custom.cpp
index ae0c46ac9b71..804c57bd3c35 100644
--- a/compiler-rt/lib/dfsan/dfsan_custom.cpp
+++ b/compiler-rt/lib/dfsan/dfsan_custom.cpp
@@ -1,4 +1,4 @@
-//===-- dfsan.cpp ---------------------------------------------------------===//
+//===-- dfsan_custom.cpp --------------------------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -89,6 +89,14 @@ __dfsw_stat(const char *path, struct stat *buf, dfsan_label path_label,
   return ret;
 }
 
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_stat(
+    const char *path, struct stat *buf, dfsan_label path_label,
+    dfsan_label buf_label, dfsan_label *ret_label, dfsan_origin path_origin,
+    dfsan_origin buf_origin, dfsan_origin *ret_origin) {
+  int ret = __dfsw_stat(path, buf, path_label, buf_label, ret_label);
+  return ret;
+}
+
 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf,
                                                dfsan_label fd_label,
                                                dfsan_label buf_label,
@@ -100,27 +108,58 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_fstat(int fd, struct stat *buf,
   return ret;
 }
 
-SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c,
-                                                  dfsan_label s_label,
-                                                  dfsan_label c_label,
-                                                  dfsan_label *ret_label) {
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_fstat(
+    int fd, struct stat *buf, dfsan_label fd_label, dfsan_label buf_label,
+    dfsan_label *ret_label, dfsan_origin fd_origin, dfsan_origin buf_origin,
+    dfsan_origin *ret_origin) {
+  int ret = __dfsw_fstat(fd, buf, fd_label, buf_label, ret_label);
+  return ret;
+}
+
+static char *dfsan_strchr_with_label(const char *s, int c, size_t *bytes_read,
+                                     dfsan_label s_label, dfsan_label c_label,
+                                     dfsan_label *ret_label) {
+  char *match_pos = nullptr;
   for (size_t i = 0;; ++i) {
     if (s[i] == c || s[i] == 0) {
-      if (flags().strict_data_dependencies) {
-        *ret_label = s_label;
-      } else {
-        *ret_label = dfsan_union(dfsan_read_label(s, i + 1),
-                                 dfsan_union(s_label, c_label));
-      }
-
       // If s[i] is the \0 at the end of the string, and \0 is not the
       // character we are searching for, then return null.
-      if (s[i] == 0 && c != 0) {
-        return nullptr;
-      }
-      return const_cast<char *>(s + i);
+      *bytes_read = i + 1;
+      match_pos = s[i] == 0 && c != 0 ? nullptr : const_cast<char *>(s + i);
+      break;
     }
   }
+  if (flags().strict_data_dependencies)
+    *ret_label = s_label;
+  else
+    *ret_label = dfsan_union(dfsan_read_label(s, *bytes_read),
+                             dfsan_union(s_label, c_label));
+  return match_pos;
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strchr(const char *s, int c,
+                                                  dfsan_label s_label,
+                                                  dfsan_label c_label,
+                                                  dfsan_label *ret_label) {
+  size_t bytes_read;
+  return dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label,
+                                 ret_label);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strchr(
+    const char *s, int c, dfsan_label s_label, dfsan_label c_label,
+    dfsan_label *ret_label, dfsan_origin s_origin, dfsan_origin c_origin,
+    dfsan_origin *ret_origin) {
+  size_t bytes_read;
+  char *r =
+      dfsan_strchr_with_label(s, c, &bytes_read, s_label, c_label, ret_label);
+  if (flags().strict_data_dependencies) {
+    *ret_origin = s_origin;
+  } else if (*ret_label) {
+    dfsan_origin o = dfsan_read_origin_of_first_taint(s, bytes_read);
+    *ret_origin = o ? o : (s_label ? s_origin : c_origin);
+  }
+  return r;
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s,
@@ -141,36 +180,87 @@ SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strpbrk(const char *s,
   return const_cast<char *>(ret);
 }
 
+SANITIZER_INTERFACE_ATTRIBUTE char *__dfso_strpbrk(
+    const char *s, const char *accept, dfsan_label s_label,
+    dfsan_label accept_label, dfsan_label *ret_label, dfsan_origin s_origin,
+    dfsan_origin accept_origin, dfsan_origin *ret_origin) {
+  const char *ret = __dfsw_strpbrk(s, accept, s_label, accept_label, ret_label);
+  if (flags().strict_data_dependencies) {
+    if (ret)
+      *ret_origin = s_origin;
+  } else {
+    if (*ret_label) {
+      size_t s_bytes_read = (ret ? ret - s : strlen(s)) + 1;
+      dfsan_origin o = dfsan_read_origin_of_first_taint(s, s_bytes_read);
+      if (o) {
+        *ret_origin = o;
+      } else {
+        o = dfsan_read_origin_of_first_taint(accept, strlen(accept) + 1);
+        *ret_origin = o ? o : (s_label ? s_origin : accept_origin);
+      }
+    }
+  }
+  return const_cast<char *>(ret);
+}
+
 static int dfsan_memcmp_bcmp(const void *s1, const void *s2, size_t n,
-                             dfsan_label s1_label, dfsan_label s2_label,
-                             dfsan_label n_label, dfsan_label *ret_label) {
+                             size_t *bytes_read) {
   const char *cs1 = (const char *) s1, *cs2 = (const char *) s2;
   for (size_t i = 0; i != n; ++i) {
     if (cs1[i] != cs2[i]) {
-      if (flags().strict_data_dependencies) {
-        *ret_label = 0;
-      } else {
-        *ret_label = dfsan_union(dfsan_read_label(cs1, i + 1),
-                                 dfsan_read_label(cs2, i + 1));
-      }
+      *bytes_read = i + 1;
       return cs1[i] - cs2[i];
     }
   }
-
-  if (flags().strict_data_dependencies) {
-    *ret_label = 0;
-  } else {
-    *ret_label = dfsan_union(dfsan_read_label(cs1, n),
-                             dfsan_read_label(cs2, n));
-  }
+  *bytes_read = n;
   return 0;
 }
 
+static dfsan_label dfsan_get_memcmp_label(const void *s1, const void *s2,
+                                          size_t pos) {
+  if (flags().strict_data_dependencies)
+    return 0;
+  return dfsan_union(dfsan_read_label(s1, pos), dfsan_read_label(s2, pos));
+}
+
+static void dfsan_get_memcmp_origin(const void *s1, const void *s2, size_t pos,
+                                    dfsan_label *ret_label,
+                                    dfsan_origin *ret_origin) {
+  *ret_label = dfsan_get_memcmp_label(s1, s2, pos);
+  if (*ret_label == 0)
+    return;
+  dfsan_origin o = dfsan_read_origin_of_first_taint(s1, pos);
+  *ret_origin = o ? o : dfsan_read_origin_of_first_taint(s2, pos);
+}
+
+static int dfsan_memcmp_bcmp_label(const void *s1, const void *s2, size_t n,
+                                   dfsan_label *ret_label) {
+  size_t bytes_read;
+  int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
+  *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
+  return r;
+}
+
+static int dfsan_memcmp_bcmp_origin(const void *s1, const void *s2, size_t n,
+                                    dfsan_label *ret_label,
+                                    dfsan_origin *ret_origin) {
+  size_t bytes_read;
+  int r = dfsan_memcmp_bcmp(s1, s2, n, &bytes_read);
+  dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
+  return r;
+}
+
 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, uptr caller_pc,
                               const void *s1, const void *s2, size_t n,
                               dfsan_label s1_label, dfsan_label s2_label,
                               dfsan_label n_label)
 
+DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, uptr caller_pc,
+                              const void *s1, const void *s2, size_t n,
+                              dfsan_label s1_label, dfsan_label s2_label,
+                              dfsan_label n_label, dfsan_origin s1_origin,
+                              dfsan_origin s2_origin, dfsan_origin n_origin)
+
 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
                                                 size_t n, dfsan_label s1_label,
                                                 dfsan_label s2_label,
@@ -178,7 +268,18 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_memcmp(const void *s1, const void *s2,
                                                 dfsan_label *ret_label) {
   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_memcmp, GET_CALLER_PC(), s1, s2, n,
                              s1_label, s2_label, n_label);
-  return dfsan_memcmp_bcmp(s1, s2, n, s1_label, s2_label, n_label, ret_label);
+  return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_memcmp(
+    const void *s1, const void *s2, size_t n, dfsan_label s1_label,
+    dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
+    dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
+    dfsan_origin *ret_origin) {
+  CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_memcmp, GET_CALLER_PC(), s1,
+                             s2, n, s1_label, s2_label, n_label, s1_origin,
+                             s2_origin, n_origin);
+  return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2,
@@ -186,51 +287,97 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_bcmp(const void *s1, const void *s2,
                                               dfsan_label s2_label,
                                               dfsan_label n_label,
                                               dfsan_label *ret_label) {
-  return dfsan_memcmp_bcmp(s1, s2, n, s1_label, s2_label, n_label, ret_label);
+  return dfsan_memcmp_bcmp_label(s1, s2, n, ret_label);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_bcmp(
+    const void *s1, const void *s2, size_t n, dfsan_label s1_label,
+    dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
+    dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
+    dfsan_origin *ret_origin) {
+  return dfsan_memcmp_bcmp_origin(s1, s2, n, ret_label, ret_origin);
+}
+
+// When n == 0, compare strings without byte limit.
+// When n > 0, compare the first (at most) n bytes of s1 and s2.
+static int dfsan_strncmp(const char *s1, const char *s2, size_t n,
+                         size_t *bytes_read) {
+  for (size_t i = 0;; ++i) {
+    if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || (n > 0 && i == n - 1)) {
+      *bytes_read = i + 1;
+      return s1[i] - s2[i];
+    }
+  }
 }
 
 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, uptr caller_pc,
                               const char *s1, const char *s2,
                               dfsan_label s1_label, dfsan_label s2_label)
 
+DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, uptr caller_pc,
+                              const char *s1, const char *s2,
+                              dfsan_label s1_label, dfsan_label s2_label,
+                              dfsan_origin s1_origin, dfsan_origin s2_origin)
+
 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcmp(const char *s1, const char *s2,
                                                 dfsan_label s1_label,
                                                 dfsan_label s2_label,
                                                 dfsan_label *ret_label) {
   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strcmp, GET_CALLER_PC(), s1, s2,
                              s1_label, s2_label);
-  for (size_t i = 0;; ++i) {
-    if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0) {
-      if (flags().strict_data_dependencies) {
-        *ret_label = 0;
-      } else {
-        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
-                                 dfsan_read_label(s2, i + 1));
-      }
-      return s1[i] - s2[i];
-    }
-  }
-  return 0;
+  size_t bytes_read;
+  int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
+  *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
+  return r;
 }
 
-SANITIZER_INTERFACE_ATTRIBUTE int
-__dfsw_strcasecmp(const char *s1, const char *s2, dfsan_label s1_label,
-                  dfsan_label s2_label, dfsan_label *ret_label) {
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcmp(
+    const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
+    dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
+    dfsan_origin *ret_origin) {
+  CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strcmp, GET_CALLER_PC(), s1,
+                             s2, s1_label, s2_label, s1_origin, s2_origin);
+  size_t bytes_read;
+  int r = dfsan_strncmp(s1, s2, 0, &bytes_read);
+  dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
+  return r;
+}
+
+// When n == 0, compare strings without byte limit.
+// When n > 0, compare the first (at most) n bytes of s1 and s2.
+static int dfsan_strncasecmp(const char *s1, const char *s2, size_t n,
+                             size_t *bytes_read) {
   for (size_t i = 0;; ++i) {
     char s1_lower = tolower(s1[i]);
     char s2_lower = tolower(s2[i]);
 
-    if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0) {
-      if (flags().strict_data_dependencies) {
-        *ret_label = 0;
-      } else {
-        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
-                                 dfsan_read_label(s2, i + 1));
-      }
+    if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 ||
+        (n > 0 && i == n - 1)) {
+      *bytes_read = i + 1;
       return s1_lower - s2_lower;
     }
   }
-  return 0;
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strcasecmp(const char *s1,
+                                                    const char *s2,
+                                                    dfsan_label s1_label,
+                                                    dfsan_label s2_label,
+                                                    dfsan_label *ret_label) {
+  size_t bytes_read;
+  int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
+  *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
+  return r;
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strcasecmp(
+    const char *s1, const char *s2, dfsan_label s1_label, dfsan_label s2_label,
+    dfsan_label *ret_label, dfsan_origin s1_origin, dfsan_origin s2_origin,
+    dfsan_origin *ret_origin) {
+  size_t bytes_read;
+  int r = dfsan_strncasecmp(s1, s2, 0, &bytes_read);
+  dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
+  return r;
 }
 
 DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc,
@@ -238,6 +385,12 @@ DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, uptr caller_pc,
                               dfsan_label s1_label, dfsan_label s2_label,
                               dfsan_label n_label)
 
+DECLARE_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, uptr caller_pc,
+                              const char *s1, const char *s2, size_t n,
+                              dfsan_label s1_label, dfsan_label s2_label,
+                              dfsan_label n_label, dfsan_origin s1_origin,
+                              dfsan_origin s2_origin, dfsan_origin n_origin)
+
 SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,
                                                  size_t n, dfsan_label s1_label,
                                                  dfsan_label s2_label,
@@ -251,44 +404,60 @@ SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncmp(const char *s1, const char *s2,
   CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_strncmp, GET_CALLER_PC(), s1, s2,
                              n, s1_label, s2_label, n_label);
 
-  for (size_t i = 0;; ++i) {
-    if (s1[i] != s2[i] || s1[i] == 0 || s2[i] == 0 || i == n - 1) {
-      if (flags().strict_data_dependencies) {
-        *ret_label = 0;
-      } else {
-        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
-                                 dfsan_read_label(s2, i + 1));
-      }
-      return s1[i] - s2[i];
-    }
+  size_t bytes_read;
+  int r = dfsan_strncmp(s1, s2, n, &bytes_read);
+  *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
+  return r;
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncmp(
+    const char *s1, const char *s2, size_t n, dfsan_label s1_label,
+    dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
+    dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
+    dfsan_origin *ret_origin) {
+  if (n == 0) {
+    *ret_label = 0;
+    return 0;
   }
-  return 0;
+
+  CALL_WEAK_INTERCEPTOR_HOOK(dfsan_weak_hook_origin_strncmp, GET_CALLER_PC(),
+                             s1, s2, n, s1_label, s2_label, n_label, s1_origin,
+                             s2_origin, n_origin);
+
+  size_t bytes_read;
+  int r = dfsan_strncmp(s1, s2, n, &bytes_read);
+  dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
+  return r;
 }
 
-SANITIZER_INTERFACE_ATTRIBUTE int
-__dfsw_strncasecmp(const char *s1, const char *s2, size_t n,
-                   dfsan_label s1_label, dfsan_label s2_label,
-                   dfsan_label n_label, dfsan_label *ret_label) {
+SANITIZER_INTERFACE_ATTRIBUTE int __dfsw_strncasecmp(
+    const char *s1, const char *s2, size_t n, dfsan_label s1_label,
+    dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label) {
   if (n == 0) {
     *ret_label = 0;
     return 0;
   }
 
-  for (size_t i = 0;; ++i) {
-    char s1_lower = tolower(s1[i]);
-    char s2_lower = tolower(s2[i]);
+  size_t bytes_read;
+  int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
+  *ret_label = dfsan_get_memcmp_label(s1, s2, bytes_read);
+  return r;
+}
 
-    if (s1_lower != s2_lower || s1[i] == 0 || s2[i] == 0 || i == n - 1) {
-      if (flags().strict_data_dependencies) {
-        *ret_label = 0;
-      } else {
-        *ret_label = dfsan_union(dfsan_read_label(s1, i + 1),
-                                 dfsan_read_label(s2, i + 1));
-      }
-      return s1_lower - s2_lower;
-    }
+SANITIZER_INTERFACE_ATTRIBUTE int __dfso_strncasecmp(
+    const char *s1, const char *s2, size_t n, dfsan_label s1_label,
+    dfsan_label s2_label, dfsan_label n_label, dfsan_label *ret_label,
+    dfsan_origin s1_origin, dfsan_origin s2_origin, dfsan_origin n_origin,
+    dfsan_origin *ret_origin) {
+  if (n == 0) {
+    *ret_label = 0;
+    return 0;
   }
-  return 0;
+
+  size_t bytes_read;
+  int r = dfsan_strncasecmp(s1, s2, n, &bytes_read);
+  dfsan_get_memcmp_origin(s1, s2, bytes_read, ret_label, ret_origin);
+  return r;
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE void *__dfsw_calloc(size_t nmemb, size_t size,

diff  --git a/compiler-rt/test/dfsan/custom.cpp b/compiler-rt/test/dfsan/custom.cpp
index b95d74446acd..7825f7aa8f32 100644
--- a/compiler-rt/test/dfsan/custom.cpp
+++ b/compiler-rt/test/dfsan/custom.cpp
@@ -83,8 +83,8 @@ dfsan_label i_j_label = 0;
   for (int i = 0; i < size; ++i) {                                \
     assert(origin == dfsan_get_origin((long)(((char *)ptr)[i]))); \
   }
-#define ASSERT_ORIGINS(ptr, size, origin)
 #else
+#define ASSERT_ORIGINS(ptr, size, origin)
 #endif
 
 #ifdef ORIGIN_TRACKING
@@ -142,27 +142,26 @@ dfsan_label i_j_label = 0;
 #define ASSERT_SAVED_ORIGINS(val)
 #endif
 
-#ifdef ORIGIN_TRACKING
-#define ASSERT_SAVED_N_ORIGINS(val, n) \
-  for (int i = 0; i < n; ++i)          \
-    ASSERT_ORIGIN(val[i], val##_o[i]);
-#else
-#define ASSERT_SAVED_N_ORIGINS(val, n)
-#endif
-
-#if !defined(ORIGIN_TRACKING)
 void test_stat() {
   int i = 1;
   dfsan_set_label(i_label, &i, sizeof(i));
 
   struct stat s;
   s.st_dev = i;
-  assert(0 == stat("/", &s));
+  DEFINE_AND_SAVE_ORIGINS(s)
+  int ret = stat("/", &s);
+  assert(0 == ret);
+  ASSERT_ZERO_LABEL(ret);
   ASSERT_ZERO_LABEL(s.st_dev);
+  ASSERT_SAVED_ORIGINS(s)
 
   s.st_dev = i;
-  assert(-1 == stat("/nonexistent", &s));
+  SAVE_ORIGINS(s)
+  ret = stat("/nonexistent", &s);
+  assert(-1 == ret);
+  ASSERT_ZERO_LABEL(ret);
   ASSERT_LABEL(s.st_dev, i_label);
+  ASSERT_SAVED_ORIGINS(s)
 }
 
 void test_fstat() {
@@ -172,9 +171,12 @@ void test_fstat() {
   struct stat s;
   int fd = open("/dev/zero", O_RDONLY);
   s.st_dev = i;
+  DEFINE_AND_SAVE_ORIGINS(s)
   int rv = fstat(fd, &s);
   assert(0 == rv);
+  ASSERT_ZERO_LABEL(rv);
   ASSERT_ZERO_LABEL(s.st_dev);
+  ASSERT_SAVED_ORIGINS(s)
 }
 
 void test_memcmp() {
@@ -188,7 +190,12 @@ void test_memcmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, i_j_label);
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
+
+  rv = memcmp(str1, str2, sizeof(str1) - 2);
+  assert(rv == 0);
+  ASSERT_ZERO_LABEL(rv);
 }
 
 void test_bcmp() {
@@ -202,6 +209,7 @@ void test_bcmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, i_j_label);
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
 
   rv = bcmp(str1, str2, sizeof(str1) - 2);
@@ -209,6 +217,7 @@ void test_bcmp() {
   ASSERT_ZERO_LABEL(rv);
 }
 
+#if !defined(ORIGIN_TRACKING)
 void test_memcpy() {
   char str1[] = "str1";
   char str2[sizeof(str1)];
@@ -242,6 +251,7 @@ void test_memset() {
     assert(buf[i] == 'a');
   }
 }
+#endif // !defined(ORIGIN_TRACKING)
 
 void test_strcmp() {
   char str1[] = "str1", str2[] = "str2";
@@ -254,9 +264,21 @@ void test_strcmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, i_j_label);
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
+#endif
+
+  rv = strcmp(str1, str1);
+  assert(rv == 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+  ASSERT_ZERO_LABEL(rv);
+  ASSERT_ZERO_ORIGIN(rv);
+#else
+  ASSERT_LABEL(rv, i_label);
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
 }
 
+#if !defined(ORIGIN_TRACKING)
 void test_strcat() {
   char src[] = "world";
   char dst[] = "hello \0    ";
@@ -326,6 +348,7 @@ void test_strncpy() {
   ASSERT_ZERO_LABEL(strd[1]);
   ASSERT_ZERO_LABEL(strd[2]);
 }
+#endif // !defined(ORIGIN_TRACKING)
 
 void test_strncmp() {
   char str1[] = "str1", str2[] = "str2";
@@ -338,11 +361,25 @@ void test_strncmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
 
+  rv = strncmp(str1, str2, 0);
+  assert(rv == 0);
+  ASSERT_ZERO_LABEL(rv);
+
   rv = strncmp(str1, str2, 3);
   assert(rv == 0);
   ASSERT_ZERO_LABEL(rv);
+
+  rv = strncmp(str1, str1, 4);
+  assert(rv == 0);
+#ifdef STRICT_DATA_DEPENDENCIES
+  ASSERT_ZERO_LABEL(rv);
+#else
+  ASSERT_LABEL(rv, i_label);
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
+#endif
 }
 
 void test_strcasecmp() {
@@ -357,6 +394,7 @@ void test_strcasecmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
 
   rv = strcasecmp(str1, str3);
@@ -365,6 +403,7 @@ void test_strcasecmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
 
   char s1[] = "AbZ";
@@ -378,6 +417,7 @@ void test_strcasecmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+  ASSERT_EQ_ORIGIN(rv, s1[2]);
 #endif
 }
 
@@ -392,6 +432,7 @@ void test_strncasecmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+  ASSERT_EQ_ORIGIN(rv, str1[3]);
 #endif
 
   rv = strncasecmp(str1, str2, 3);
@@ -421,6 +462,7 @@ void test_strncasecmp() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, dfsan_union(i_label, j_label));
+  ASSERT_EQ_ORIGIN(rv, s1[2]);
 #endif
 }
 
@@ -428,38 +470,60 @@ void test_strchr() {
   char str1[] = "str1";
   dfsan_set_label(i_label, &str1[3], 1);
 
-  char *crv = strchr(str1, 'r');
+  char *p1 = str1;
+  char c = 'r';
+  dfsan_set_label(k_label, &c, sizeof(c));
+
+  char *crv = strchr(p1, c);
   assert(crv == &str1[2]);
+#ifdef STRICT_DATA_DEPENDENCIES
   ASSERT_ZERO_LABEL(crv);
+#else
+  ASSERT_LABEL(crv, k_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, c);
+#endif
+
+  dfsan_set_label(j_label, &p1, sizeof(p1));
+  crv = strchr(p1, 'r');
+  assert(crv == &str1[2]);
+  ASSERT_LABEL(crv, j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
 
-  crv = strchr(str1, '1');
+  crv = strchr(p1, '1');
   assert(crv == &str1[3]);
 #ifdef STRICT_DATA_DEPENDENCIES
-  ASSERT_ZERO_LABEL(crv);
+  ASSERT_LABEL(crv, j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
 #else
-  ASSERT_LABEL(crv, i_label);
+  ASSERT_LABEL(crv, i_j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
 #endif
 
-  crv = strchr(str1, 'x');
+  crv = strchr(p1, 'x');
   assert(!crv);
 #ifdef STRICT_DATA_DEPENDENCIES
-  ASSERT_ZERO_LABEL(crv);
+  ASSERT_LABEL(crv, j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
 #else
-  ASSERT_LABEL(crv, i_label);
+  ASSERT_LABEL(crv, i_j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
 #endif
 
   // `man strchr` says:
   // The terminating null byte is considered part of the string, so that if c
   // is specified as '\0', these functions return a pointer to the terminator.
-  crv = strchr(str1, '\0');
+  crv = strchr(p1, '\0');
   assert(crv == &str1[4]);
 #ifdef STRICT_DATA_DEPENDENCIES
-  ASSERT_ZERO_LABEL(crv);
+  ASSERT_LABEL(crv, j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, p1);
 #else
-  ASSERT_LABEL(crv, i_label);
+  ASSERT_LABEL(crv, i_j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&crv, str1[3]);
 #endif
 }
 
+#if !defined(ORIGIN_TRACKING)
 void test_calloc() {
   // With any luck this sequence of calls will cause calloc to return the same
   // pointer both times.  This is probably the best we can do to test this
@@ -1126,19 +1190,48 @@ void test_strstr() {
   ASSERT_LABEL(rv, i_j_label);
 #endif
 }
+#endif // !defined(ORIGIN_TRACKING)
 
 void test_strpbrk() {
   char s[] = "abcdefg";
   char accept[] = "123fd";
+
+  char *p_s = s;
+  char *p_accept = accept;
+
+  dfsan_set_label(n_label, &p_accept, sizeof(p_accept));
+
+  char *rv = strpbrk(p_s, p_accept);
+  assert(rv == &s[3]);
+#ifdef STRICT_DATA_DEPENDENCIES
+  ASSERT_ZERO_LABEL(rv);
+#else
+  ASSERT_LABEL(rv, n_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_accept);
+#endif
+
+  dfsan_set_label(m_label, &p_s, sizeof(p_s));
+
+  rv = strpbrk(p_s, p_accept);
+  assert(rv == &s[3]);
+#ifdef STRICT_DATA_DEPENDENCIES
+  ASSERT_LABEL(rv, m_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);
+#else
+  ASSERT_LABEL(rv, dfsan_union(m_label, n_label));
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, p_s);
+#endif
+
   dfsan_set_label(i_label, &s[5], 1);
   dfsan_set_label(j_label, &accept[1], 1);
 
-  char *rv = strpbrk(s, accept);
+  rv = strpbrk(s, accept);
   assert(rv == &s[3]);
 #ifdef STRICT_DATA_DEPENDENCIES
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, accept[1]);
 #endif
 
   char *ps = s;
@@ -1150,6 +1243,7 @@ void test_strpbrk() {
   ASSERT_LABEL(rv, j_label);
 #else
   ASSERT_LABEL(rv, i_j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);
 #endif
 
   rv = strpbrk(ps, "123");
@@ -1158,9 +1252,11 @@ void test_strpbrk() {
   ASSERT_ZERO_LABEL(rv);
 #else
   ASSERT_LABEL(rv, i_j_label);
+  ASSERT_INIT_ORIGIN_EQ_ORIGIN(&rv, s[5]);
 #endif
 }
 
+#if !defined(ORIGIN_TRACKING)
 void test_memchr() {
   char str1[] = "str1";
   dfsan_set_label(i_label, &str1[3], 1);
@@ -1465,7 +1561,9 @@ int main(void) {
 
 #if !defined(ORIGIN_TRACKING)
   test__dl_get_tls_static_info();
+#endif // !defined(ORIGIN_TRACKING)
   test_bcmp();
+#if !defined(ORIGIN_TRACKING)
   test_calloc();
   test_clock_gettime();
   test_ctime_r();
@@ -1474,7 +1572,10 @@ int main(void) {
   test_dlopen();
   test_epoll_wait();
   test_fgets();
+#endif // !defined(ORIGIN_TRACKING)
+  test_fork();
   test_fstat();
+#if !defined(ORIGIN_TRACKING)
   test_get_current_dir_name();
   test_getcwd();
   test_gethostname();
@@ -1488,7 +1589,9 @@ int main(void) {
   test_inet_pton();
   test_localtime_r();
   test_memchr();
+#endif // !defined(ORIGIN_TRACKING)
   test_memcmp();
+#if !defined(ORIGIN_TRACKING)
   test_memcpy();
   test_memmove();
   test_memset();
@@ -1513,20 +1616,24 @@ int main(void) {
   test_snprintf();
   test_socketpair();
   test_sprintf();
+#endif // !defined(ORIGIN_TRACKING)
   test_stat();
   test_strcasecmp();
   test_strchr();
   test_strcmp();
+#if !defined(ORIGIN_TRACKING)
   test_strcat();
   test_strcpy();
   test_strdup();
 #endif // !defined(ORIGIN_TRACKING)
   test_strlen();
-#if !defined(ORIGIN_TRACKING)
   test_strncasecmp();
   test_strncmp();
+#if !defined(ORIGIN_TRACKING)
   test_strncpy();
+#endif // !defined(ORIGIN_TRACKING)
   test_strpbrk();
+#if !defined(ORIGIN_TRACKING)
   test_strrchr();
   test_strstr();
   test_strtod();
@@ -1537,5 +1644,4 @@ int main(void) {
   test_time();
 #endif // !defined(ORIGIN_TRACKING)
   test_write();
-  test_fork();
 }


        


More information about the llvm-commits mailing list