]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 364413 pselect sycallwrapper mishandles NULL sigmask.
authorMark Wielaard <mark@klomp.org>
Tue, 21 Jun 2016 19:58:21 +0000 (19:58 +0000)
committerMark Wielaard <mark@klomp.org>
Tue, 21 Jun 2016 19:58:21 +0000 (19:58 +0000)
Don't check or try to copy sigmask if it is NULL. The sigmask might be
given in a struct, where the length is non-zero, but the signal set
pointer is NULL.

Testcase provided by Paul Eggert <eggert@cs.ucla.edu>.

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

NEWS
coregrind/m_syswrap/syswrap-linux.c
none/tests/Makefile.am
none/tests/pselect_sigmask_null.c [new file with mode: 0644]
none/tests/pselect_sigmask_null.stderr.exp [new file with mode: 0644]
none/tests/pselect_sigmask_null.stdout.exp [new file with mode: 0644]
none/tests/pselect_sigmask_null.vgtest [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 459ce4aaa9e15c7ef4f8dc35c422dbd669f197ef..bbccbee36c20839887a8fd42d43ac456fd486316 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -107,6 +107,7 @@ where XXXXXX is the bug number as listed below.
 363680  add renameat2() support
 363705  arm64 missing syscall name_to_handle_at and open_by_handle_at
 363714  ppc64 missing syscalls sync, waitid and name_to/open_by_handle_at
+364413  pselect sycallwrapper mishandles NULL sigmask
 
 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 24a5ae9db63dff49f1073877df79b6f22d2fd7e5..9ace4fde7fa9f3574f388e9d18f3a5694e756e63 100644 (file)
@@ -1316,11 +1316,15 @@ PRE(sys_pselect6)
          pas->ss.ss = (void *)1;
          pas->ss.ss_len = pss->ss_len;
          if (pss->ss_len == sizeof(*pss->ss)) {
-            PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
-            if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
-               pas->adjusted_ss = *pss->ss;
-               pas->ss.ss = &pas->adjusted_ss;
-               VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
+            if (pss->ss == NULL) {
+               pas->ss.ss = NULL;
+            } else {
+               PRE_MEM_READ("pselect6(sig->ss)", (Addr)pss->ss, pss->ss_len);
+               if (ML_(safe_to_deref)(pss->ss, sizeof(*pss->ss))) {
+                  pas->adjusted_ss = *pss->ss;
+                  pas->ss.ss = &pas->adjusted_ss;
+                  VG_(sanitize_client_sigmask)(&pas->adjusted_ss);
+               }
             }
          }
       }
index 0e11492e84b2ad8aadfddf1aa2b2688ea2996508..684c1afaafa522e263e814d2c5b8f1cd2d9b46b7 100644 (file)
@@ -150,6 +150,8 @@ EXTRA_DIST = \
        procfs-non-linux.stderr.exp-with-readlinkat \
        procfs-non-linux.stderr.exp-without-readlinkat \
        pselect_alarm.stdout.exp pselect_alarm.stderr.exp pselect_alarm.vgtest \
+       pselect_signask_null.vgtest \
+       pselect_sigmask_null.stdout.exp pselect_sigmask_null.stderr.exp \
        pth_atfork1.stderr.exp pth_atfork1.stdout.exp pth_atfork1.vgtest \
        pth_blockedsig.stderr.exp \
        pth_blockedsig.stdout.exp pth_blockedsig.vgtest \
@@ -219,6 +221,7 @@ check_PROGRAMS = \
        pending \
        procfs-cmdline-exe \
        pselect_alarm \
+       pselect_sigmask_null \
        pth_atfork1 pth_blockedsig pth_cancel1 pth_cancel2 pth_cvsimple \
        pth_empty pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \
        pth_stackalign \
diff --git a/none/tests/pselect_sigmask_null.c b/none/tests/pselect_sigmask_null.c
new file mode 100644 (file)
index 0000000..34bd584
--- /dev/null
@@ -0,0 +1,26 @@
+/* Make sure handling of NULL sigmask is correct.
+   https://bugs.kde.org/show_bug.cgi?id=XXX
+   We might try to make a copy and adjust the mask.
+   Testcase provided by Paul Eggert <eggert@cs.ucla.edu> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/select.h>
+
+int
+main (void)
+{
+  struct timespec timeout;
+  timeout.tv_sec = 1;
+  timeout.tv_nsec = 0;
+  switch (pselect (0, 0, 0, 0, &timeout, 0))
+    {
+    default:
+      abort ();
+    case -1:
+      perror ("pselect");
+      return 1;
+    case 0:
+      return 0;
+    }
+}
diff --git a/none/tests/pselect_sigmask_null.stderr.exp b/none/tests/pselect_sigmask_null.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/pselect_sigmask_null.stdout.exp b/none/tests/pselect_sigmask_null.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/pselect_sigmask_null.vgtest b/none/tests/pselect_sigmask_null.vgtest
new file mode 100644 (file)
index 0000000..e59688c
--- /dev/null
@@ -0,0 +1,2 @@
+prog: pselect_sigmask_null
+vgopts: -q