<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 9 January 2015 at 23:11, Kees Cook <span dir="ltr"><<a href="mailto:kees@outflux.net" target="_blank">kees@outflux.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Bryce,<br>
<span class=""><br>
On Fri, Jan 09, 2015 at 01:24:39PM -0800, Bryce Harrington wrote:<br>
> On Fri, Jan 09, 2015 at 11:33:57AM +0100, Marek Chalupa wrote:<br>
> > Yeah and one more thing:<br>
><br>
> Btw, any reason this is offlist?<br>
><br></span></blockquote><div><br></div><div>No, just clicked on the wrong button (reply instead of reply to all), sorry. I just resend it.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> > PR_SET_PTRACER is since Linux 3.4. What happens with older kernels or with<br>
> > Yama disabled?<br>
><br>
> If I understand how the prctl handlers work, if Yama is not loaded then<br>
> PR_SET_PTRACER will just be ignored if it is set. I'll cc author to be<br>
> sure.<br>
<br>
</span>The prctl will return EINVAL if Yama is not loaded. (i.e. just ignore the<br>
prctl).<br>
<span class=""><br>
><br>
> Good point on pre-3.4 kernels. I'll #ifdef around it.<br>
<br>
</span>I recommend:<br>
<br>
#include <sys/prctl.h><br>
#ifndef PR_SET_PTRACER<br>
# define PR_SET_PTRACER 0x59616d61<br>
#endif<br>
<span class=""><br>
<br>
><br>
> > I suppose that prctl call fails but since the return code is not used, it<br>
> > is ignored and everything continues like before without prctl, right?<br>
><br>
> >From my understanding of yama_lsm.c, there wouldn't be an error code in<br>
> the case that Yama was not enabled (i.e. rc = 0). With Yama enabled, it<br>
> looks like prctl will error if it can't get the tracer task, or in out<br>
> of memory conditions.<br>
><br>
> I suppose if the prctl call fails, we could bail out at that point. We<br>
> wouldn't know whether a debugger is attached or not though, so perhaps<br>
> in that case is_debugger_attached() should return 0? Looks like we<br>
> return 0 in other error cases.<br>
<br>
</span>If the prctl fails, there's no Yama, so no need for the prctl, so it can be<br>
ignored.<br>
<div><div class="h5"><br>
><br>
> Thanks for the review; will re-roll the patchset.<br>
><br>
> Bryce<br>
><br>
> > Cheers,<br>
> > Marek<br>
> ><br>
> > On 9 January 2015 at 11:26, Marek Chalupa <<a href="mailto:mchqwerty@gmail.com">mchqwerty@gmail.com</a>> wrote:<br>
> ><br>
> > ><br>
> > ><br>
> > > On 7 January 2015 at 21:34, Bryce Harrington <<a href="mailto:bryce@osg.samsung.com">bryce@osg.samsung.com</a>><br>
> > > wrote:<br>
> > ><br>
> > >> 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."<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>
> > >> 1:<br>
> > >> <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:<br>
> > >> <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>
> > >> ---<br>
> > >> tests/test-runner.c | 35 ++++++++++++++++++++++++++++++++---<br>
> > >> 1 file changed, 32 insertions(+), 3 deletions(-)<br>
> > >><br>
> > >> diff --git a/tests/test-runner.c b/tests/test-runner.c<br>
> > >> index b813b69..11d064e 100644<br>
> > >> --- a/tests/test-runner.c<br>
> > >> +++ b/tests/test-runner.c<br>
> > >> @@ -34,6 +34,7 @@<br>
> > >> #include <errno.h><br>
> > >> #include <limits.h><br>
> > >> #include <sys/ptrace.h><br>
> > >> +#include <linux/prctl.h><br>
> > >><br>
> > ><br>
> > > Better use <sys/prctl.h>. prctl() is declared in sys/prctl.h.<br>
> > > linux/prctl.h only defines the values for arguments (and is included by<br>
> > > sys/prctl.h)<br>
> > ><br>
> > ><br>
> > >><br>
> > >> #include "test-runner.h"<br>
> > >><br>
> > >> @@ -255,13 +256,33 @@ 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 (pid == -1)<br>
> > >> + if (pipe(pipefd) == -1) {<br>
> > >> + perror("pipe");<br>
> > >> return 0;<br>
> > >> + }<br>
> > >> +<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>
> > >> + char buf;<br>
> > >> + pid_t ppid;<br>
> > >> +<br>
> > >> + /* Wait until parent is ready */<br>
> > >> + close(pipefd[1]); /* Close unused write end */<br>
> > >> + while (read(pipefd[0], &buf, 1) > 0);<br>
> > >><br>
> > > + close(pipefd[0]);<br>
> > >> +<br>
> > >> + /* Attempt to ptrace the parent */<br>
> > >> + ppid = getppid();<br>
> > >> rc = ptrace(PTRACE_ATTACH, ppid, NULL, NULL);<br>
> > >> if (rc == 0) {<br>
> > >> waitpid(ppid, NULL, 0);<br>
> > >> @@ -273,6 +294,14 @@ is_debugger_attached(void)<br>
> > >> }<br>
> > >> _exit(rc);<br>
> > >> } else {<br>
> > >> + close(pipefd[0]);<br>
> > >> +<br>
> > >> + /* Enable child to ptrace the parent process */<br>
> > >> + prctl(PR_SET_PTRACER, pid);<br>
> > >> +<br>
> > >> + /* Signal to client that parent is ready */<br>
> > >> + close(pipefd[1]);<br>
> > >><br>
> > ><br>
> > > Maybe this would deserve better description, because signaling something<br>
> > > by closing the pipe is not clear IMO.<br>
<br>
</div></div>Since the pipe is blocking, it should be sufficient. I don't think it's<br>
needed to actually perform a write. The read will block until the close,<br>
and on close, the read will return 0, which is what it's waiting for<br>
(or for an error).<br>
<br></blockquote><div>Yep, I understand how it works, but I had to go thourgh the code back and forth to make myself sure that I get it. Therefore I suggested to add a comment that explains how the signaling works :)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
-Kees<br>
<div class=""><div class="h5"><br>
> > ><br>
> > ><br>
> > ><br>
> > >> waitpid(pid, &status, 0);<br>
> > >> rc = WEXITSTATUS(status);<br>
> > >> }<br>
> > >> --<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>
> > >><br>
> > ><br>
> > ><br>
> > > For both patches:<br>
> > ><br>
> > > Reviewed-by: Marek Chalupa <<a href="mailto:mchqwerty@gmail.com">mchqwerty@gmail.com</a>><br>
> > ><br>
> > ><br>
<br>
</div></div><span class=""><font color="#888888">--<br>
Kees Cook @<a href="http://outflux.net" target="_blank">outflux.net</a><br></font></span></blockquote><div><br></div><div>Thanks,<br></div><div>Marek <br></div></div><br></div></div>