strace -f (v4.7) randomly failing on grsecurity and Ubuntu kernels

Dmitry V. Levin ldv at altlinux.org
Wed May 9 23:12:01 UTC 2012


Hi,

On Tue, May 08, 2012 at 07:43:28PM -0400, Brad Spengler wrote:
> Hi guys,
> 
> I'm writing to report this before the recent release sees more 
> widespread use.  I've already had one report from a user of strace v4.7 
> failing on a grsecurity kernel when run with the -f argument.  Strace 
> (due to what IMO is a bug) is randomly conflicting with a feature of 
> grsecurity that prevents ptracing processes other than one's decendents.  
> Since Ubuntu's kernel carries the same logic/algorithm as grsecurity 
> through the Yama module, strace will likewise fail on their kernels.
> 
> I've investigated the problem a bit.  The failing code (in strace.c) is:
>                if (tracee_pid != pid) {
>                         found_grandchild = tracee_pid;
>                         if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
>                                 kill_save_errno(tracee_pid, SIGKILL);
>                                 kill_save_errno(pid, SIGKILL);
>                                 perror_msg_and_die("PTRACE_CONT doesn't work");
>                         }
>                         continue;
>                 }
> 
> This happens because of the raciness of the following code (in strace.c):
>         if (pid == 0) {
>                 pid = getpid();
>                 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
>                         perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
>                                            __func__);
>                 kill_save_errno(pid, SIGSTOP);
>                 if (fork() < 0)
>                         perror_msg_and_die("fork");
>                 _exit(0);
>         }
> 
> Sometimes the child exits before the PTRACE_CONT is issued against the 
> grandchild, while other times the child exits after.  If the child exits 
> after, there are no issues, as the grandchild keeps its descendent 
> relation to the ptracing grandparent.  If the child exits before, 
> however, it gets reparented to init, breaking the ability to walk back 
> through the ancestors of the grandchild to reach the (previous) 
> grandparent.  Because of this, grsecurity (and Ubuntu) will deny the 
> ptrace to the grandchild.

The code in strace.c you are talking about is
test_ptrace_setoptions_followfork function, which is a runtime test for
kernel features.  There is no problem to add a wait call in this test to
make grsec kernels happy, but the problem may arise in real code anyway.
If grsec disallows PTRACE_CONT'ing already attached processes just because
they were re-parented to init, then grsec changes ptrace semantics and
strace is hardly expected to work properly in such circumstances.

I wonder is there a rationale for such a restriction?  What kind of
extra security risk could be caused by allowing ptrace of already
attached processes?


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20120510/3cb1112a/attachment.bin>


More information about the Strace-devel mailing list