¿Tiene Linux alguna medida de protección contra las bombas de horquilla?

12
#include <unistd.h>
int main(int argc, char* argv[]) {
  while(1)
  {
    fork();
  } 
}

Ejecuto este programa en mi Linux, no sale nada en el terminal, el sistema operativo parece estar muerto. ¿Tiene Linux alguna medida de protección para dicho programa que pueda quedarse sin memoria?


fuente
2
Sospecho que el impacto sería mucho menor si usted no siguió el mal consejo muchas distribuciones dan para crear una partición de intercambio grande ...
R .. GitHub dejar de ayudar a ICE
1
¿"No crear ningún proceso nuevo después de alcanzar 65k" cuenta como contramedida? ;)
Bobby

Respuestas:

18

Esto se conoce como una bomba tenedor .

¿Tiene Linux alguna medida de protección para dicho programa que pueda quedarse sin memoria?

Realmente no. Cada bifurcación produce un nuevo proceso, con su propio espacio de direcciones virtuales y uso de memoria. Entonces cada copia es relativamente pequeña. Eventualmente, usará toda la memoria física + de intercambio en el sistema, y ​​el asesino de falta de memoria (OOM) comenzará a matar procesos individuales. Pero la bomba tenedor seguirá creando procesos igual de rápido (si no más rápido).

En primer lugar, una forma de evitar que esto ocurra es limitar el número de procesos de usuario, utilizando ulimit -u(suponiendo que esté utilizando Bash; otros shells tendrán equivalentes).

Oliver Charlesworth
fuente
2
Una cosa a tener en cuenta es que ulimites específico de bash; otros shells probablemente tendrán el mismo comando incorporado, pero quizás con un nombre diferente.
Jay
@ Jay: punto justo. He notado eso en la respuesta ahora, ¡gracias!
Oliver Charlesworth
1
limitar los descriptores de memoria / archivo por usuario debería ser suficiente. Limitar la memoria por usuario es siempre una buena idea. Cuando se mata un proceso (oom), el perro guardián debe enviar una notificación para que el BOFH pueda arrancar al usuario 'el pícaro' con todos los procesos pertenecientes al sistema
Creo que también puede establecer algunos límites a través de parámetros de inicio de sesión
p_l
10

Sí, aunque es posible que no esté habilitado de forma predeterminada en su sistema. La setrlimitllamada al sistema define los límites del sistema, incluido el número de procesos por usuario.

Miremos primero en la API del núcleo (ya que mencionó "linux"): puede usar la página de manual para setrlimit, que le indicará que haga algo como

#include <sys/resource.h>
...

struct rlimit  r;

rnew.r_cur = 40;
rnew.r_max = 50;
setrlimit(RLIMIT_NPROC,&r);

Esto establecerá los procesos máximos por usuario ( RLIMIT_NPROC) en 40 (límite flexible) y 50 (límite rígido).

Ahora, desde el shell, si usa bash, puede usar el ulimitcomando incorporado:

ulimit -u
29089

Puede establecer el límite pasándolo como argumento:

ulimit -u 100

ulimit --help le mostrará que hay varios otros límites que puede establecer (uno que puede ser de interés es el número máximo de descriptores de archivo utilizados por el usuario).

Arrendajo
fuente
7

Depende si desea usarlo a nivel de usuario o de sistema. En el nivel de usuario, ulimit(o los comandos correspondientes para otros shells) serían la solución más fácil.

Sin embargo, a nivel del sistema, existen mecanismos para evitar que usuarios malintencionados (o simplemente no usen ulimit) detengan el sistema. El mecanismo de cgroups de Linux puede limitar los recursos por grupo. Puede forzar (por pam_systemdmacanismo) que la sesión del usuario esté en un grupo específico. Esto tiene otros beneficios para, por ejemplo, el planificador de CPU.

Maciej Piechotka
fuente
1
+1: los cgroups son realmente nuevos, y la mayoría de las personas aún no saben mucho sobre ellos. ¿Dónde podemos aprender más?
Ken Bloom
1
@KenBloom: 1. navegando /sys/fs/cgroup/2. buscando en google 3. navegando a través de make menuconfig4. Al examinar /usr/src/linux/Documentation/cgroups5. Al leer la documentación de systemd. Lo siento, no puedo ayudar más, pero usé solo esos recursos. Usé cgroups en el escritorio para controlar los recursos.
Maciej Piechotka
6

Úselo ulimit -udesde el shell bash para establecer un límite en "procesos de usuario máximos".

Desde el shell C, usa el limitcomando.

Si necesita una llamada al sistema para hacer esto, use la setrlimitllamada para configurar RLIMIT_NPROC.

Ken Bloom
fuente