[PATCH] D41502: Correct the setitimer interceptor on NetBSD

Kamil Rytarowski via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 21 10:14:20 PST 2017


krytarowski created this revision.
krytarowski added reviewers: eugenis, joerg, vitalybuka.
krytarowski added a project: Sanitizers.
Herald added subscribers: kubamracek, emaste.

itimerval can contain padding that may be legitimately uninitialized.

On NetBSD there are four integers of type "long, int, long, int", the
int argument stands for __sanitizer_suseconds_t. Compiler adds extra
padding in this layout.

Check every field of struct itimerval separately.

Define __sanitizer_suseconds_t as long on FreeBSD, Linux and SmartOS,
and int on NetBSD. Define __sanitizer_timeval and __sanitizer_itimerval.

Sponsored by <The NetBSD Foundation>


Repository:
  rL LLVM

https://reviews.llvm.org/D41502

Files:
  lib/sanitizer_common/sanitizer_common_interceptors.inc
  lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
  lib/sanitizer_common/sanitizer_platform_limits_posix.h
  lib/sanitizer_common/sanitizer_platform_limits_solaris.h


Index: lib/sanitizer_common/sanitizer_platform_limits_solaris.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform_limits_solaris.h
+++ lib/sanitizer_common/sanitizer_platform_limits_solaris.h
@@ -160,6 +160,18 @@
 
 typedef long __sanitizer_time_t;
 
+typedef long __sanitizer_suseconds_t;
+
+struct __sanitizer_timeval {
+  __sanitizer_time_t tv_sec;
+  __sanitizer_suseconds_t tv_usec;
+};
+
+struct __sanitizer_itimerval {
+  struct __sanitizer_timeval it_interval;
+  struct __sanitizer_timeval it_value;
+};
+
 struct __sanitizer_timeb {
   __sanitizer_time_t time;
   unsigned short millitm;
Index: lib/sanitizer_common/sanitizer_platform_limits_posix.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -414,6 +414,18 @@
   typedef long __sanitizer_time_t;
 #endif
 
+  typedef long __sanitizer_suseconds_t;
+
+  struct __sanitizer_timeval {
+    __sanitizer_time_t tv_sec;
+    __sanitizer_suseconds_t tv_usec;
+  };
+
+  struct __sanitizer_itimerval {
+    struct __sanitizer_timeval it_interval;
+    struct __sanitizer_timeval it_value;
+  };
+
   struct __sanitizer_timeb {
     __sanitizer_time_t time;
     unsigned short millitm;
Index: lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
===================================================================
--- lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
+++ lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
@@ -134,6 +134,17 @@
 typedef unsigned __sanitizer_pthread_key_t;
 
 typedef long long __sanitizer_time_t;
+typedef int __sanitizer_suseconds_t;
+
+struct __sanitizer_timeval {
+  __sanitizer_time_t tv_sec;
+  __sanitizer_suseconds_t tv_usec;
+};
+
+struct __sanitizer_itimerval {
+  struct __sanitizer_timeval it_interval;
+  struct __sanitizer_timeval it_value;
+};
 
 struct __sanitizer_passwd {
   char *pw_name;
Index: lib/sanitizer_common/sanitizer_common_interceptors.inc
===================================================================
--- lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2125,8 +2125,19 @@
 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
-  if (new_value)
-    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
+  if (new_value) {
+    // itimerval can contain padding that may be legitimately uninitialized
+    const struct __sanitizer_itimerval *nv =
+        (const struct __sanitizer_itimerval *)new_value;
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,
+                                  sizeof(__sanitizer_time_t));
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,
+                                  sizeof(__sanitizer_suseconds_t));
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,
+                                  sizeof(__sanitizer_time_t));
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,
+                                  sizeof(__sanitizer_suseconds_t));
+  }
   // FIXME: under ASan the call below may write to freed memory and corrupt
   // its metadata. See
   // https://github.com/google/sanitizers/issues/321.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41502.127908.patch
Type: text/x-patch
Size: 3430 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171221/d15d784e/attachment.bin>


More information about the llvm-commits mailing list