¿Qué sucede cuando un usuario no root envía señales al proceso del usuario root?

33

Me pregunto sobre la seguridad de las señales UNIX.

SIGKILLmatará el proceso. Entonces, ¿qué sucede cuando el proceso de un usuario no root envía una señal al proceso de un usuario root? ¿El proceso todavía lleva a cabo el controlador de señal?

Sigo la respuesta aceptada (de gollum), escribo man capabilitesy encuentro muchas cosas sobre el kernel de Linux. De man capabilities:

NAME

   capabilities - overview of Linux capabilities
DESCRIPTION

   For the purpose of performing permission checks, traditional UNIX
   implementations distinguish two categories of processes: privileged
   processes (whose effective user ID is 0, referred to as superuser or
   root), and unprivileged processes (whose effective UID is nonzero).
   Privileged processes bypass all kernel permission checks, while
   unprivileged processes are subject to full permission checking based
   on the process's credentials (usually: effective UID, effective GID,
   and supplementary group list).

   Starting with kernel 2.2, Linux divides the privileges traditionally
   associated with superuser into distinct units, known as capabilities,
   which can be independently enabled and disabled.  Capabilities are a
   per-thread attribute.
primavera amorosa
fuente
55
Aparte de SIGKILL, que es un caso especial y administrado completamente por el núcleo, las señales son simplemente una solicitud. El proceso de recepción puede hacer lo que quieran con ellos.
chepner
3
@chepner Aparte de SIGKILL y SIGSTOP ...
jlliagre
1
@chepner El proceso de recepción tiene que decidir activamente si quiere manejar la señal. Si el proceso de recepción no lo ha hecho, muchas señales matarán por defecto el proceso exactamente de la misma manera SIGKILL. Inicialmente SIGINT, SIGKILLy SIGTERMtendrá exactamente el mismo efecto, la única diferencia es que el proceso de recepción puede cambiar este valor predeterminado para algunos de ellos.
kasperd

Respuestas:

34

En Linux depende de las capacidades del archivo.

Tome la siguiente mykill.cfuente simple :

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>

void exit_usage(const char *prog) {
        printf("usage: %s -<signal> <pid>\n", prog);
        exit(1);
}

int main(int argc, char **argv) {
        pid_t pid;
        int sig;

        if (argc != 3)
                exit_usage(argv[0]);

        sig = atoi(argv[1]);
        pid = atoi(argv[2]);

        if (sig >= 0 || pid < 2)
                exit_usage(argv[0]);

        if (kill(pid, -sig) == -1) {
                perror("failed");
                return 1;
        }
        printf("successfully sent signal %d to process %d\n", -sig, pid);

        return 0;
}

constrúyelo:

gcc -Wall mykill.c -o /tmp/mykill

Ahora, como usuario root, inicie un proceso de suspensión en segundo plano:

root@horny:/root# /bin/sleep 3600 &
[1] 16098

Ahora, como usuario normal, intenta matarlo:

demouser@horny:/home/demouser$ ps aux | grep sleep
root     16098  0.0  0.0  11652   696 pts/20   S    15:06   0:00 sleep 500

demouser@horny:/home/demouser$ /tmp/mykill -9 16098
failed: Operation not permitted

Ahora, como usuario root, cambie las /tmp/mykillmayúsculas:

root@horny:/root# setcap cap_kill+ep /tmp/mykill

E intente nuevamente como usuario normal:

demouser@horny:/home/demouser$ /tmp/mykill -9 16098
successfully sent signal 9 to process 16098

Finalmente, elimine /tmp/mykillpor razones obvias;)

Gollum
fuente
3
Sigue tu pista,
escribo
24

Nada:

strace kill -HUP 1
[...]
kill(1, SIGHUP)    = -1 EPERM (Operation not permitted)
[...]
Hauke ​​Laging
fuente
1
¿Este tipo de seguridad se realiza a nivel del sistema operativo o codificado en el controlador de señal del usuario?
lovespring
3
@lovespring El núcleo no entrega la señal al proceso de destino. La llamada al sistema se devuelve con un error y, aparte de eso, se ignora.
Hauke ​​Laging
Eso no es cierto en general. Depende de las capacidades.
gollum
1
@psmears sí, pero otros tienen conceptos similares (por ejemplo, "privilegios" en solaris). Entonces la respuesta "Nada" es definitivamente incorrecta.
gollum
1
@gollum: no es exactamente incorrecto (después de todo, es el comportamiento predeterminado en todos los sistemas operativos de la familia Unix, y el único posible en muchos, incluidos los núcleos Linux más antiguos, por ejemplo), pero tiene razón en que está incompleto, pero solo menciona "capacidades", sin entrar en más detalles acerca de dónde son soportadas también es incompleta en una pregunta sobre Unix en general :)
psmears
5

kill(2) La página man explica:

Notas de Linux

En diferentes versiones de kernel, Linux ha impuesto diferentes reglas para los permisos necesarios para que un proceso sin privilegios envíe una señal a otro proceso. En los núcleos 1.0 a 1.2.2, se podría enviar una señal si la ID de usuario efectiva del remitente coincidía con la del receptor, o si la ID de usuario real del remitente coincidía con la del receptor. Desde el kernel 1.2.3 hasta 1.3.77, se podría enviar una señal si la ID de usuario efectiva del remitente coincidía con la ID de usuario real o efectiva del receptor. Las reglas actuales, que se ajustan a POSIX.1-2001, se adoptaron en el núcleo 1.3.78.

jai_s
fuente
1.3.78 es una historia extremadamente antigua, como 1.3. data de 1995 o por ahí. 1.3 fue la serie de desarrollo que condujo a 2.0 (en 1996)
vonbrand
-1

la señal se llevaría pero el propietario del proceso pertenece a la raíz. por lo tanto, el otro usuario no tiene derecho a finalizar el proceso, por lo que recibirá un problema de error de permiso.

la finalización del proceso solo es posible cuando es propietario de la propiedad (derechos propios) del proceso.

Naveen Dharman
fuente
No, sys_kill devuelve -1 y errno será -EPERM.
Peter dice reinstalar a Monica