Mark Wielaard 81b3a0
    BZ#331380 Syscall param timer_create(evp) points to uninitialised byte(s)
Mark Wielaard 81b3a0
    
Mark Wielaard 81b3a0
    Only check struct sigevent actually used by the kernel. If SIGEV_THREAD_ID
Mark Wielaard 81b3a0
    is set check sigev_notify_thread_id, otherwise don't.
Mark Wielaard 81b3a0
Mark Wielaard 81b3a0
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 81b3a0
index 9dadd84..1a7fa6b 100644
Mark Wielaard 81b3a0
--- a/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 81b3a0
+++ b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 81b3a0
@@ -2175,8 +2175,18 @@ PRE(sys_timer_create)
Mark Wielaard 81b3a0
    PRE_REG_READ3(long, "timer_create",
Mark Wielaard 81b3a0
                  vki_clockid_t, clockid, struct sigevent *, evp,
Mark Wielaard 81b3a0
                  vki_timer_t *, timerid);
Mark Wielaard 81b3a0
-   if (ARG2 != 0)
Mark Wielaard 81b3a0
-      PRE_MEM_READ( "timer_create(evp)", ARG2, sizeof(struct vki_sigevent) );
Mark Wielaard 81b3a0
+   if (ARG2 != 0) {
Mark Wielaard 81b3a0
+      struct vki_sigevent *evp = (struct vki_sigevent *) ARG2;
Mark Wielaard 81b3a0
+      PRE_MEM_READ( "timer_create(evp.sigev_value)", (Addr)&evp->sigev_value,
Mark Wielaard 81b3a0
+                    sizeof(vki_sigval_t) );
Mark Wielaard 81b3a0
+      PRE_MEM_READ( "timer_create(evp.sigev_signo)", (Addr)&evp->sigev_signo,
Mark Wielaard 81b3a0
+                    sizeof(int) );
Mark Wielaard 81b3a0
+      PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
Mark Wielaard 81b3a0
+                    sizeof(int) );
Mark Wielaard 81b3a0
+      if ((evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
Mark Wielaard 81b3a0
+         PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
Mark Wielaard 81b3a0
+                       (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
Mark Wielaard 81b3a0
+   }
Mark Wielaard 81b3a0
    PRE_MEM_WRITE( "timer_create(timerid)", ARG3, sizeof(vki_timer_t) );
Mark Wielaard 81b3a0
 }
Mark Wielaard 81b3a0
 POST(sys_timer_create)
Mark Wielaard 81b3a0
diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h
Mark Wielaard 81b3a0
index 14bb8bf..a3c4b3c 100644
Mark Wielaard 81b3a0
--- a/include/vki/vki-linux.h
Mark Wielaard 81b3a0
+++ b/include/vki/vki-linux.h
Mark Wielaard 81b3a0
@@ -544,6 +544,9 @@ typedef struct vki_siginfo {
Mark Wielaard 81b3a0
 #define VKI_SIGEV_PAD_SIZE	((VKI_SIGEV_MAX_SIZE - VKI___ARCH_SIGEV_PREAMBLE_SIZE) \
Mark Wielaard 81b3a0
 		/ sizeof(int))
Mark Wielaard 81b3a0
 
Mark Wielaard 81b3a0
+/* This is the flag the kernel handles, userspace/glibc handles SEGEV_THEAD. */
Mark Wielaard 81b3a0
+#define VKI_SIGEV_THREAD_ID	4
Mark Wielaard 81b3a0
+
Mark Wielaard 81b3a0
 typedef struct vki_sigevent {
Mark Wielaard 81b3a0
 	vki_sigval_t sigev_value;
Mark Wielaard 81b3a0
 	int sigev_signo;
Mark Wielaard 81b3a0
@@ -559,6 +562,8 @@ typedef struct vki_sigevent {
Mark Wielaard 81b3a0
 	} _sigev_un;
Mark Wielaard 81b3a0
 } vki_sigevent_t;
Mark Wielaard 81b3a0
 
Mark Wielaard 81b3a0
+#define vki_sigev_notify_thread_id	_sigev_un._tid
Mark Wielaard 81b3a0
+
Mark Wielaard 81b3a0
 //----------------------------------------------------------------------
Mark Wielaard 81b3a0
 // From elsewhere...
Mark Wielaard 81b3a0
 //----------------------------------------------------------------------
Mark Wielaard 4714e5
commit 763710cc391c5adc85712606bf9882f49ee43e7c
Mark Wielaard 4714e5
Author: mjw <mjw@a5019735-40e9-0310-863c-91ae7b9d1cf9>
Mark Wielaard 4714e5
Date:   Mon Feb 24 15:09:21 2014 +0000
Mark Wielaard 4714e5
Mark Wielaard 4714e5
    BZ#331380 cont. Don't crash if evp->sigev_notify is invalid. Fix scalar test.
Mark Wielaard 4714e5
    
Mark Wielaard 4714e5
    We check evp.sigev_notify_thread_id only if evp->sigev_notify has
Mark Wielaard 4714e5
    SIGEV_THREAD_ID set. But before checking we need to make sure accessing
Mark Wielaard 4714e5
    evp->sigev_notify is valid.
Mark Wielaard 4714e5
    
Mark Wielaard 4714e5
    Fix memcheck/tests/x86-linux/scalar.stderr.exp output.
Mark Wielaard 4714e5
    We now produce separate warnings for the 3 different fields.
Mark Wielaard 4714e5
    
Mark Wielaard 4714e5
    git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13837 a5019735-40e9-0310-863c-91ae7b9d1cf9
Mark Wielaard 4714e5
Mark Wielaard 4714e5
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 4714e5
index 1a7fa6b..1b1e65e 100644
Mark Wielaard 4714e5
--- a/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 4714e5
+++ b/coregrind/m_syswrap/syswrap-linux.c
Mark Wielaard 4714e5
@@ -2183,7 +2183,8 @@ PRE(sys_timer_create)
Mark Wielaard 4714e5
                     sizeof(int) );
Mark Wielaard 4714e5
       PRE_MEM_READ( "timer_create(evp.sigev_notify)", (Addr)&evp->sigev_notify,
Mark Wielaard 4714e5
                     sizeof(int) );
Mark Wielaard 4714e5
-      if ((evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
Mark Wielaard 4714e5
+      if (ML_(safe_to_deref)(&evp->sigev_notify, sizeof(int))
Mark Wielaard 4714e5
+          && (evp->sigev_notify & VKI_SIGEV_THREAD_ID) != 0)
Mark Wielaard 4714e5
          PRE_MEM_READ( "timer_create(evp.sigev_notify_thread_id)",
Mark Wielaard 4714e5
                        (Addr)&evp->vki_sigev_notify_thread_id, sizeof(int) );
Mark Wielaard 4714e5
    }
Mark Wielaard 4714e5
diff --git a/memcheck/tests/x86-linux/scalar.stderr.exp b/memcheck/tests/x86-linux/scalar.stderr.exp
Mark Wielaard 4714e5
index e1a2bf2..2114db9 100644
Mark Wielaard 4714e5
--- a/memcheck/tests/x86-linux/scalar.stderr.exp
Mark Wielaard 4714e5
+++ b/memcheck/tests/x86-linux/scalar.stderr.exp
Mark Wielaard 4714e5
@@ -3602,7 +3602,17 @@ Syscall param timer_create(timerid) contains uninitialised byte(s)
Mark Wielaard 4714e5
    ...
Mark Wielaard 4714e5
    by 0x........: main (scalar.c:1158)
Mark Wielaard 4714e5
 
Mark Wielaard 4714e5
-Syscall param timer_create(evp) points to unaddressable byte(s)
Mark Wielaard 4714e5
+Syscall param timer_create(evp.sigev_value) points to unaddressable byte(s)
Mark Wielaard 4714e5
+   ...
Mark Wielaard 4714e5
+   by 0x........: main (scalar.c:1158)
Mark Wielaard 4714e5
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
Mark Wielaard 4714e5
+
Mark Wielaard 4714e5
+Syscall param timer_create(evp.sigev_signo) points to unaddressable byte(s)
Mark Wielaard 4714e5
+   ...
Mark Wielaard 4714e5
+   by 0x........: main (scalar.c:1158)
Mark Wielaard 4714e5
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
Mark Wielaard 4714e5
+
Mark Wielaard 4714e5
+Syscall param timer_create(evp.sigev_notify) points to unaddressable byte(s)
Mark Wielaard 4714e5
    ...
Mark Wielaard 4714e5
    by 0x........: main (scalar.c:1158)
Mark Wielaard 4714e5
  Address 0x........ is not stack'd, malloc'd or (recently) free'd