Changeset 2450 for neercs


Ignore:
Timestamp:
Jun 18, 2008, 10:29:34 PM (12 years ago)
Author:
Pascal Terjan
Message:
  • Detach properly the process from the previous tty
  • Use major to decide if a device is a pty slave
File:
1 edited

Legend:

Unmodified
Added
Removed
  • neercs/trunk/src/grab.c

    r2444 r2450  
    1414#include <sys/user.h>
    1515#include <sys/wait.h>
     16
     17#include <linux/kdev_t.h>
     18#include <linux/major.h>
    1619
    1720#include "neercs.h"
     
    6164    }
    6265
    63     regs->esp -= 4;
     66    regs->esp = oregs.esp-4;
    6467
    6568    oinst = ptrace(PTRACE_PEEKTEXT, pid, regs->esp, 0);
     
    8689    waitpid(pid, NULL, 0);
    8790
     91    if(ptrace(PTRACE_GETREGS, pid, NULL, regs) < 0)
     92    {
     93        return errno;
     94    }
     95
    8896    if(ptrace(PTRACE_SETREGS, pid, NULL, &oregs) < 0)
    8997    {
     98        fprintf(stderr, "PTRACE_SETREGS failed\n");
    9099        return errno;
    91100    }
     
    93102    if(ptrace(PTRACE_POKETEXT, pid, oregs.esp-4 , oinst) < 0)
    94103    {
     104        fprintf(stderr, "PTRACE_POKETEXT failed\n");
    95105        return errno;
    96106    }
     
    157167    regs.edx = 0755;
    158168
    159     if((ret = do_syscall(pid, &regs)) < 0)
     169    if((ret = do_syscall(pid, &regs)) != 0)
    160170    {
    161171        return ret;
     
    193203    regs.edx = ((long)target_page);
    194204
    195     if((ret = do_syscall(pid, &regs)) < 0)
     205    if((ret = do_syscall(pid, &regs)) != 0)
    196206    {
    197207        return ret;
     
    211221}
    212222
    213 static int do_setpgrp(pid_t pid, int fd) {
    214     struct user_regs_struct regs;
    215     void *backup_page;
    216     void *target_page = (void*)(0x08048000);
    217     size_t size = (1<<12)*2; /* 8K */
    218     int ret, pgrp;
    219 
    220     /* Backup the pages that we will use */
    221     backup_page = malloc(size);
    222     if (memcpy_from_target(pid, backup_page, target_page, size) < 0)
    223         return -1;
    224 
    225     if(ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
    226     {
    227         fprintf(stderr, "PTRACE_GETREGS failed\n");
    228         return errno;
    229     }
    230 
    231     pgrp = getpgrp();
    232 
    233     memcpy_into_target(pid, target_page, &getpgrp, 4);
    234 
    235     regs.eax = SYS_ioctl;
    236     regs.ebx = fd;
    237     regs.ecx = TIOCSPGRP;
    238     regs.edx = (long)(target_page);
    239     do_syscall(pid, &regs);
    240 
    241 
    242     if((ret = do_syscall(pid, &regs)) < 0)
     223static int do_setsid(pid_t pid) {
     224    struct user_regs_struct regs;
     225    int ret;
     226
     227    if(ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
     228    {
     229        fprintf(stderr, "PTRACE_GETREGS failed\n");
     230        return errno;
     231    }
     232
     233    debug("Running setsid on process %d (sid=%d)", pid, getsid(pid));
     234
     235    regs.eax = SYS_setpgid;
     236    regs.ebx = 0;
     237    regs.ecx = getsid(pid);
     238
     239    if((ret = do_syscall(pid, &regs)) != 0)
    243240    {
    244241        return ret;
    245242    }
    246243
    247     if (regs.eax < 0) {
    248         fprintf(stderr, "ioctl failed\n");
    249         return (-regs.eax);
    250     }
    251 
    252     /* Restore the pages */
    253     memcpy_into_target(pid, target_page, backup_page, size);
     244    if (regs.eax != 0) {
     245        fprintf(stderr, "setpgid failed\n");
     246        return -regs.eax;
     247    }
     248
     249    regs.eax = SYS_setsid;
     250
     251    if((ret = do_syscall(pid, &regs)) != 0)
     252    {
     253        return ret;
     254    }
     255
     256    debug("pid %d has now sid %d", pid, getsid(pid));
     257
     258    if (regs.eax == -1) {
     259        fprintf(stderr, "getsid failed\n");
     260        return -regs.eax;
     261    }
    254262
    255263    return 0;
     
    261269    int i, fd = 0, mode, ret;
    262270    char fdstr[1024];
     271    char to_open[3];
    263272    struct stat stat_buf;
    264273
    265274    debug("pty is %s", ptyname);
    266275
     276    kill(pid, SIGSTOP);
    267277    if(ptrace(PTRACE_ATTACH, pid, 0, 0) < 0)
    268278    {
     
    270280        return errno;
    271281    }
     282    kill(pid, SIGCONT);
    272283    waitpid(pid, NULL, 0);
    273284
     
    275286    {
    276287        snprintf(fdstr, sizeof(fdstr), "/proc/%d/fd/%d", pid, i);
     288        to_open[i]=0;
    277289        lstat(fdstr, &stat_buf);
    278290        if ((stat_buf.st_mode & S_IRUSR) && (stat_buf.st_mode & S_IWUSR))
     
    285297        if (stat(fdstr, &stat_buf) < 0)
    286298            continue;
    287         if (!S_ISCHR(stat_buf.st_mode)) //FIXME How to know for sure this is the pty and not /dev/null ?
     299
     300        if (!S_ISCHR(stat_buf.st_mode) || MAJOR(stat_buf.st_rdev) != UNIX98_PTY_SLAVE_MAJOR)
    288301            continue;
    289302
     
    297310            fprintf(stderr, "do_close %s\n", strerror(ret));
    298311        }
     312        to_open[i]=1;
     313    }
     314
     315    if((ret = do_setsid(pid)))
     316    {
     317        fprintf(stderr, "do_setsid %s\n", strerror(ret));
     318    }
     319
     320    for(i=0; i<=2; i++)
     321    {
     322        if(!to_open[i])
     323            continue;
    299324        if((ret = do_open(pid, ptyname, mode, &fd)))
    300325        {
     
    305330            fprintf(stderr, "do_dup2 %s\n", strerror(ret));
    306331        }
    307         if((ret = do_setpgrp(pid, i)))
    308         {
    309             fprintf(stderr, "do_setpgrp %s\n", strerror(ret));
    310         }
    311332    }
    312333
    313334    kill(pid, SIGWINCH);
    314 
    315335    ptrace(PTRACE_DETACH, pid, 0, 0);
    316336
Note: See TracChangeset for help on using the changeset viewer.