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) {
/*