<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 10 January 2015 at 01:05, Bryce Harrington <span dir="ltr"><<a href="mailto:bryce@osg.samsung.com" target="_blank">bryce@osg.samsung.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This fixes a regression in the testsuite since c3653f7f, where four of<br>
the timeout tests fail with "Timeouts suppressed" messages.<br>
<br>
The timeouts are being suppressed because the testsuite is erroneously<br>
detecting that a debugger is attached.  This detection mechanism<br>
(adopted from libinput) uses ptrace to test if there is a debugger<br>
parent process that can be attached.  Unfortunately, this is an<br>
unreliable test: Kernel security policies exist to restrict the scope of<br>
ptrace to prevent processes from snooping on one another.[1] This<br>
security policy is set as the default on Ubuntu, and potentially other<br>
Linux distributions.[2]<br>
<br>
The Yama documentation suggests, "For software that has defined<br>
application-specific relationships between a debugging process and its<br>
inferior (crash handlers, etc), prctl(PR_SET_PTRACER, pid, ...) can be<br>
used.  An inferior can declare which other process (and its descendents)<br>
are allowed to call PTRACE_ATTACH against it."  This prctl call has no<br>
effect if Yama LSM is not loaded.<br>
<br>
The child needs to be synchronized to the client to prevent a race<br>
condition where the child might try to operate before the parent has<br>
finished its prctl call.  This synchronization is done via pipes.<br>
<br>
This patch can be tested by running sanity-test with<br>
/proc/sys/kernel/yama/ptrace_scope set to 0 or 1; the test must pass for<br>
either value.<br>
<br>
1: <a href="http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=2d514487faf188938a4ee4fb3464eeecfbdcf8eb" target="_blank">http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=2d514487faf188938a4ee4fb3464eeecfbdcf8eb</a><br>
2: <a href="https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace_Protection" target="_blank">https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace_Protection</a><br>
<br>
Signed-off-by: Bryce Harrington <<a href="mailto:bryce@osg.samsung.com">bryce@osg.samsung.com</a>><br>
Reviewed-by: Marek Chalupa <<a href="mailto:mchqwerty@gmail.com">mchqwerty@gmail.com</a>><br>
---<br>
 tests/test-runner.c | 41 +++++++++++++++++++++++++++++++++++++++--<br>
 1 file changed, 39 insertions(+), 2 deletions(-)<br>
<br>
diff --git a/tests/test-runner.c b/tests/test-runner.c<br>
index 48e9a22..4750038 100644<br>
--- a/tests/test-runner.c<br>
+++ b/tests/test-runner.c<br>
@@ -34,6 +34,10 @@<br>
 #include <errno.h><br>
 #include <limits.h><br>
 #include <sys/ptrace.h><br>
+#include <sys/prctl.h><br>
+#ifndef PR_SET_PTRACER<br>
+# define PR_SET_PTRACER 0x59616d61<br>
+#endif<br>
<br>
 #include "test-runner.h"<br>
<br>
@@ -249,16 +253,30 @@ stderr_reset_color(void)<br>
<br>
 /* this function is taken from libinput/test/litest.c<br>
  * (rev 028513a0a723e97941c39)<br>
+ *<br>
+ * Returns: 1 if a debugger is confirmed present; 0 if no debugger is<br>
+ * present or if it can't be determined.<br>
  */<br>
 static int<br>
 is_debugger_attached(void)<br>
 {<br>
        int status;<br>
        int rc;<br>
-       pid_t pid = fork();<br>
+       pid_t pid;<br>
+       int pipefd[2];<br>
+<br>
+       if (pipe(pipefd) == -1) {<br>
+               perror("pipe");<br>
+               return 0;<br>
+       }<br>
<br>
-       if (pid == -1)<br>
+       pid = fork();<br>
+       if (pid == -1) {<br>
+               perror("fork");<br>
+               close(pipefd[0]);<br>
+               close(pipefd[1]);<br>
                return 0;<br>
+       }<br>
<br>
        if (pid == 0) {<br>
                pid_t ppid = getppid();<br>
@@ -272,6 +290,25 @@ is_debugger_attached(void)<br>
                }<br>
                _exit(rc);<br>
        } else {<br>
+               close(pipefd[0]);<br>
+<br>
+               /* Enable child to ptrace the parent process */<br>
+               rc = prctl(PR_SET_PTRACER, pid);<br>
+               if (rc != 0 && rc != EINVAL) {<br>
+                       /* An error prevents us from telling if a debugger is attached.<br>
+                        * Instead of propagating the error, assume no debugger present.<br>
+                        * But note the error to the log as a clue for troubleshooting.<br>
+                        */<br>
+                       perror("prctl");<br>
+                       close(pipefd[1]);<br>
+                       return 0;<br></blockquote><div><br></div><div>Here we're creating a zombie, aren't we?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+               }<br>
+<br>
+               /* Signal to client that parent is ready.  No need to write<br>
+                * anything to the child; the closure of the pipe will be<br>
+                * sufficient to signal we're ready. */<br>
+               close(pipefd[1]);<br>
+<br>
                waitpid(pid, &status, 0);<br>
                rc = WEXITSTATUS(status);<br>
        }<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
_______________________________________________<br>
wayland-devel mailing list<br>
<a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/wayland-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/wayland-devel</a><br></font></span></blockquote><div><br><br></div><div>Thanks for the added comments :)<br><br></div><div>Marek <br></div></div><br></div></div>