]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
syswrap-linux.c: fix clock_adjtime handling
authorAlexandra Hájková <ahajkova@redhat.com>
Mon, 13 Jan 2020 17:29:55 +0000 (12:29 -0500)
committerMark Wielaard <mark@klomp.org>
Wed, 15 Jan 2020 15:01:12 +0000 (16:01 +0100)
Not checking whether valgrind can dereference timex pointer
casues VALGRIND INTERNAL ERROR while handling clock_adjtime.

coregrind/m_syswrap/syswrap-linux.c

index 25d9a9508386c843418ee3259694ace31f9a724b..d04a081dd959b3708cce1e906e74500d6c50c1d4 100644 (file)
@@ -1291,24 +1291,28 @@ PRE(sys_clock_adjtime)
    PRE_REG_READ2(long, "clock_adjtime", vki_clockid_t, id, struct timex *, buf);
    PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
 
-#define ADJX(bits,field)                                \
-   if (tx->modes & (bits))                              \
-      PRE_MEM_READ( "clock_adjtime(timex->"#field")",   \
-                    (Addr)&tx->field, sizeof(tx->field))
-
-   if (tx->modes & VKI_ADJ_ADJTIME) {
-      if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
-         PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
-   } else {
-      ADJX(VKI_ADJ_OFFSET, offset);
-      ADJX(VKI_ADJ_FREQUENCY, freq);
-      ADJX(VKI_ADJ_MAXERROR, maxerror);
-      ADJX(VKI_ADJ_ESTERROR, esterror);
-      ADJX(VKI_ADJ_STATUS, status);
-      ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
-      ADJX(VKI_ADJ_TICK, tick);
-   }
+   if (ML_(safe_to_deref) (tx, sizeof(struct vki_timex))) {
+      PRE_MEM_READ( "clock_adjtime(timex->modes)", ARG2, sizeof(tx->modes));
+
+#define ADJX(bits,field)                                        \
+      if (tx->modes & (bits))                                   \
+         PRE_MEM_READ( "clock_adjtime(timex->"#field")",        \
+                       (Addr)&tx->field, sizeof(tx->field))
+
+      if (tx->modes & VKI_ADJ_ADJTIME) {
+         if (!(tx->modes & VKI_ADJ_OFFSET_READONLY))
+            PRE_MEM_READ( "clock_adjtime(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset));
+      } else {
+         ADJX(VKI_ADJ_OFFSET, offset);
+         ADJX(VKI_ADJ_FREQUENCY, freq);
+         ADJX(VKI_ADJ_MAXERROR, maxerror);
+         ADJX(VKI_ADJ_ESTERROR, esterror);
+         ADJX(VKI_ADJ_STATUS, status);
+         ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant);
+         ADJX(VKI_ADJ_TICK, tick);
+      }
 #undef ADJX
+   }
 
    PRE_MEM_WRITE( "adjtimex(timex)", ARG2, sizeof(struct vki_timex));
 }