리눅스는 포크 폭탄으로부터 보호 할 수단이 있습니까? fork(); } } 리눅스 에서이 프로그램을 실행하고 터미널에서

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

리눅스 에서이 프로그램을 실행하고 터미널에서 아무것도 출력하지 않으면 OS가 죽어 버린 것 같습니다. 리눅스는 메모리가 부족한 프로그램에 대한 보호 수단을 가지고 있습니까?



답변

이것은 포크 폭탄으로 알려져 있습니다.

리눅스는 메모리가 부족한 프로그램에 대한 보호 수단을 가지고 있습니까?

실제로는 아닙니다. 각 포크는 자체 가상 주소 공간과 메모리 사용량으로 새로운 프로세스를 생성합니다. 따라서 각 사본은 상대적으로 작습니다. 결국 시스템의 모든 물리적 + 스왑 메모리를 사용하게되고 메모리 부족 (OOM) 킬러가 개별 프로세스를 종료하기 시작합니다. 그러나 포크 폭탄은 여전히 ​​빠른 프로세스를 만듭니다 (더 빠르지 않은 경우).

이를 방지하는 한 가지 방법은 다음을 사용하여 사용자 프로세스 수를 제한하는 ulimit -u것입니다.


답변

예, 시스템에서 기본적으로 활성화되어 있지 않을 수 있습니다. setrlimit사용자 당 프로세스의 수를 포함하여 – 시스템 호출은 시스템 제한을 정의합니다.

커널 API에서 먼저 살펴 보자 ( “linux”를 언급 했으므로) : 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 설정할 수있는 몇 가지 다른 제한이 있음을 보여줍니다 (관심 할 수있는 것은 사용자가 사용하는 최대 파일 설명자 수임).


답변

사용자 레벨 또는 시스템 레벨에서 사용할 것인지에 따라 다릅니다. 사용자 수준에서 ulimit(또는 다른 쉘에 해당하는 명령) 가장 쉬운 솔루션입니다.

그러나 시스템 수준에는 악의적 인 사용자 (또는 ulimit를 사용하지 않는)가 시스템을 중지하지 못하게하는 메커니즘이 있습니다. Linux cgroups 메커니즘은 그룹별로 리소스를 제한 할 수 있습니다. pam_systemd사용자 그룹이 특정 그룹에 있도록 ( 기계적으로) 강제 할 수 있습니다 . 이것은 CPU 스케줄러와 같은 다른 이점도 있습니다.


답변

ulimit -ubash 쉘에서 사용 하여 “최대 사용자 프로세스”에 대한 한계를 설정하십시오.

C 쉘에서 limit명령 을 사용합니다 .

이를 위해 시스템 호출이 필요한 경우 호출을 사용 setrlimit하여을 설정하십시오 RLIMIT_NPROC.


답변

여기에 가장 최근의 답변이 3 년이 넘었으므로, 최신 커널 (4.3 이후)은 새로운 “PIDs 서브 시스템”을 통해 포크 폭탄을 방지하기 위해 명시 적으로 지원하고 있음을 지적하고 싶습니다. ( https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=49b786ea146f69c371df18e81ce0a2d5839f865chttps://git.kernel.org/cgit/linux/kernel/git 참조 /torvalds/linux.git/commit/?id=917d8e2d10f40e28aa9e0d824b2e5b8197d79fc2 )


답변