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

Я запускаю эту программу на моем Linux, на терминале ничего не выводится, операционная система кажется мертвой. Есть ли у linux какие-либо меры защиты для такой программы, которая может исчерпать память?

5 ответов5

18

Это известно как вилочная бомба.

Есть ли у linux какие-либо меры защиты для такой программы, которая может исчерпать память?

На самом деле, нет. Каждый форк создает новый процесс с собственным виртуальным адресным пространством и использованием памяти. Так что каждая копия относительно мала. В конце концов, вы израсходуете всю физическую + подкачку памяти в системе, и убийца нехватки памяти (OOM) начнет убивать отдельные процессы. Но вилочная бомба все равно будет создавать процессы так же быстро (если не быстрее).

Одним из способов предотвратить это в первую очередь является ограничение числа пользовательских процессов с помощью ulimit -u (при условии, что вы используете Bash; другие оболочки будут иметь эквиваленты).

10

Да, хотя он может быть не включен по умолчанию в вашей системе. Системный вызов setrlimit определяет системные ограничения - включая количество процессов на пользователя.

Давайте сначала рассмотрим это в API ядра (поскольку вы упомянули "linux"): вы можете использовать man-страницу для setrlimit, которая скажет вам сделать что-то вроде

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

struct rlimit  r;

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

Это установит максимальное количество процессов для пользователя (RLIMIT_NPROC) равным 40 (мягкое ограничение) и 50 (жесткое ограничение).

Теперь из оболочки, если вы используете bash, вы можете использовать встроенную команду ulimit :

ulimit -u
29089

Вы можете установить ограничение, передав его в качестве аргумента:

ulimit -u 100

ulimit --help покажет вам, что есть несколько других ограничений, которые вы можете установить (одно из которых может представлять интерес для максимального количества дескрипторов файлов, используемых пользователем).

7

Это зависит от того, хотите ли вы использовать его на уровне пользователя или системы. На уровне пользователя самым простым решением будет ulimit(или соответствующие команды для других оболочек).

Однако на системном уровне существуют механизмы, предотвращающие остановку системы злоумышленниками (или просто не использующими ulimit). Механизм Linux cgroups может ограничивать ресурсы для каждой группы. Вы можете заставить (посредством механизма pam_systemd ) сеанс пользователя быть в определенной группе. Это имеет и другие преимущества, например, для планировщика ЦП.

6

Используйте ulimit -u из оболочки bash, чтобы установить ограничение на "максимальное количество пользовательских процессов".

Из оболочки C вы используете команду limit .

Если вам нужен системный вызов для этого, используйте вызов setrlimit для установки RLIMIT_NPROC .

1

Поскольку самым последним ответам здесь уже более 3 лет, я хочу отметить, что более новые ядра (начиная с 4.3) имеют явную поддержку для предотвращения разветвления бомб через новую "подсистему PID". (См. Https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=49b786ea146f69c371df18e81ce0a2d5839f865c и https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=917d8e2d10f40e28aa9e0d824b2e5b8197d79fc2)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .