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