Mate um processo iniciado por execl

1

Estou executando o nmap a partir de um programa em C usando execl:

execl("/bin/sh","sh","-c","sudo nmap -sS -A 192.168.0.1/24",NULL);

Eu tenho o HTOP sendo executado em outra janela do shell e vejo que meu execl inicia os PIDs:

2339 for command "nmap -sS .."
2335 for command "sudo nmap -sS .."
2334 for command "sh .."

O PID filho é 2334. O Nmap demora muito para terminar e se eu quiser matar todos os três processos eu emito kill 2339 do shell. Todos os 2339,2335 e 2334 desaparecem do programa de monitoramento do HTOP.

O que eu gostaria de fazer é emitir kill (2339, ...) dentro do meu programa em C e matar todos como eu posso fazer no shell. Meu problema é que como faço para obter o PID 2339? Meu childPID está neste exemplo 2334.

    
por user1231247 05.06.2017 / 23:00

2 respostas

3

Primeiro, você pode simplificar seu problema cortando um dos processos intermediários: não há motivo para usar sh -c para iniciar seu processo. Na verdade, é potencialmente menos seguro, se sua linha de comando real for construída dinamicamente. Em vez de:

execl("/bin/sh","sh","-c","sudo nmap -sS -A 192.168.0.1/24",NULL);

Você deve fazer apenas:

execlp("sudo", "sudo", "nmap", "-sS", "-A", "192.168.0.1/24", NULL);

Agora você tem apenas dois processos: o sudo e o nmap em si. Você conhece o ID do processo do pai ( sudo ), mas não conhece o ID do processo do filho ( nmap ). Mas isso não importa, porque você pode usar um recurso de sudo : matar o pai (com SIGTERM ) e ele encaminhará o sinal ao filho para você.

Seu último problema restante não está diretamente relacionado à pergunta que você está fazendo, mas é assim mesmo que você provavelmente não tem permissão para matar qualquer um desses processos! Como sudo está envolvido, o qual tem como objetivo elevar seu privilégio, você provavelmente não tem permissão para enviá-lo ou a seus sinais filhos em primeiro lugar.

    
por 05.06.2017 / 23:10
1

Um método seria sudo kill a criança pid do processo pai, assumindo que sudoers concede isso.

#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void sudokill(pid_t tokill);

int main(void)
{
    pid_t pid;

    pid = fork();
    switch (pid) {
    case -1:
        err(1, "fork() failed");
    case 0:
        execlp("sudo", "sudo", "sleep", "999", (char *) NULL);
        err(1, "execlp() failed");
    default:
        sleep(7);
        sudokill(pid);
    }
    exit(EXIT_SUCCESS);
}

void sudokill(pid_t tokill)
{
    char *killstr;
    int status;
    pid_t pid;

    if (asprintf(&killstr, "%d", tokill) < 0)
        err(1, "asprintf() failed");

    pid = fork();
    switch (pid) {
    case -1:
        err(1, "fork() failed");
    case 0:
        execlp("sudo", "sudo", "kill", killstr, (char *) NULL);
        err(1, "execlp() failed");
    default:
        wait(&status);
    }

    free(killstr);
}
    
por 05.06.2017 / 23:35

Tags