Hello, guys. Jiangui Liu told right thing - next code fragment creates a SIGKILL immune allproc entry: --begin------------------------------------------------------ #include <sys/types.h> #include <sys/ptrace.h> #include <unistd.h> #include <signal.h> int main() { ptrace(PT_TRACE_ME, 0, 0, 0); puts("never kill me"); execve("/bin/sh", NULL, NULL); } --end------------------------------------------------------- Ok, lets see.. > ./im [1]+ Stopped ./im > ps -O flags -p 473 PID F TT STAT TIME COMMAND 473 5806 v1 TX 0:00.00 (sh) > We have: flags = 0x05806 = P_CONTROLT | P_INMEM | P_TRACED | P_WAITED | P_EXEC state = SSTOP In such state SIGKILL never will be delivered (+1000 kern_sig.c) Attached is an *attempt* to fix the problem - please expertise and correct me (patch made against 4.1.1R) Another problem(?) Jiangui found considers PT_DETACH ptrace(2) call. While i'm attaching to a running process via PT_ATTACH, PT_DETACH works well as expected. If i instead use PT_TRACE_ME -> execve -> PT_DETACH, child always got killed by SIGTRAP. I'm not sure it's a bug - needs play a bit more with gdb... .. Attached is a simple program i used for tests. Note that Jiangyi Liu reported same effects on 4.3-S. Sorry Jiangyi Liu, I wrong understood you yesterday - needs more more more sleeping :~) Best Regards. > On 30 May 2001, Jiangyi Liu wrote: > > > Hi all, > > > > The ptrace(2) man page is probably outdated. I used PT_DETACH in the > > following code, but it didn't run ./test. I also tried to use > > ptrace(PT_DETACH, pid, (caddr_t)1, 0) to detach, but it failed too. > > > > BTW, if I omit wait(0) and ptrace(PT_DETACH, ...) in the code, after > > it runs there is a process sticking to the system. Even kill -9 can't > > kill it. > > > > $ ps aux | grep jyliu > > ... > > jyliu 423 0.0 0.1 216 100 p2 TX 7:41AM 0:00.00 (test) > > ... > > $ kill -9 423 > > $ ps aux | grep jyliu > > ... > > jyliu 423 0.0 0.1 216 100 p2 TX 7:41AM 0:00.00 (test) > > ... > > > > So it's still there. Quite funny. Any clue? > > > > Jiangyi > > > > ---code begins here > > #include <unistd.h> > > #include <sys/types.h> > > #include <sys/ptrace.h> > > > > int main() > > { > > pid_t pid; > > > > if(!(pid=fork())) { > > /* child */ > > ptrace(PT_TRACE_ME, 0, 0, 0); > > puts("child speaking"); > > execve("./test", NULL, NULL); > > } else { > > wait(0); > > ptrace(PT_DETACH, pid, 0, 0); > > exit(0); > > } > > } > > ---code ends here
#include <unistd.h> #include <sys/types.h> #include <sys/ptrace.h> #include <sys/wait.h> #include <signal.h> int main(int ac, char **av) { pid_t pid=0; int s, i=0; if ( ac > 1) { pid = atoi( av[1] ); if ( 0 > ptrace(PT_ATTACH,pid,0,0) ) { printf("can't attach to %d\n",pid); exit(0); } } else pid = fork(); if ( !pid ) { /* child - unreached if attaching mode */ /* sleep a bit to make parent able issue wait */ usleep(100000); ptrace(PT_TRACE_ME, 0, 0, 0); puts("-- child speaking"); execve("/bin/df", NULL, NULL); } else /* wait for child/inferior */ while ( 0 < waitpid(pid,&s,0) ) { if ( WIFSIGNALED(s) ) { printf("-- %d exited %s\n", pid, WCOREDUMP(s) ? "core dumped": "" ); exit(0); } if ( WIFEXITED(s) ) { printf("-- %d exited with status %d\n", \ pid, WEXITSTATUS(s) ); exit(0); } if ( WIFSTOPPED(s) ) { printf("-- %d stopped on signal %d\n", \ pid, WSTOPSIG(s) ); if( !i ) { printf("-- PT_CONTINUE it..\n"); ptrace(PT_CONTINUE, pid, (caddr_t)1, 0); } else { printf("-- PT_DETACH it..\n"); ptrace(PT_DETACH, pid, (caddr_t)1, SIGCONT); } i ++; } else printf("/* not reached */\n"); } }
*** /usr/src/sys/kern/kern_sig.c.old Thu May 31 12:25:52 2001 --- /usr/src/sys/kern/kern_sig.c Thu May 31 12:19:19 2001 *************** *** 1120,1136 **** case SSTOP: /* * If traced process is already stopped, * then no further action is necessary. */ if (p->p_flag & P_TRACED) goto out; - /* - * Kill signal always sets processes running. - */ - if (sig == SIGKILL) - goto runfast; if (prop & SA_CONT) { /* --- 1120,1137 ---- case SSTOP: /* + * Kill signal always sets processes running. + */ + if (sig == SIGKILL) + goto runfast; + + /* * If traced process is already stopped, * then no further action is necessary. */ if (p->p_flag & P_TRACED) goto out; if (prop & SA_CONT) { /*