Messages in this thread Patch in this message | | | Subject | [PATCH] subterfugue-ptrace patch #1 (was Re: vfork) | From | Mike Coleman <> | Date | 07 Feb 2000 00:32:26 -0600 |
| |
Linus Torvalds <torvalds@transmeta.com> writes: > On 24 Dec 1999, Mike Coleman wrote: > > I didn't see anyone comment, so I will. I'd like to see this change go in for > > 2.4. Without it, CLONE_PTRACE is not very useful. > > If you can show that it works, and that you can strace a vfork() and over > a clone(), then send me the patch and I'll apply it in a jiffy. I'd like > to hear that it actually _does_ work in real life, and I'd be even happier > if I'd see a working "strace" as a result. Ok?
Ok. SUBTERFUGUE, which I just posted an announcment for, demonstrates process following over vfork and clone. The patch it uses is pretty similar to what was being discussed here in December, but adds a couple of things. Here is a description of the patch (from http://subterfugue.org/patches.html). The patch itself, against 2.3.42, is appended below.
(Sorry, I don't have a working strace, but I believe the same techniques used in SUBTERFUGUE will also work for strace. I'll happily render any needed assistance to make that happen.)
--Mike
------------------------------------------------------------------------------
Here are the changes included in the patch. Most are fairly innocuous extensions, but the first two might break some things.
1. The exit_code reported during PTRACE_SYSCALL stops now has its high bit (0x80) set, to distinguish it from signal stops. Unfortunately, this breaks strace, and probably any other program that uses PTRACE_SYSCALL (see ptrace(2)). The fix is pretty simple--just mask off the high bit (or adapt the program to make use of the extra information). A patch is available that does this for strace. (It doesn't appear that gdb is affected.) 2. When a new child is created with clone and CLONE_PARENT is set, and the child is being traced (e.g., it's done a PTRACE_TRACEME), it will now report to the first process' parent. This is correct behavior, but it opens up what some would consider a security hole--a malicious child might unexpectedly invoke PTRACE_TRACEME, causing it to report to a waiting parent process that never expected to hear from it. This was discussed on linux-kernel for a bit; there didn't seem to be a consensus about whether this was even a hole at all. 3. A new wait flag __WALL is implemented, to allow clone and non-clone children to be waited for simultaneously. 4. A new ptrace command PTRACE_GETPPID is implemented, which lets a tracing process discover the original parent of a traced child. This information is otherwise unavailable. 5. Exits of the system calls fork, vfork, and clone are now reported.
------------------------------------------------------------------------------
--- linux-2.3.42/kernel/exit.c.orig Sat Feb 5 02:08:19 2000 +++ linux-2.3.42/kernel/exit.c Sat Feb 5 02:09:32 2000 @@ -445,7 +445,7 @@ DECLARE_WAITQUEUE(wait, current); struct task_struct *p; - if (options & ~(WNOHANG|WUNTRACED|__WCLONE)) + if (options & ~(WNOHANG|WUNTRACED|__WCLONE|__WALL)) return -EINVAL; add_wait_queue(¤t->wait_chldexit,&wait); @@ -464,8 +464,13 @@ if (p->pgrp != -pid) continue; } - /* wait for cloned processes iff the __WCLONE flag is set */ - if ((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0)) + /* Wait for all children (clone and not) if __WALL is set; + * otherwise, wait for clone children *only* if __WCLONE is + * set; otherwise, wait for non-clone children *only*. (Note: + * A "clone" child here is one that reports to its parent + * using a signal other than SIGCHLD.) */ + if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0)) + && !(options & __WALL)) continue; flag = 1; switch (p->state) { --- linux-2.3.42/kernel/fork.c.orig Mon Dec 13 17:39:24 1999 +++ linux-2.3.42/kernel/fork.c Sat Feb 5 02:09:32 2000 @@ -646,8 +646,11 @@ p->run_list.next = NULL; p->run_list.prev = NULL; - if ((clone_flags & CLONE_VFORK) || !(clone_flags & CLONE_PARENT)) - p->p_pptr = p->p_opptr = current; + if ((clone_flags & CLONE_VFORK) || !(clone_flags & CLONE_PARENT)) { + p->p_opptr = current; + if (!(current->flags & PF_PTRACED)) + p->p_pptr = current; + } p->p_cptr = NULL; init_waitqueue_head(&p->wait_chldexit); p->vfork_sem = NULL; --- linux-2.3.42/include/linux/wait.h.orig Mon Jan 10 20:29:12 2000 +++ linux-2.3.42/include/linux/wait.h Sat Feb 5 02:09:32 2000 @@ -4,6 +4,7 @@ #define WNOHANG 0x00000001 #define WUNTRACED 0x00000002 +#define __WALL 0x40000000 #define __WCLONE 0x80000000 #ifdef __KERNEL__ --- linux-2.3.42/include/asm-i386/ptrace.h.orig Tue Dec 9 19:57:09 1997 +++ linux-2.3.42/include/asm-i386/ptrace.h Sat Feb 5 02:09:32 2000 @@ -47,6 +47,8 @@ #define PTRACE_GETFPREGS 14 #define PTRACE_SETFPREGS 15 +#define PTRACE_GETPPID 20 + #ifdef __KERNEL__ #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) #define instruction_pointer(regs) ((regs)->eip) --- linux-2.3.42/arch/i386/kernel/entry.S.orig Sat Feb 5 02:07:42 2000 +++ linux-2.3.42/arch/i386/kernel/entry.S Sat Feb 5 02:09:32 2000 @@ -180,6 +180,8 @@ call SYMBOL_NAME(schedule_tail) addl $4, %esp GET_CURRENT(%ebx) + testb $0x20,flags(%ebx) # PF_TRACESYS + jne tracesys_exit # need to set eax first?? jmp ret_from_sys_call /* --- linux-2.3.42/arch/i386/kernel/ptrace.c.orig Sat Feb 5 02:07:22 2000 +++ linux-2.3.42/arch/i386/kernel/ptrace.c Sat Feb 5 02:11:27 2000 @@ -431,6 +431,12 @@ break; } + case PTRACE_GETPPID: { /* Who's your daddy? */ + unsigned long ppid = child->p_opptr->pid; + ret = put_user(ppid, (unsigned long *) data); + break; + } + default: ret = -EIO; break; @@ -445,7 +451,7 @@ if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS)) return; - current->exit_code = SIGTRAP; + current->exit_code = SIGTRAP | 0x80; current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule();
-- Any sufficiently adverse technology is indistinguishable from Microsoft.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |