포크 폭탄으로 시스템을 충돌시킬 수없는 이유는 무엇입니까?


54

최근에 GNU / Linux의 프로세스에 대한 정보를 파헤쳐 서 악명 높은 포크 폭탄을 만났습니다.

:(){ : | :& }; :

이론적으로 시스템에 리소스가 부족할 때까지 자체 복제됩니다.

그러나 CLI 데비안GUI 민트 배포판 모두에서 테스트를 시도했지만 시스템에 많은 영향을 미치지 않는 것 같습니다. 예, 수많은 프로세스가 생성되며 잠시 후 다음과 같은 콘솔 메시지를 읽습니다.

bash : 포크 : 리소스를 일시적으로 사용할 수 없음

배쉬 : 포크 : 재시도 : 자식 프로세스 없음

그러나 얼마 후 모든 프로세스가 중단되고 모든 것이 정상으로 돌아옵니다. ulimit가 사용자 당 최대 프로세스 수를 설정 한 것을 읽었 지만 실제로 그것을 높일 수없는 것 같습니다.

포크 폭탄에 대한 시스템 보호는 무엇입니까? 왜 모든 것이 얼어 붙거나 적어도 많이 지연 될 때까지 스스로 복제되지 않습니까? 포크 폭탄으로 시스템을 실제로 충돌시키는 방법이 있습니까?


2
현재 최대 PID는 무엇으로 설정되어 있습니까?
dsstorefile1

5
포크 폭탄을 사용하여 시스템을 "충돌"하지는 않을 것입니다 ... 당신이 말했듯이, 리소스를 소진하고 새로운 프로세스를 생성 할 수는 없지만 시스템은 충돌
Josh

2
사용자가 실행하면 어떻게됩니까 :(){ :& :; }; :대신? 그들은 또한 결국 결국 살 해당합니까? 무엇에 대해 :(){ while :& do :& done; }; :?
mtraceur

이 멋진 질문으로 이전의 "폐쇄 된"투표를 다시 생각하게되었습니다. 그러나 "I"는 항상 영어 대문자이므로 더 이상 잘못 쓰지 마십시오.
user259412

답변:


86

systemd를 사용하는 Linux 배포판이있을 것입니다.

Systemd는 각 사용자에 대한 cgroup을 만들고 사용자의 모든 프로세스는 동일한 cgroup에 속합니다.

Cgroups는 최대 프로세스 수, CPU주기, RAM 사용량 등과 같은 시스템 리소스에 대한 제한을 설정하는 Linux 메커니즘입니다. 이는 syscall ulimit을 사용 하는 것과는 다른,보다 현대적인 리소스 제한 레이어입니다 getrlimit().

실행하면 systemctl status user-<uid>.slice(사용자의 cgroup을 나타냄 ) 해당 cgroup 내에서 허용되는 현재 및 최대 작업 수 (프로세스 및 스레드)를 볼 수 있습니다.

$ systemctl 상태 사용자-$ UID.slice
● user-22001.slice-UID 22001의 사용자 조각
   로드 됨 :로드 됨
  드롭 인 : /usr/lib/systemd/system/user-.slice.d
           └─10-defaults.conf
   활성화 : 월요일부터 활성화 2018-09-10 17:36:35 EEST; 1 주일 전
    작업 : 17 (한계 : 10267)
   메모리 : 616.7M

기본적으로 systemd가 각 사용자에게 허용하는 최대 작업 수는 "시스템 전체 최대"( sysctl kernel.threads-max) 의 33 %입니다 . 이것은 일반적으로 ~ 10,000 개의 작업에 해당합니다. 이 한계를 변경하려면 다음을 수행하십시오.

  • systemd v239 이상에서 사용자 기본값은 다음에서 TasksMax = 를 통해 설정됩니다 .

    /usr/lib/systemd/system/user-.slice.d/10-defaults.conf
    

    특정 사용자에 대한 제한을 조정하려면 (/etc/systemd/system.control에 저장 될뿐만 아니라 즉시 적용됨) 다음을 실행하십시오.

    systemctl [--runtime] set-property user-<uid>.slice TasksMax=<value>
    

    여기에서 장치 설정을 재정의하는 일반적인 메커니즘 (예 :)도 systemctl edit여기에서 사용할 수 있지만 재부팅해야합니다. 예를 들어 모든 사용자에 대한 제한을 변경 하려면을 만들 수 있습니다 /etc/systemd/system/user-.slice.d/15-limits.conf.

  • systemd v238 및 이전 버전에서는 사용자 기본값이 에서 UserTasksMax = 를 통해 설정됩니다 /etc/systemd/logind.conf. 값을 변경하려면 일반적으로 재부팅해야합니다.

이것에 대한 자세한 정보 :


5
그리고 12288 개 프로세스 (마이너스 이미 폭탄 전에 산란 된 것)을 제외하고 아무것도하지 않고 노력 새로 만들 정말 현대적인 시스템에 영향을주지 않습니다.
마스트

13

어쨌든 현대 리눅스 시스템은 더 이상 충돌하지 않습니다.

많은 프로세스를 생성하지만 프로세스가 유휴 상태가 될 때 CPU를 많이 소모하지는 않습니다. RAM이 부족하기 전에 프로세스 테이블에 슬롯이 부족합니다.

Hkoof가 지적한 것처럼 cgroup이 제한되지 않은 경우에도 다음 변경으로 인해 시스템이 다운됩니다.

:(){ : | :& : | :& }; :

5
이것은 실제로 시스템을 '충돌'한다고 생각하는 것에 달려 있습니다. 프로세스 테이블의 슬롯이 부족하면 커널 패닉이 발생하지 않더라도 대부분의 경우 시스템이 무릎을 꿇게됩니다.
Austin Hemmelgarn

4
@AustinHemmelgarn : 이것이 현명한 시스템이 루트에 대한 마지막 4 개 정도의 프로세스 ID를 예약하는 이유입니다.
Joshua

2
프로세스가 "유휴"상태가되는 이유는 무엇입니까? 각 분기 프로세스는 더 많은 프로세스를 작성하는 무한 재귀입니다. 따라서 시스템 호출 오버 헤드 ( fork오버 및 오버) 에 많은 시간을 소비 하고 나머지 시간은 함수 호출을 수행합니다 (쉘 호출 스택의 각 호출에 대해 더 많은 메모리를 사용하는 것으로 추정됩니다).
mtraceur

4
@ mtraceur : 포크가 시작되지 않을 때만 발생합니다.
Joshua

1
아, 다시 가져가 나는 :(){ :& :; }; :질문에있는 것 대신 내 머리에 약간 다른 포크 폭탄 구현의 논리를 모델링했습니다 (예 :). 나는 주어진 고전 주의적 실행 흐름을 실제로 완전히 생각하지 않았다.
mtraceur

9

90 년대로 돌아가서 우연히이 중 하나를 스스로에게 공개했습니다. fork () 명령이있는 C 소스 파일에서 실수로 실행 비트를 설정했습니다. 두 번 클릭하면 csh가 원하는대로 편집기에서 열지 않고 실행하려고했습니다.

그럼에도 불구하고 시스템이 충돌하지 않았습니다. Unix는 계정 및 / 또는 OS에 프로세스 제한이있을 정도로 강력합니다. 대신에 매우 느리게 진행되므로 프로세스를 시작해야하는 모든 것이 실패 할 수 있습니다.

배후에서 일어나는 일은 프로세스 테이블이 새로운 프로세스를 생성하려는 프로세스로 채워진다는 것입니다. 프로세스 테이블이 가득 차서 포크에 오류가 발생하거나 절망적 인 운영자가 시스템에 정신을 복원하려고 시도하여 프로세스 중 하나가 종료되면 다른 프로세스 중 하나가 새 프로세스를 즐겁게 포크합니다. 공극.

"포크 폭탄"은 기본적으로 프로세스 테이블을 가득 채우는 미션에서 의도하지 않은 자체 복구 프로세스 프로세스입니다. 그것을 막을 수있는 유일한 방법은 어떻게 든 그들을 한 번에 죽일 것입니다.


1
한 번에 모두 죽이는 것이 생각보다 쉽습니다.
Score_Under

2
@Score_Under-가장 가까운 해리스 나이트 호크로 즉시 달려 가서 문제가 해결되었는지 확인하지 않으면 저를 용서해주십시오. 실패한 포크로 죽기 전에 PID에 신호를 보내서 신호를 보내는 중이라고 생각하고 있는데, 또 다른 문제는 어려울 수도 있지만 시도해 봐야합니다.
TED

@TED ​​kill -9 -1 (여러분은 루트가 아니라 포크 폭탄을 실행하는 동일한 사용자와 함께) 여기에 친구가 될 수 있습니다.
Andreas Krey

@AndreasKrey-그 깃발은 친숙하지 않아서 90 년대 나이트 호크가 그랬다는 것을 의심합니다.
TED

1
@TED ​​: -1깃발이 아닙니다. kill하나의 옵션 만 사용하고 구문 분석 옵션을 중지합니다. -1모든 프로세스의 별명 인 프로세스 id 가 종료됩니다.
Joshua
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.