@@ -2561,60 +2561,63 @@ static bool verify_ptrace_options(RecordTask* t,
25612561 return true ;
25622562}
25632563
2564- static bool check_ptracer_compatible (RecordTask* tracer, RecordTask* tracee) {
2564+ static void check_ptracer_compatible (RecordTask* tracer, RecordTask* tracee) {
25652565 // Don't allow a 32-bit process to trace a 64-bit process. That doesn't
25662566 // make much sense (manipulating registers gets crazy), and would be hard to
25672567 // support.
2568- if (tracee->emulated_ptracer || tracee->tgid () == tracer->tgid () ||
2569- (tracer->arch () == x86 && tracee->arch () == x86_64)) {
2570- return false ;
2571- }
2572- return true ;
2568+ ASSERT (tracer, !(tracer->arch () == x86 && tracee->arch () == x86_64));
25732569}
25742570
2575- static RecordTask* get_ptrace_partner (RecordTask* t, pid_t pid) {
2571+ static RecordTask* prepare_ptrace_attach (RecordTask* tracer, pid_t attach_to_tid,
2572+ TaskSyscallState& syscall_state) {
25762573 // To simplify things, require that a ptracer be in the same pid
25772574 // namespace as rr itself. I.e., tracee tasks sandboxed in a pid
25782575 // namespace can't use ptrace. This is normally a requirement of
25792576 // sandboxes anyway.
25802577 // This could be supported, but would require some work to translate
25812578 // rr's pids to/from the ptracer's pid namespace.
2582- ASSERT (t , is_same_namespace (" pid" , t ->tid , getpid ()));
2583- RecordTask* partner = t ->session ().find_task (pid );
2584- if (!partner ) {
2585- // XXX This prevents a tracee from attaching to a process which isn't
2579+ ASSERT (tracer , is_same_namespace (" pid" , tracer ->tid , getpid ()));
2580+ RecordTask* tracee = tracer ->session ().find_task (attach_to_tid );
2581+ if (!tracee ) {
2582+ // XXX This prevents a tracer from attaching to a process which isn't
25862583 // under rr's control. We could support this but it would complicate
25872584 // things.
2588- return nullptr ;
2589- }
2590- return partner;
2591- }
2592-
2593- static RecordTask* prepare_ptrace_attach (RecordTask* t, pid_t pid,
2594- TaskSyscallState& syscall_state) {
2595- RecordTask* tracee = get_ptrace_partner (t, pid);
2596- if (!tracee) {
25972585 syscall_state.emulate_result (-ESRCH);
25982586 return nullptr ;
25992587 }
2600- if (! check_ptracer_compatible (t, tracee)) {
2588+ if (tracee-> emulated_ptracer || tracee-> tgid () == tracer-> tgid ( )) {
26012589 syscall_state.emulate_result (-EPERM);
26022590 return nullptr ;
26032591 }
2592+ check_ptracer_compatible (tracer, tracee);
26042593 return tracee;
26052594}
26062595
2607- static RecordTask* prepare_ptrace_traceme (RecordTask* t ,
2596+ static RecordTask* prepare_ptrace_traceme (RecordTask* tracee ,
26082597 TaskSyscallState& syscall_state) {
2609- RecordTask* tracer = get_ptrace_partner (t, t->get_parent_pid ());
2598+ RecordTask* tracer = nullptr ;
2599+ pid_t parent_pid = tracee->get_parent_pid ();
2600+ if (tracee->creator_tid != 0 ) {
2601+ RecordTask* creator = tracee->session ().find_task (tracee->creator_tid );
2602+ if (creator && creator->thread_group ()->tgid == parent_pid) {
2603+ tracer = creator;
2604+ }
2605+ }
26102606 if (!tracer) {
2611- syscall_state.emulate_result (-ESRCH);
2612- return nullptr ;
2607+ ThreadGroup* tg = tracee->session ().find_thread_group (parent_pid);
2608+ if (tg) {
2609+ tracer = static_cast <RecordTask*>(tg->first_running_task ());
2610+ }
2611+ if (!tracer) {
2612+ syscall_state.emulate_result (0 );
2613+ return nullptr ;
2614+ }
26132615 }
2614- if (! check_ptracer_compatible (tracer, t )) {
2616+ if (tracee-> emulated_ptracer || tracee-> tgid () == tracer-> tgid ( )) {
26152617 syscall_state.emulate_result (-EPERM);
26162618 return nullptr ;
26172619 }
2620+ check_ptracer_compatible (tracer, tracee);
26182621 return tracer;
26192622}
26202623
0 commit comments