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

Reply via email to