]> granicus.if.org Git - strace/commitdiff
Fix filtering of <unavailable> syscalls
authorDmitry V. Levin <ldv@altlinux.org>
Mon, 29 Jun 2015 11:57:44 +0000 (11:57 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Tue, 30 Jun 2015 17:28:02 +0000 (17:28 +0000)
* syscall.c (trace_syscall_exiting): Skip filtered syscalls also in case
of get_regs or get_syscall_result failure.
* tests/filter-unavailable.c: New file.
* tests/filter-unavailable.expected: Likewise.
* tests/filter-unavailable.test: New test.
* tests/Makefile.am (check_PROGRAMS): Add filter-unavailable.
(filter_unavailable_LDFLAGS): Add -pthread.
(TESTS): Add filter-unavailable.test.
(EXTRA_DIST): Add filter-unavailable.expected.
* tests/.gitignore: Add filter-unavailable.

Reported-by: Bryan Matsuo <bryan.matsuo@gmail.com>
syscall.c
tests/.gitignore
tests/Makefile.am
tests/filter-unavailable.c [new file with mode: 0644]
tests/filter-unavailable.expected [new file with mode: 0644]
tests/filter-unavailable.test [new file with mode: 0755]

index 0d26b45c3f43a68ccc58c5e5dcc7af649506fe73..0ab424c1a46179bd4e9248a98b1d81f113591aec 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -873,10 +873,8 @@ trace_syscall_exiting(struct tcb *tcp)
        update_personality(tcp, tcp->currpers);
 #endif
        res = (get_regs_error ? -1 : get_syscall_result(tcp));
-       if (res == 1) {
-               if (filtered(tcp) || hide_log_until_execve)
-                       goto ret;
-       }
+       if (filtered(tcp) || hide_log_until_execve)
+               goto ret;
 
        if (cflag) {
                count_syscall(tcp, &tv);
index c3eada90b8b72c6c03a172214e8967bd8c4995db..fe19dd8953872e29db8bd73102be6394bf72a720 100644 (file)
@@ -1,5 +1,6 @@
 caps
 fanotify_mark
+filter-unavailable
 getrandom
 inet-accept-connect-send-recv
 ioctl
index f1e882050744c0327112a994fc6a7fe51b48292d..32e6e52e97017e916f0fbd574623f15b7eaa119d 100644 (file)
@@ -11,6 +11,7 @@ AM_CPPFLAGS = -I$(top_builddir)/$(OS)/$(ARCH) \
 check_PROGRAMS = \
        caps \
        fanotify_mark \
+       filter-unavailable \
        getrandom \
        inet-accept-connect-send-recv \
        ioctl \
@@ -44,6 +45,7 @@ check_PROGRAMS = \
        umovestr2 \
        unix-pair-send-recv
 
+filter_unavailable_LDFLAGS = -pthread
 mmap64_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
 pc_LDADD = $(dl_LIBS)
 stat_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
@@ -59,6 +61,7 @@ TESTS = \
        caps.test \
        dumpio.test \
        fanotify_mark.test \
+       filter-unavailable.test \
        getdents.test \
        getrandom.test \
        ioctl.test \
@@ -107,6 +110,7 @@ EXTRA_DIST = init.sh run.sh match.awk \
             caps.awk \
             dumpio.expected \
             fanotify_mark.expected \
+            filter-unavailable.expected \
             getdents.awk \
             getdents.out \
             getrandom.awk \
diff --git a/tests/filter-unavailable.c b/tests/filter-unavailable.c
new file mode 100644 (file)
index 0000000..6f865e6
--- /dev/null
@@ -0,0 +1,54 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/wait.h>
+
+#define P 16
+#define T 7
+
+static void *
+thread(void *arg)
+{
+       assert(write(1, "", 1) == 1);
+       pause();
+       return arg;
+}
+
+static int
+process(void)
+{
+       int i;
+       int fds[2];
+       pthread_t t;
+       struct timespec ts = { .tv_nsec = 10000000 };
+
+       (void) close(0);
+       (void) close(1);
+       assert(pipe(fds) == 0 && fds[0] == 0 && fds[1] == 1);
+
+       for (i = 0; i < T; ++i)
+               assert(pthread_create(&t, NULL, thread, NULL) == 0);
+       for (i = 0; i < T; ++i)
+               assert(read(0, fds, 1) == 1);
+
+       (void) nanosleep(&ts, 0);
+       return 0;
+}
+
+int
+main(void)
+{
+       int i, s;
+       pid_t p;
+
+       for (i = 0; i < P; ++i) {
+               assert((p = fork()) >= 0);
+               if (p == 0)
+                       return process();
+               assert(waitpid(p, &s, 0) == p && WIFEXITED(s));
+               if (WEXITSTATUS(s))
+                       return WEXITSTATUS(s);
+       }
+       return 0;
+}
diff --git a/tests/filter-unavailable.expected b/tests/filter-unavailable.expected
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/filter-unavailable.test b/tests/filter-unavailable.test
new file mode 100755 (executable)
index 0000000..15a9ad1
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# check that <unavailable> syscalls are filtered properly
+
+. "${srcdir=.}/init.sh"
+
+run_prog
+run_strace -qq -f -echdir -esignal=none $args
+match_diff
+
+exit 0