포크 폭탄의 포크()는 어디에 있습니까:(){ :|: & };:?

포크 폭탄의 포크()는 어디에 있습니까:(){ :|: & };:?

경고: 대부분의 셸에서 이 명령을 실행하면 시스템이 손상되어 복구를 위해 강제 종료가 필요합니다.

나는 재귀 함수 :(){ :|: & };:와 그 기능을 이해합니다. 하지만 포크 시스템 호출이 어디에 있는지 모르겠습니다. 확실하진 않지만 파이프 안에 있는 것 같아요 |.

답변1

의 파이프로 인해 x | y파이프를 포그라운드 프로세스 그룹의 일부로 포함하는 하위 쉘이 생성됩니다. 이렇게 하면 계속해서 서브쉘(패스)이 생성되어 fork()포크 폭탄이 생성됩니다.

$ for (( i=0; i<3; i++ )); do
>     echo "$BASHPID"
> done
16907
16907
16907
$ for (( i=0; i<3; i++ )); do
>     echo "$BASHPID" | cat
> done
17195
17197
17199

:그러나 분기는 코드의 마지막 호출 인 코드가 실행될 때까지 실제로 발생하지 않습니다 .

포크 폭탄 해체 작동 방식:

  • :()-라는 새로운 함수를 정의합니다.:
  • { :|: & }- 호출 함수를 백그라운드 호출 함수의 다른 인스턴스로 재귀적으로 전송하는 함수 정의
  • :- 포크 폭탄 기능 호출

이는 많은 메모리를 차지하지 않는 경향이 있지만 PID를 차지하고 CPU 사이클을 소모합니다.

답변2

코드의 마지막 비트 ;:는 함수를 실행하는 것입니다 :(){ ... }. 여기서 포크가 발생합니다.

세미콜론은 첫 번째 명령을 종료하고 함수를 호출하는 또 다른 명령을 시작합니다 :. 함수 정의에는 :자체 호출( )이 포함되며 해당 호출의 출력은 백그라운드 버전으로 파이프됩니다 :. 이는 프로세스를 무기한으로 지원합니다.

이 함수를 호출할 때마다 :()C 함수를 호출하는 것입니다 fork(). 결국 이로 인해 시스템의 모든 프로세스 ID(PID)가 소진됩니다.

|:&무슨 일이 일어나고 있는지 이해할 수 있도록 다른 것으로 바꿀 수 있습니다 .

관찰자 설정

터미널 창에서 다음을 수행합니다.

$ watch "ps -eaf|grep \"[s]leep 61\""

"퓨즈 지연" 포크 폭탄 설정

다른 창에서는 약간 수정된 Fork Bomb 버전을 실행하겠습니다. 이 버전은 자체적으로 제한을 시도하여 해당 버전이 수행하는 작업을 연구할 수 있습니다. 우리 버전은 이 함수를 호출하기 전에 61초 동안 절전 모드로 전환됩니다 :().

또한 초기 호출이 이루어진 후 백그라운드에 배치할 수도 있습니다. Ctrl+ z를 입력하고 bg.

$ :(){ sleep 61; : | : & };:

# control + z
[1]+  Stopped                 sleep 61
[2] 5845
$ bg
[1]+ sleep 61 &

이제 초기 창에서 명령을 실행하면 다음이 jobs표시됩니다.

$ jobs
[1]-  Running                 sleep 61 &
[2]+  Running                 : | : &

몇 분 후:

$ jobs
[1]-  Done                    sleep 61
[2]+  Done                    : | :

관찰자에게 확인

한편 다른 창에서는 다음을 실행하고 있습니다 watch.

Every 2.0s: ps -eaf|grep "[s]leep 61"                                                                                                                                             Sat Aug 31 12:48:14 2013

saml      6112  6108  0 12:47 pts/2    00:00:00 sleep 61
saml      6115  6110  0 12:47 pts/2    00:00:00 sleep 61
saml      6116  6111  0 12:47 pts/2    00:00:00 sleep 61
saml      6117  6109  0 12:47 pts/2    00:00:00 sleep 61
saml      6119  6114  0 12:47 pts/2    00:00:00 sleep 61
saml      6120  6113  0 12:47 pts/2    00:00:00 sleep 61
saml      6122  6118  0 12:47 pts/2    00:00:00 sleep 61
saml      6123  6121  0 12:47 pts/2    00:00:00 sleep 61

프로세스 계층

a는 ps -auxf다음 프로세스 계층 구조를 보여줍니다.

$ ps -auxf
saml      6245  0.0  0.0 115184  5316 pts/2    S    12:48   0:00 bash
saml      6247  0.0  0.0 100988   468 pts/2    S    12:48   0:00  \_ sleep 61
....
....
saml      6250  0.0  0.0 115184  5328 pts/2    S    12:48   0:00 bash
saml      6268  0.0  0.0 100988   468 pts/2    S    12:48   0:00  \_ sleep 61
saml      6251  0.0  0.0 115184  5320 pts/2    S    12:48   0:00 bash
saml      6272  0.0  0.0 100988   468 pts/2    S    12:48   0:00  \_ sleep 61
saml      6252  0.0  0.0 115184  5324 pts/2    S    12:48   0:00 bash
saml      6269  0.0  0.0 100988   464 pts/2    S    12:48   0:00  \_ sleep 61
...
...

청소 시간

A는 killall bash일이 통제 불가능해지기 전에 일이 일어나는 것을 막을 것입니다. 이 방법으로 청소하는 것은 약간 가혹할 수 있지만 모든 bash껍질을 벗기지 않을 수 있는 더 부드럽고 온화한 방법은 다음을 수행하는 것입니다.

  1. 포크 폭탄이 실행될 의사 터미널을 결정합니다.

    $ tty
    /dev/pts/4
    
  2. 의사 터미널 종료

    $ pkill -t pts/4
    

무슨 일이야?

및 에 대한 각 호출 은 bash명령을 실행하는 셸에서 호출되는 sleepC 함수 입니다.fork()bash

관련 정보