]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Sanitize signal mask in ppoll and pselect syscalls
authorIvo Raisr <ivosh@ivosh.net>
Tue, 8 Mar 2016 09:04:48 +0000 (09:04 +0000)
committerIvo Raisr <ivosh@ivosh.net>
Tue, 8 Mar 2016 09:04:48 +0000 (09:04 +0000)
Reported and Linux patch contributed by Steven Smith <sos22@archy.org.uk>
Fixes BZ#359871

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

24 files changed:
NEWS
coregrind/m_syswrap/priv_syswrap-main.h
coregrind/m_syswrap/syswrap-amd64-linux.c
coregrind/m_syswrap/syswrap-arm-linux.c
coregrind/m_syswrap/syswrap-arm64-linux.c
coregrind/m_syswrap/syswrap-linux.c
coregrind/m_syswrap/syswrap-main.c
coregrind/m_syswrap/syswrap-mips64-linux.c
coregrind/m_syswrap/syswrap-ppc32-linux.c
coregrind/m_syswrap/syswrap-ppc64-linux.c
coregrind/m_syswrap/syswrap-s390x-linux.c
coregrind/m_syswrap/syswrap-solaris.c
coregrind/m_syswrap/syswrap-tilegx-linux.c
coregrind/m_syswrap/syswrap-x86-linux.c
none/tests/Makefile.am
none/tests/ppoll_alarm.c [new file with mode: 0644]
none/tests/ppoll_alarm.stderr.exp [new file with mode: 0644]
none/tests/ppoll_alarm.stdout.exp [new file with mode: 0644]
none/tests/ppoll_alarm.vgtest [new file with mode: 0644]
none/tests/pselect_alarm.c [new file with mode: 0644]
none/tests/pselect_alarm.stderr.exp [new file with mode: 0644]
none/tests/pselect_alarm.stdout.exp [new file with mode: 0644]
none/tests/pselect_alarm.vgtest [new file with mode: 0644]
tests/filter_stderr_basic

diff --git a/NEWS b/NEWS
index 3164e146fa1eac91105746ccde776404384a3752..32482404ceb46bf98f7ad227698abb146d482f0f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -79,6 +79,7 @@ where XXXXXX is the bug number as listed below.
 359733  amd64 implement ld.so strchr/index override like x86
 359829  PowerPC test none/tests/ppc64/test_isa_2_07.c uninitialized memory
         references was fixed.
+359871  Incorrect mask handling in ppoll
 
 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 cabad7ccc50d601bf9073dfd4fc24a1682889296..3164c81bf8891de61215f5b3a75e9990bcf817d2 100644 (file)
@@ -38,6 +38,9 @@
 extern
 void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch );
 
+extern
+void VG_(sanitize_client_sigmask)(vki_sigset_t *mask);
+
 #if defined(VGO_darwin)
 /* Longjmp to scheduler after client calls workq_ops(WQOPS_THREAD_RETURN)*/
 extern
index 7c88bc225dbec27d410b21ee9f4e4b8d15b7048d..4a8344b886df4974487c0088674dff3b33627ca3 100644 (file)
@@ -1018,7 +1018,7 @@ static SyscallTableEntry syscall_table[] = {
    LINX_(__NR_fchmodat,                 sys_fchmodat),         // 268
    LINX_(__NR_faccessat,        sys_faccessat),        // 269
 
-   LINX_(__NR_pselect6,                 sys_pselect6),         // 270
+   LINXY(__NR_pselect6,                 sys_pselect6),         // 270
    LINXY(__NR_ppoll,            sys_ppoll),            // 271
    LINX_(__NR_unshare,          sys_unshare),          // 272
    LINX_(__NR_set_robust_list,  sys_set_robust_list),  // 273
index 3ccad12c2b3a12526edd8c94733782b364420c73..224070cb16ee6ce80297179a1aba4cec85d95ce0 100644 (file)
@@ -1188,7 +1188,7 @@ static SyscallTableEntry syscall_main_table[] = {
 
    LINX_(__NR_arm_fadvise64_64,  sys_fadvise64_64),     // 270 */(Linux?)
 
-   LINX_(__NR_pselect6,          sys_pselect6),         // 335
+   LINXY(__NR_pselect6,          sys_pselect6),         // 335
    LINXY(__NR_ppoll,             sys_ppoll),            // 336
 
    LINXY(__NR_epoll_pwait,       sys_epoll_pwait),      // 346
index 8d3027de653eeb5bf27579b657ca4a564675d3e7..abddff1839f6027b5bc53943d2b1e85c95f5cfd0 100644 (file)
@@ -924,7 +924,7 @@ static SyscallTableEntry syscall_main_table[] = {
    GENX_(__NR_writev,            sys_writev),            // 66
    GENXY(__NR_pread64,           sys_pread64),           // 67
    GENX_(__NR_pwrite64,          sys_pwrite64),          // 68
-   LINX_(__NR_pselect6,          sys_pselect6),          // 72
+   LINXY(__NR_pselect6,          sys_pselect6),          // 72
    LINXY(__NR_ppoll,             sys_ppoll),             // 73
    LINXY(__NR_signalfd4,         sys_signalfd4),         // 74
    LINX_(__NR_readlinkat,        sys_readlinkat),        // 78
index f2d10764312d9b5f1fbdf7945324ab9b6b5aef8f..6fdacda4b0c5431a0863674215dab2283a3563e8 100644 (file)
@@ -62,6 +62,7 @@
 #include "priv_types_n_macros.h"
 #include "priv_syswrap-generic.h"
 #include "priv_syswrap-linux.h"
+#include "priv_syswrap-main.h"
 #include "priv_syswrap-xen.h"
 
 // Run a thread from beginning to end and return the thread's
@@ -1272,9 +1273,18 @@ POST(sys_get_robust_list)
    POST_MEM_WRITE(ARG3, sizeof(struct vki_size_t *));
 }
 
+struct pselect_sized_sigset {
+    const vki_sigset_t *ss;
+    vki_size_t ss_len;
+};
+struct pselect_adjusted_sigset {
+    struct pselect_sized_sigset ss; /* The actual syscall arg */
+    vki_sigset_t adjusted_ss;
+};
+
 PRE(sys_pselect6)
 {
-   *flags |= SfMayBlock;
+   *flags |= SfMayBlock | SfPostOnFail;
    PRINT("sys_pselect6 ( %ld, %#lx, %#lx, %#lx, %#lx, %#lx )",
          SARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
    PRE_REG_READ6(long, "pselect6",
@@ -1293,15 +1303,41 @@ PRE(sys_pselect6)
                     ARG4, ARG1/8 /* __FD_SETSIZE/8 */ );
    if (ARG5 != 0)
       PRE_MEM_READ( "pselect6(timeout)", ARG5, sizeof(struct vki_timeval) );
-   if (ARG6 != 0)
-      PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(void *)+sizeof(vki_size_t) );
+   if (ARG6 != 0) {
+      const struct pselect_sized_sigset *pss =
+          (struct pselect_sized_sigset *)ARG6;
+      PRE_MEM_READ( "pselect6(sig)", ARG6, sizeof(*pss) );
+      if (!ML_(safe_to_deref)(pss, sizeof(*pss))) {
+         ARG6 = 1; /* Something recognisable to POST() hook. */
+      } else {
+         struct pselect_adjusted_sigset *pas;
+         pas = VG_(malloc)("syswrap.pselect6.1", sizeof(*pas));
+         ARG6 = (Addr)pas;
+         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);
+            }
+         }
+      }
+   }
+}
+POST(sys_pselect6)
+{
+   if (ARG6 != 0 && ARG6 != 1) {
+       VG_(free)((struct pselect_adjusted_sigset *)ARG6);
+   }
 }
 
 PRE(sys_ppoll)
 {
    UInt i;
    struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
-   *flags |= SfMayBlock;
+   *flags |= SfMayBlock | SfPostOnFail;
    PRINT("sys_ppoll ( %#lx, %lu, %#lx, %#lx, %lu )\n", ARG1,ARG2,ARG3,ARG4,ARG5);
    PRE_REG_READ5(long, "ppoll",
                  struct vki_pollfd *, ufds, unsigned int, nfds,
@@ -1319,18 +1355,33 @@ PRE(sys_ppoll)
 
    if (ARG3)
       PRE_MEM_READ( "ppoll(tsp)", ARG3, sizeof(struct vki_timespec) );
-   if (ARG4)
-      PRE_MEM_READ( "ppoll(sigmask)", ARG4, sizeof(vki_sigset_t) );
+   if (ARG4 != 0 && sizeof(vki_sigset_t) == ARG5) {
+      const vki_sigset_t *guest_sigmask = (vki_sigset_t *)ARG4;
+      PRE_MEM_READ( "ppoll(sigmask)", ARG4, ARG5);
+      if (!ML_(safe_to_deref)(guest_sigmask, sizeof(*guest_sigmask))) {
+         ARG4 = 1; /* Something recognisable to POST() hook. */
+      } else {
+         vki_sigset_t *vg_sigmask =
+             VG_(malloc)("syswrap.ppoll.1", sizeof(*vg_sigmask));
+         ARG4 = (Addr)vg_sigmask;
+         *vg_sigmask = *guest_sigmask;
+         VG_(sanitize_client_sigmask)(vg_sigmask);
+      }
+   }
 }
 
 POST(sys_ppoll)
 {
-   if (RES > 0) {
+   vg_assert(SUCCESS || FAILURE);
+   if (SUCCESS && (RES >= 0)) {
       UInt i;
       struct vki_pollfd* ufds = (struct vki_pollfd *)ARG1;
       for (i = 0; i < ARG2; i++)
         POST_MEM_WRITE( (Addr)(&ufds[i].revents), sizeof(ufds[i].revents) );
    }
+   if (ARG4 != 0 && ARG5 == sizeof(vki_sigset_t) && ARG4 != 1) {
+      VG_(free)((vki_sigset_t *) ARG4);
+   }
 }
 
 
index 054891f7ebe7b6afe9f15f6059b8d41373923fc4..d85419473efc91856802523c07c6fab69754086e 100644 (file)
@@ -1657,7 +1657,7 @@ static const SyscallTableEntry* get_syscall_entry ( Int syscallno )
 /* Add and remove signals from mask so that we end up telling the
    kernel the state we actually want rather than what the client
    wants. */
-static void sanitize_client_sigmask(vki_sigset_t *mask)
+void VG_(sanitize_client_sigmask)(vki_sigset_t *mask)
 {
    VG_(sigdelset)(mask, VKI_SIGKILL);
    VG_(sigdelset)(mask, VKI_SIGSTOP);
@@ -1979,7 +1979,7 @@ void VG_(client_syscall) ( ThreadId tid, UInt trc )
          PRINT(" --> [async] ... \n");
 
          mask = tst->sig_mask;
-         sanitize_client_sigmask(&mask);
+         VG_(sanitize_client_sigmask)(&mask);
 
          /* Gack.  More impedance matching.  Copy the possibly
             modified syscall args back into the guest state. */
index 12d147dfdb8d16f8b7af0509c4d7468c32c2cf33..7c5fbdbb519bec1e66f4023667f4daf0fc3bbfde 100644 (file)
@@ -889,7 +889,7 @@ static SyscallTableEntry syscall_main_table[] = {
    LINX_ (__NR_readlinkat, sys_readlinkat),
    LINX_ (__NR_fchmodat, sys_fchmodat),
    LINX_ (__NR_faccessat, sys_faccessat),
-   LINX_ (__NR_pselect6, sys_pselect6),
+   LINXY (__NR_pselect6, sys_pselect6),
    LINXY (__NR_ppoll, sys_ppoll),
    PLAX_ (__NR_unshare, sys_unshare),
    PLAX_ (__NR_splice, sys_splice),
index 9ceaa15148149e2f419a7794cd3e33520f2d6fa8..379fcb383ea96054892e43ccf6db98041a1dbeda 100644 (file)
@@ -1194,7 +1194,7 @@ static SyscallTableEntry syscall_table[] = {
    PLAXY(__NR_spu_run,            sys_spu_run),               // 278
    PLAX_(__NR_spu_create,         sys_spu_create),            // 279
 
-   LINX_(__NR_pselect6,          sys_pselect6),          // 280
+   LINXY(__NR_pselect6,          sys_pselect6),          // 280
    LINXY(__NR_ppoll,             sys_ppoll),             // 281
 
    LINXY(__NR_openat,            sys_openat),            // 286
index 15b8979eb1f95f964883daeea44049ea9507702b..77668c7b2087f5c2de73faca0bd2daf46fd3a7f0 100644 (file)
@@ -1110,7 +1110,7 @@ static SyscallTableEntry syscall_table[] = {
    LINX_(__NR_inotify_add_watch,  sys_inotify_add_watch), // 276
    LINX_(__NR_inotify_rm_watch,   sys_inotify_rm_watch),  // 277
 
-   LINX_(__NR_pselect6,          sys_pselect6),           // 280
+   LINXY(__NR_pselect6,          sys_pselect6),           // 280
    LINXY(__NR_ppoll,             sys_ppoll),              // 281
 
    LINXY(__NR_openat,            sys_openat),             // 286
index 05137893237a44557a5fb0fef6de2d4ee72205c5..107a569633feeb8118b4e31c4a5f882787570324 100644 (file)
@@ -992,7 +992,7 @@ static SyscallTableEntry syscall_table[] = {
    LINX_(__NR_fchmodat,  sys_fchmodat),                               // 299
 
    LINX_(__NR_faccessat,  sys_faccessat),                             // 300
-   LINX_(__NR_pselect6, sys_pselect6),                                // 301
+   LINXY(__NR_pselect6, sys_pselect6),                                // 301
    LINXY(__NR_ppoll, sys_ppoll),                                      // 302
    LINX_(__NR_unshare, sys_unshare),                                  // 303
    LINX_(__NR_set_robust_list,  sys_set_robust_list),                 // 304
index 7ac876fe8c8c84024aa93c9b8f0b2673e160e046..a307f6c38aa932e6933b748d4ad5958aae933f4c 100644 (file)
@@ -71,6 +71,7 @@
 
 #include "priv_types_n_macros.h"
 #include "priv_syswrap-generic.h"
+#include "priv_syswrap-main.h"
 #include "priv_syswrap-solaris.h"
 
 /* Return the number of non-dead and daemon threads.
@@ -7327,7 +7328,7 @@ PRE(sys_pollsys)
    UWord i;
    struct vki_pollfd *ufds = (struct vki_pollfd *)ARG1;
 
-   *flags |= SfMayBlock;
+   *flags |= SfMayBlock | SfPostOnFail;
 
    PRINT("sys_pollsys ( %#lx, %lu, %#lx, %#lx )", ARG1, ARG2, ARG3, ARG4);
    PRE_REG_READ4(long, "poll", pollfd_t *, fds, vki_nfds_t, nfds,
@@ -7343,18 +7344,37 @@ PRE(sys_pollsys)
 
    if (ARG3)
       PRE_MEM_READ("poll(timeout)", ARG3, sizeof(vki_timespec_t));
-   if (ARG4)
+
+   if (ARG4) {
       PRE_MEM_READ("poll(set)", ARG4, sizeof(vki_sigset_t));
+
+      const vki_sigset_t *guest_sigmask = (vki_sigset_t *) ARG4;
+      if (!ML_(safe_to_deref)(guest_sigmask, sizeof(vki_sigset_t))) {
+         ARG4 = 1; /* Something recognisable to POST() hook. */
+      } else {
+         vki_sigset_t *vg_sigmask =
+            VG_(malloc)("syswrap.pollsys.1", sizeof(vki_sigset_t));
+         ARG4 = (Addr) vg_sigmask;
+         *vg_sigmask = *guest_sigmask;
+         VG_(sanitize_client_sigmask)(vg_sigmask);
+      }
+   }
 }
 
 POST(sys_pollsys)
 {
-   if (RES >= 0) {
+   vg_assert(SUCCESS || FAILURE);
+
+   if (SUCCESS && (RES >= 0)) {
       UWord i;
       vki_pollfd_t *ufds = (vki_pollfd_t*)ARG1;
       for (i = 0; i < ARG2; i++)
          POST_FIELD_WRITE(ufds[i].revents);
    }
+
+   if ((ARG4 != 0) && (ARG4 != 1)) {
+      VG_(free)((vki_sigset_t *) ARG4);
+   }
 }
 
 PRE(sys_labelsys)
index aceceb465ef3e555ea90bec3003f93a654bd3585..4845f79fb8d7033b1fe58b9b54485f84e8ced37c 100644 (file)
@@ -1202,7 +1202,7 @@ static SyscallTableEntry syscall_table[] = {
   LINXY(__NR_preadv,            sys_preadv),               // 69
   LINX_(__NR_pwritev,           sys_pwritev),              // 70
   LINXY(__NR_sendfile,          sys_sendfile),             // 71
-  LINX_(__NR_pselect6,          sys_pselect6),             // 72
+  LINXY(__NR_pselect6,          sys_pselect6),             // 72
   LINXY(__NR_ppoll,             sys_ppoll),                // 73
   LINXY(__NR_signalfd4,         sys_signalfd4),            // 74
   LINX_(__NR_splice,            sys_splice),               // 75
index 3c80e6a2b778d9caf5c2602da9e7483927d1110e..f1f97d70ca12aa88099cfcff24ee8731505d85e2 100644 (file)
@@ -1766,7 +1766,7 @@ static SyscallTableEntry syscall_table[] = {
    LINX_(__NR_readlinkat,       sys_readlinkat),       // 305
    LINX_(__NR_fchmodat,                 sys_fchmodat),         // 306
    LINX_(__NR_faccessat,        sys_faccessat),        // 307
-   LINX_(__NR_pselect6,                 sys_pselect6),         // 308
+   LINXY(__NR_pselect6,                 sys_pselect6),         // 308
    LINXY(__NR_ppoll,            sys_ppoll),            // 309
 
    LINX_(__NR_unshare,          sys_unshare),          // 310
index 7eb2bf855cdc4ea403e30646a3b5e210e054ec75..5d8e942eaa9f07b9fd71fd65bbc4321cce7b80f7 100644 (file)
@@ -142,12 +142,14 @@ EXTRA_DIST = \
        nestedfns.stderr.exp nestedfns.stdout.exp nestedfns.vgtest \
        nodir.stderr.exp nodir.vgtest \
        pending.stdout.exp pending.stderr.exp pending.vgtest \
+       ppoll_alarm.stdout.exp ppoll_alarm.stderr.exp ppoll_alarm.vgtest \
        procfs-linux.stderr.exp-with-readlinkat \
        procfs-linux.stderr.exp-without-readlinkat \
        procfs-linux.vgtest \
        procfs-non-linux.vgtest \
        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 \
        pth_atfork1.stderr.exp pth_atfork1.stdout.exp pth_atfork1.vgtest \
        pth_blockedsig.stderr.exp \
        pth_blockedsig.stdout.exp pth_blockedsig.vgtest \
@@ -215,7 +217,9 @@ check_PROGRAMS = \
        mmap_fcntl_bug \
        munmap_exe map_unaligned map_unmap mq \
        pending \
+       ppoll_alarm \
        procfs-cmdline-exe \
+       pselect_alarm \
        pth_atfork1 pth_blockedsig pth_cancel1 pth_cancel2 pth_cvsimple \
        pth_empty pth_exit pth_exit2 pth_mutexspeed pth_once pth_rwlock \
        pth_stackalign \
@@ -289,6 +293,8 @@ libvexmultiarch_test_LDADD = \
        ../../VEX/libvexmultiarch-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a \
        ../../VEX/libvex-@VGCONF_ARCH_PRI@-@VGCONF_OS@.a @LIB_UBSAN@
 libvexmultiarch_test_SOURCES = libvex_test.c
+ppoll_alarm_LDADD      = -lpthread
+pselect_alarm_LDADD    = -lpthread
 pth_atfork1_LDADD      = -lpthread
 pth_blockedsig_LDADD   = -lpthread
 pth_cancel1_CFLAGS     = $(AM_CFLAGS) -Wno-shadow
diff --git a/none/tests/ppoll_alarm.c b/none/tests/ppoll_alarm.c
new file mode 100644 (file)
index 0000000..1b1794b
--- /dev/null
@@ -0,0 +1,55 @@
+/* Tries to exploit bug in ppoll mask handling:
+   https://bugs.kde.org/show_bug.cgi?id=359871
+   where client program was able to successfully block VG_SIGVGKILL. */
+
+#define _GNU_SOURCE /* for ppoll */
+#include <poll.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int ready = 0;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+static void *
+mythr(void *ignore)
+{
+    pthread_mutex_lock(&mutex);
+    ready = 1;
+    pthread_cond_signal(&cond);
+    pthread_mutex_unlock(&mutex);
+
+    sigset_t ss;
+    sigfillset(&ss);
+    while (1) {
+        struct timespec ts = {10000, 0};
+        ppoll(NULL, 0, &ts, &ss);
+    }
+
+    return NULL;
+}
+
+int
+main()
+{
+    pthread_t thr;
+    int ret = pthread_create(&thr, NULL, mythr, NULL);
+    if (ret != 0) {
+        fprintf(stderr, "pthread_create failed\n");
+        return 1;
+    }
+
+    pthread_mutex_lock(&mutex);
+    while (ready == 0) {
+        pthread_cond_wait(&cond, &mutex);
+    }
+    pthread_mutex_unlock(&mutex);
+
+    alarm(1); /* Unhandled SIGALRM should cause exit. */
+    while (1)
+        sleep(1);
+
+    return 0;
+}
diff --git a/none/tests/ppoll_alarm.stderr.exp b/none/tests/ppoll_alarm.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/ppoll_alarm.stdout.exp b/none/tests/ppoll_alarm.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/ppoll_alarm.vgtest b/none/tests/ppoll_alarm.vgtest
new file mode 100644 (file)
index 0000000..b1309d3
--- /dev/null
@@ -0,0 +1,3 @@
+prog: ppoll_alarm
+vgopts: -q
+stderr_filter: filter_stderr
diff --git a/none/tests/pselect_alarm.c b/none/tests/pselect_alarm.c
new file mode 100644 (file)
index 0000000..7a68ec0
--- /dev/null
@@ -0,0 +1,61 @@
+/* Tries to exploit bug in pselect mask handling:
+   https://bugs.kde.org/show_bug.cgi?id=359871
+   where client program was able to successfully block VG_SIGVGKILL. */
+
+#include <sys/select.h>
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static int ready = 0;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+static void *
+mythr(void *ignore)
+{
+    pthread_mutex_lock(&mutex);
+    ready = 1;
+    pthread_cond_signal(&cond);
+    pthread_mutex_unlock(&mutex);
+
+    sigset_t ss;
+    sigfillset(&ss);
+    while (1) {
+        struct timespec ts = {10000, 0};
+        pselect(0, NULL, NULL, NULL, &ts, &ss);
+    }
+
+    return NULL;
+}
+
+int
+main()
+{
+    pthread_t thr;
+    int ret = pthread_create(&thr, NULL, mythr, NULL);
+    if (ret != 0) {
+        fprintf(stderr, "pthread_create failed\n");
+        return 1;
+    }
+
+    pthread_mutex_lock(&mutex);
+    while (ready == 0) {
+        pthread_cond_wait(&cond, &mutex);
+    }
+    pthread_mutex_unlock(&mutex);
+
+#if defined(VGO_linux)
+    assert(pselect(0, NULL, NULL, NULL, NULL, (sigset_t *)12) == -1);
+    assert(errno == EFAULT);
+#endif
+
+    alarm(1); /* Unhandled SIGALRM should cause exit. */
+    while (1)
+        sleep(1);
+
+    return 0;
+}
diff --git a/none/tests/pselect_alarm.stderr.exp b/none/tests/pselect_alarm.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/pselect_alarm.stdout.exp b/none/tests/pselect_alarm.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/pselect_alarm.vgtest b/none/tests/pselect_alarm.vgtest
new file mode 100644 (file)
index 0000000..84cc674
--- /dev/null
@@ -0,0 +1,3 @@
+prog: pselect_alarm
+vgopts: -q
+stderr_filter: filter_stderr
index 472cd8fb4dc6578d89cc8975478fd07baeffc54a..4b6e4806be6e6cee9fb7dba514690097a76ce321 100755 (executable)
@@ -46,7 +46,7 @@ sed "/warning: line info addresses out of order/d" |
 # of the bash process. Newer bash versions redirect such messages properly.
 # Suppress any redirected abnormal termination messages. You can find the
 # complete list of messages in the bash source file siglist.c.
-perl -n -e 'print if !/^(Segmentation fault|Alarm clock|Aborted|Bus error)( \(core dumped\))?$/' |
+perl -n -e 'print if !/^(Segmentation fault|Alarm clock|Aborted|Bus error|Killed)( \(core dumped\))?$/' |
 
 # Similar as above, but for ksh on Solaris/illumos.
 perl -n -e 'print if !/^(Memory fault|Killed) $/' |