From 12451e6b06f4a552acdfaac96637aedd69448920 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Sun, 5 Jul 2009 22:48:18 +0000 Subject: [PATCH] Miscellaneous PM fixes: o Don't call vm_willexit() more than once upon normal process exit o Correct two cases of indenting of the no-discussion-possible kind o Perform slightly stricter ptrace(2) checks: - process calling ptrace must be target process's parent - process must call wait/waitpid before using ptrace on stopped child - no ptrace on zombies o Allow user processes to use ptrace(T_STOP) to stop an active child --- servers/pm/forkexit.c | 4 ++-- servers/pm/signal.c | 12 ++++-------- servers/pm/trace.c | 30 +++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/servers/pm/forkexit.c b/servers/pm/forkexit.c index 4bfe4ad30..eae82993d 100644 --- a/servers/pm/forkexit.c +++ b/servers/pm/forkexit.c @@ -226,8 +226,8 @@ int for_trace; * such as copying to/ from the exiting process, before it is gone. */ sys_nice(proc_nr_e, PRIO_STOP); /* stop the process */ - if(vm_willexit(proc_nr_e) != OK) { - panic(__FILE__, "pm_exit: vm_willexit failed", proc_nr_e); + if((r=vm_willexit(proc_nr_e)) != OK) { + panic(__FILE__, "pm_exit: vm_willexit failed", r); } if (proc_nr_e == INIT_PROC_NR) diff --git a/servers/pm/signal.c b/servers/pm/signal.c index 23c2cb4d1..f80dc0ba4 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -260,7 +260,7 @@ sigset_t sig_map; if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) { printf("PM: handle_ksig: %d?? zombie / not in use\n", proc_nr_e); return; -} + } proc_id = rmp->mp_pid; mp = &mproc[0]; /* pretend signals are from PM */ mp->mp_procgrp = rmp->mp_procgrp; /* get process group right */ @@ -517,13 +517,6 @@ doterminate: /* Signal should not or cannot be caught. Take default action. */ if (sigismember(&ign_sset, signo)) { return; -} - - /* This process will exit, with or without dumping core. - * Announce this fact to VM. - */ - if((s=vm_willexit(rmp->mp_endpoint)) != OK) { - panic(__FILE__,"sig_proc: vm_willexit failed", s); } rmp->mp_sigstatus = (char) signo; @@ -745,6 +738,9 @@ register struct mproc *rmp; /* whose core is to be dumped */ * such as copying to/ from the exiting process, before it is gone. */ sys_nice(proc_nr_e, PRIO_STOP); /* stop the process */ + if((r=vm_willexit(proc_nr_e)) != OK) { + panic(__FILE__,"dump_core: vm_willexit failed", r); + } if(proc_nr_e != FS_PROC_NR) /* if it is not FS that is exiting.. */ { diff --git a/servers/pm/trace.c b/servers/pm/trace.c index 943169602..ec7b35a9a 100644 --- a/servers/pm/trace.c +++ b/servers/pm/trace.c @@ -87,12 +87,29 @@ PUBLIC int do_trace() return(OK); } - if ((child=find_proc(m_in.pid))==NIL_MPROC || !(child->mp_flags & STOPPED)) { - return(ESRCH); - } /* all the other calls are made by the parent fork of the debugger to * control execution of the child */ + if ((child=find_proc(m_in.pid))==NIL_MPROC || child->mp_parent != who_p) + return(ESRCH); + + if (m_in.request == T_STOP) { + if ((r = sys_trace(T_STOP, child->mp_endpoint, 0L, (long *) 0)) != OK) + return(r); + + child->mp_flags |= STOPPED; + child->mp_sigstatus = 0; + + mp->mp_reply.reply_trace = 0; + return(OK); + } + + /* for calls other than T_STOP, the child must be stopped and the parent + * must have waited for it + */ + if (!(child->mp_flags & STOPPED) || child->mp_sigstatus > 0) + return(ESRCH); + switch (m_in.request) { case T_EXIT: /* exit */ pm_exit(child, (int) m_in.data, TRUE /*for_trace*/); @@ -127,7 +144,10 @@ pid_t lpid; register struct mproc *rmp; for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) - if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp); + if ((rmp->mp_flags & (IN_USE | ZOMBIE)) == IN_USE && + rmp->mp_pid == lpid) { + return(rmp); + } return(NIL_MPROC); } @@ -143,7 +163,7 @@ int signo; register struct mproc *rpmp = mproc + rmp->mp_parent; int r; - r= sys_trace(-1, rmp->mp_endpoint, 0L, (long *) 0); + r= sys_trace(T_STOP, rmp->mp_endpoint, 0L, (long *) 0); if (r != OK) panic("pm", "sys_trace failed", r); rmp->mp_flags |= STOPPED;