]> granicus.if.org Git - strace/commitdiff
alpha, cris, mips, ppc, sh, sparc: fix decoding of sigsuspend syscall
authorDmitry V. Levin <ldv@altlinux.org>
Sun, 30 Apr 2017 20:33:04 +0000 (20:33 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Mon, 1 May 2017 14:49:26 +0000 (14:49 +0000)
On some architectures old sigsuspend syscall takes the signal mask from
the 3rd argument, on some from the 1st.  And, if it wasn't peculiar
enough, the signal mask is passed by value on all architectures except
mips where it's passed by reference.

* signal.c (SYS_FUNC(sigsuspend)): Take the signal mask from the last
argument.
* linux/alpha/syscallent.h (sigsuspend): Set nargs to 1.
* linux/crisv10/syscallent.h: Likewise.
* linux/mips/syscallent-o32.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/powerpc64/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
* linux/sparc64/syscallent.h: Likewise.
* tests/sigsuspend.c: New file.
* tests/gen_tests.in (sigsuspend): New entry.
* tests/pure_executables.list: Add sigsuspend.
* tests/.gitignore: Likewise.
* NEWS: Mention this fix.

15 files changed:
NEWS
linux/alpha/syscallent.h
linux/crisv10/syscallent.h
linux/mips/syscallent-o32.h
linux/powerpc/syscallent.h
linux/powerpc64/syscallent.h
linux/sh/syscallent.h
linux/sh64/syscallent.h
linux/sparc/syscallent.h
linux/sparc64/syscallent.h
signal.c
tests/.gitignore
tests/gen_tests.in
tests/pure_executables.list
tests/sigsuspend.c [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index dd6bd88bf1008368386dae4bb2f46a80d6ec909a..b109d98d8c028d0ec65b6a8bc8f6fd8a22324b10 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,8 @@ Noteworthy changes in release ?.?? (????-??-??)
 * Bug fixes
   * Fixed decoding of flags argument of preadv2 and pwritev2 syscalls on x32.
   * Fixed the number of arguments and tracing flags of alpha specific syscalls.
+  * Fixed decoding of old sigsuspend syscall on alpha, cris, mips, powerpc,
+    powerpc64, sh, sh64, sparc, and sparc64.
   * Fixed decoding of netlink messages received within struct msghdr.
   * Worked around a bug in miscompiled aarch64 kernels leading to the 3rd
     argument of sched_getattr syscall being not quite 32-bit.
index d9367cff0c7a4c387fde1cd85b071b982a1b02b9..6ea965b16caae6b67cbb8ea267dcbe288e01f22f 100644 (file)
 [108] = { 5,   0,              SEN(printargs),                 "osf_old_sigvec"        }, /* not implemented */
 [109] = { 5,   0,              SEN(printargs),                 "osf_old_sigblock"      }, /* not implemented */
 [110] = { 5,   0,              SEN(printargs),                 "osf_old_sigsetmask"    }, /* not implemented */
-[111] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[111] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [112] = { 2,   0,              SEN(printargs),                 "osf_sigstack"          },
 [113] = { 3,   TN,             SEN(recvmsg),                   "recvmsg"               },
 [114] = { 3,   TN,             SEN(sendmsg),                   "sendmsg"               },
index 0f77fe54fb7ccecd2233fc68e08b0a41de152b6c..c384a8bc35d50ecf03ed3e49ea83378777d6392c 100644 (file)
@@ -70,7 +70,7 @@
 [ 69] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
 [ 70] = { 2,   0,              SEN(setreuid16),                "setreuid"              },
 [ 71] = { 2,   0,              SEN(setregid16),                "setregid"              },
-[ 72] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[ 72] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [ 73] = { 1,   TS,             SEN(sigpending),                "sigpending"            },
 [ 74] = { 2,   0,              SEN(sethostname),               "sethostname"           },
 [ 75] = { 2,   0,              SEN(setrlimit),                 "setrlimit"             },
index b319f07a01020a443c1a25f0ad7eb4104206a232..c47525144a2f3ca4a9f8b4223bf48bcd65f77fb4 100644 (file)
@@ -72,7 +72,7 @@
 [4069] = { 1,  TS,             SEN(sigsetmask),                "ssetmask"              },
 [4070] = { 2,  0,              SEN(setreuid),                  "setreuid"              },
 [4071] = { 2,  0,              SEN(setregid),                  "setregid"              },
-[4072] = { 3,  TS,             SEN(sigsuspend),                "sigsuspend"            },
+[4072] = { 1,  TS,             SEN(sigsuspend),                "sigsuspend"            },
 [4073] = { 1,  TS,             SEN(sigpending),                "sigpending"            },
 [4074] = { 2,  0,              SEN(sethostname),               "sethostname"           },
 [4075] = { 2,  0,              SEN(setrlimit),                 "setrlimit"             },
index 90a9103b3f0c32239cfa00d8aa90e53b36817f2b..69c2ac18e89ca5e0b12f1f7747ab700f3ca211ab 100644 (file)
@@ -98,7 +98,7 @@
 [ 69] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
 [ 70] = { 2,   0,              SEN(setreuid),                  "setreuid"              },
 [ 71] = { 2,   0,              SEN(setregid),                  "setregid"              },
-[ 72] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[ 72] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [ 73] = { 1,   TS,             SEN(sigpending),                "sigpending"            },
 [ 74] = { 2,   0,              SEN(sethostname),               "sethostname"           },
 [ 75] = { 2,   0,              SEN(setrlimit),                 "setrlimit"             },
index 23962bd0cd7a321d485b7fd7e30c587b6cbeb781..ce99ae6267e38175f20c4973c42aec128cd31435 100644 (file)
@@ -98,7 +98,7 @@
 [ 69] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
 [ 70] = { 2,   0,              SEN(setreuid),                  "setreuid"              },
 [ 71] = { 2,   0,              SEN(setregid),                  "setregid"              },
-[ 72] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[ 72] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [ 73] = { 1,   TS,             SEN(sigpending),                "sigpending"            },
 [ 74] = { 2,   0,              SEN(sethostname),               "sethostname"           },
 [ 75] = { 2,   0,              SEN(setrlimit),                 "setrlimit"             },
index eea1436574428fa69533702db2b6ccfed7f66a61..072aea28d2fd6f2eb8efdc7d6d32801f1833ca39 100644 (file)
 [ 69] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
 [ 70] = { 2,   0,              SEN(setreuid16),                "setreuid"              },
 [ 71] = { 2,   0,              SEN(setregid16),                "setregid"              },
-[ 72] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[ 72] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [ 73] = { 1,   TS,             SEN(sigpending),                "sigpending"            },
 [ 74] = { 2,   0,              SEN(sethostname),               "sethostname"           },
 [ 75] = { 2,   0,              SEN(setrlimit),                 "setrlimit"             },
index 2fb15bb9be533e8b133e83db5038384893075e8e..043c20e60635029e2ef2b3d42297365d77fd2cb8 100644 (file)
@@ -98,7 +98,7 @@
 [ 69] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
 [ 70] = { 2,   0,              SEN(setreuid16),                "setreuid"              },
 [ 71] = { 2,   0,              SEN(setregid16),                "setregid"              },
-[ 72] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[ 72] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [ 73] = { 1,   TS,             SEN(sigpending),                "sigpending"            },
 [ 74] = { 2,   0,              SEN(sethostname),               "sethostname"           },
 [ 75] = { 2,   0,              SEN(setrlimit),                 "setrlimit"             },
index 82e2a81b7b8742cd8091ba010054d38e6e03d3f1..c64b4461bbdba1b5100f72f75342237063b6fab6 100644 (file)
 [198] = { 3,   TS,             SEN(sigaction),                 "sigaction"             },
 [199] = { 0,   TS,             SEN(siggetmask),                "sgetmask"              },
 [200] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
-[201] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[201] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [202] = { 2,   TF|TLST|TSTA,   SEN(lstat),                     "oldlstat"              },
 [203] = { 1,   TF,             SEN(uselib),                    "uselib"                },
 [204] = { 3,   TD,             SEN(readdir),                   "readdir"               },
index 7a6f914df9f5735abbdffaa739c64c31d34e063a..b0308a55c24a085dd573dcb5bc0c1ef2727124a8 100644 (file)
 [198] = { 3,   TS,             SEN(sigaction),                 "sigaction"             },
 [199] = { 0,   TS,             SEN(siggetmask),                "sgetmask"              },
 [200] = { 1,   TS,             SEN(sigsetmask),                "ssetmask"              },
-[201] = { 3,   TS,             SEN(sigsuspend),                "sigsuspend"            },
+[201] = { 1,   TS,             SEN(sigsuspend),                "sigsuspend"            },
 [202] = { 2,   TF|TLST|TSTA,   SEN(lstat),                     "oldlstat"              },
 [203] = { 1,   TF,             SEN(uselib),                    "uselib"                },
 [204] = { 3,   TD,             SEN(readdir),                   "readdir"               },
index ef6dbc2eeacb3a0666da66fbf4847747486050f8..04ed10cbf460149397477f6b9f461e6440ac3e2b 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -385,7 +385,12 @@ SYS_FUNC(siggetmask)
 
 SYS_FUNC(sigsuspend)
 {
-       tprintsigmask_val("", tcp->u_arg[2]);
+#ifdef MIPS
+       print_sigset_addr_len(tcp, tcp->u_arg[tcp->s_ent->nargs - 1],
+                             current_wordsize);
+#else
+       tprintsigmask_val("", tcp->u_arg[tcp->s_ent->nargs - 1]);
+#endif
 
        return RVAL_DECODED;
 }
index d0a287372cc83a35c1fb661e8ef9bc69cd2b9968..722b5e030ec683b2cc6df388b86d3efabad12c66 100644 (file)
@@ -329,6 +329,7 @@ siginfo
 signal_receive
 signalfd4
 sigreturn
+sigsuspend
 sleep
 socketcall
 splice
index f7be375235d3d3948379f1868848b3d14e0eae53..24a2d3f13369f23748f3d5c2011b4b01ab0b2f91 100644 (file)
@@ -284,6 +284,7 @@ siginfo     -e trace=none
 signal_receive -a16 -e trace=kill
 signalfd4
 sigreturn      -esignal='!USR1'
+sigsuspend     -a19 -esignal=none
 socketcall     -a20
 splice
 stat   -a32 -v -P stat.sample -P /dev/full
index 7e474b53aa98e501e72280381f37bbce0e9b170e..ca7c6b79068d4413ac23b786147b8c56fb6928f6 100755 (executable)
@@ -271,6 +271,7 @@ sigaltstack
 siginfo
 signalfd4
 sigreturn
+sigsuspend
 socketcall
 splice
 stat
diff --git a/tests/sigsuspend.c b/tests/sigsuspend.c
new file mode 100644 (file)
index 0000000..a796380
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Check decoding of sigsuspend syscall.
+ *
+ * Copyright (c) 2017 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "tests.h"
+#include <asm/unistd.h>
+
+#ifdef __NR_sigsuspend
+
+# include <assert.h>
+# include <errno.h>
+# include <signal.h>
+# include <stdio.h>
+# include <stdint.h>
+# include <string.h>
+# include <unistd.h>
+
+# ifdef MIPS
+#  define SIGNAL_MASK_BY_REF 1
+# else
+#  define SIGNAL_MASK_BY_REF 0
+# endif
+
+static long
+k_sigsuspend(const kernel_ulong_t arg1,
+            const kernel_ulong_t arg2,
+            const kernel_ulong_t arg3)
+{
+       return syscall(__NR_sigsuspend, arg1, arg2, arg3);
+}
+
+static int signo;
+
+static void
+handler(int i)
+{
+       signo = i;
+}
+
+int
+main(void)
+{
+       union {
+               sigset_t libc_mask;
+               unsigned long old_mask;
+       } u;
+       unsigned long mask1, mask2;
+
+       sigemptyset(&u.libc_mask);
+       sigaddset(&u.libc_mask, SIGUSR1);
+       mask1 = u.old_mask;
+
+       sigemptyset(&u.libc_mask);
+       sigaddset(&u.libc_mask, SIGUSR2);
+       mask2 = u.old_mask;
+
+       sigaddset(&u.libc_mask, SIGUSR1);
+       if (sigprocmask(SIG_SETMASK, &u.libc_mask, NULL))
+               perror_msg_and_fail("sigprocmask");
+
+       const struct sigaction sa = { .sa_handler = handler };
+       if (sigaction(SIGUSR1, &sa, NULL) || sigaction(SIGUSR2, &sa, NULL))
+               perror_msg_and_fail("sigaction");
+
+       raise(SIGUSR1);
+       raise(SIGUSR2);
+
+#if SIGNAL_MASK_BY_REF
+       k_sigsuspend((uintptr_t) &mask1, 0xdeadbeef, (uintptr_t) &mask2);
+#else
+       k_sigsuspend(mask1, 0xdeadbeef, mask2);
+#endif
+       if (EINTR != errno)
+               perror_msg_and_skip("sigsuspend");
+
+       printf("sigsuspend([%s]) = ? ERESTARTNOHAND"
+              " (To be restarted if no handler)\n",
+              signo == SIGUSR2 ? "USR1" : "USR2");
+
+       puts("+++ exited with 0 +++");
+       return 0;
+}
+
+#else
+
+SKIP_MAIN_UNDEFINED("__NR_sigsuspend")
+
+#endif