]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix crash when old/new sigprocmask isn't safe to dereference. Bug #369360.
authorMark Wielaard <mark@klomp.org>
Sat, 1 Oct 2016 11:54:47 +0000 (11:54 +0000)
committerMark Wielaard <mark@klomp.org>
Sat, 1 Oct 2016 11:54:47 +0000 (11:54 +0000)
Since we want to use the set and oldset for bookkeeping we also want
to make sure they are addressable otherwise, like the kernel, we EFAULT.
Also use EINVAL instead of EMFILE as failure when sigset size is wrong.

Found by LTP testcases/kernel/syscalls/rt_sigprocmask/rt_sigprocmask02.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15992

NEWS
coregrind/m_syswrap/syswrap-linux.c

diff --git a/NEWS b/NEWS
index d8c1c869e3ea3d32278902acb05e7b750fe7c08c..fca22bed0b4a09936e6bb7bedbade2d7f8d08d4f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -182,6 +182,7 @@ where XXXXXX is the bug number as listed below.
 369209  valgrind loops and eats up all memory if cwd doesn't exist.
 369356  pre_mem_read_sockaddr syscall wrapper can crash with bad sockaddr
 369359  msghdr_foreachfield can crash when handling bad iovec
+369360  Bad sigprocmask old or new sets can crash valgrind
 
 n-i-bz Fix incorrect (or infinite loop) unwind on RHEL7 x86 and amd64
 n-i-bz massif --pages-as-heap=yes does not report peak caused by mmap+munmap
index 36fadbba8c04ea62aeb8fe629d8e896ed4568390..797448427a6888508f8ff1160bff81f4a657844a 100644 (file)
@@ -3408,8 +3408,23 @@ PRE(sys_rt_sigprocmask)
       PRE_MEM_WRITE( "rt_sigprocmask(oldset)", ARG3, sizeof(vki_sigset_t));
 
    // Like the kernel, we fail if the sigsetsize is not exactly what we expect.
+   // Since we want to use the set and oldset for bookkeeping we also want
+   // to make sure they are addressable otherwise, like the kernel, we EFAULT.
    if (sizeof(vki_sigset_t) != ARG4)
-      SET_STATUS_Failure( VKI_EMFILE );
+      SET_STATUS_Failure( VKI_EINVAL );
+   else if (ARG2 != 0
+             && ! ML_(safe_to_deref)((void *)ARG2, sizeof(vki_sigset_t))) {
+            VG_(dmsg)("Warning: Bad set handler address %p in sigprocmask\n",
+                      (void *)ARG2);
+            SET_STATUS_Failure ( VKI_EFAULT );
+         }
+   else if (ARG3 != 0
+             && ! ML_(safe_to_deref)((void *)ARG3, sizeof(vki_sigset_t))) {
+            VG_(dmsg)("Warning: Bad oldset address %p in sigprocmask\n",
+                      (void *)ARG3);
+            SET_STATUS_Failure ( VKI_EFAULT );
+         }
+
    else {
       SET_STATUS_from_SysRes( 
                   VG_(do_sys_sigprocmask) ( tid, ARG1 /*how*/,