Toon posts:

[oeps] waarom hangt dit de kernel?

Pagina: 1
Acties:
  • 146 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Op zich niet zo vreemd... Ik heb een programma die random geheugen en processen opslokt. Zeer nuttig (not :+), was bedoeld om de OOM te testen. Tot mijn verbazing hing mijn computer nog geen halve seconde later met 1500+ processen actief en mijn geheugen grotendeels vol. Ik hoorde de hardeschijf (swap) nog even ratelen toen de UI al bevroren was, maar dat stopte na enkele seconden ook, en toen was de computer... dood. :o.

Code:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
int
main (int   argc,
      char *argv[])
{
  while (1) {
    if (fork()) {
      malloc(1<<20);
    } else {
      execvp(argv[0], argv);
    }
  }
  return 0;
}


Code spreekt voor zich: het maakt in een loop child processes aan (fork()), die het parent proces opstarten, wat dus een clone creeert (execvp()). Daarna allocate ie een meg aan geheugen (malloc(1<<20)), wat niet wordt vrijgegeven. Dit proces zal zich binnen de seconde enkele tig of enkele honderden keren herhalen, wat dus een giga-hoeveelheid RAM in beslag neemt en je procestabel in principe volledig inneemt.

De vraag is: waarom werkt dit? De kernel hoort OOM toe te passen, of geen scheduling aan child processes te geven als dat niet kan (wat hier clearly het geval is). Wat is er zo stom dat dit alsnog wel werkt en dat het mijn computer direct hangt? Volgens XTerm is dit geen kernel bug (wat m.i. wel zo is), wat vinden anderen hiervan?

  • Sjonny
  • Registratie: Maart 2001
  • Laatst online: 21:39

Sjonny

Fratser

je malloc()ed wel, maar je schrijft er nix in, dus dat schiet niet echt op. ik denk ook niet dat je memory volloopt, maar je procestabel wel. kwadratisch zelfs .. of hoe noem je dat .. maar oom zal niet snel in kicken zo denk ik...

The problem is in the part of your brain that handles intelligence.


  • Wilke
  • Registratie: December 2000
  • Laatst online: 22:15
Hmm...ik vind dat dit inderdaad niet zou mogen gebeuren.

Welke kernel versie probeer je eigenlijk? En ik kan me vaag herinneren dat er wel patches zijn om machines waarop meerdere mensen ingelogd zijn (bv. op een uni) te beschermen tegen 'misbruik' van resources. Dan kun je bv. instellen dat een bepaalde user max. 256 MB mem mag allocen, dat soort zaken.

Sjonny schreef op 22 February 2003 @ 15:40:
je malloc()ed wel, maar je schrijft er nix in, dus dat schiet niet echt op. ik denk ook niet dat je memory volloopt, maar je procestabel wel. kwadratisch zelfs .. of hoe noem je dat .. maar oom zal niet snel in kicken zo denk ik...


Huh? Jawel hoor...dat geheugen wordt zeker wel gealloceerd, en is dus zeker ook 'in gebruik'. Blijkbaar kickt OOM inderdaad niet snel genoeg in, dat blijkt wel ja |:(

Kan iemand die FreeBSD draait bovenstaande code eens draaien? Ik ben namelijk benieuwd...ik vermoed dat FreeBSD het wel even zwaar zal krijgen maar uiteindelijk gewoon het hele proces killt dat het gedonderd veroorzaakt. Wie kan en wil dat even testen... :)

[ Voor 53% gewijzigd door Wilke op 22-02-2003 15:44 ]


  • Aetje
  • Registratie: September 2001
  • Laatst online: 18-12-2025

Aetje

Troubleshooting met HAMERRR

Ik lees dit als:
Zolang 1:
Als fork (niets) lukt: Alloceer (1 leftshift 20 posities (=0!! 16 bits integer hier, dat bitje valt er buiten!) ), anders die execvp (kweenie wat die doet).
Wat er gebeurt is dat die Fork loop je process table vol laat lopen met lege processen. Die geen CPU tijd krijgen om zich af te sluiten (zijn immers leeg).

Forget your fears...
...and want to know more...


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

Als welke gebruiker start je dit programma? En heb je beperkingen aanstaan in je /etc/security/limits.conf (ik neem aan dat Wilke die ook bedoelt)? Zelf heb ik bij een test al eens gemerkt dat zelfs een lege lus met fork() - gewoon een forkbomb dus - niet netjes werd afgehandeld, maar bij welke kernelversie dat was weet ik niet meer. Werkt het wel als je een sleep() of nanosleep() in je loop zet, zodat de OOM-killer als het ware meer tijd krijgt om te reageren? Zou niet uit mogen maken, maar als het design van die killer niet helemaal netjes is dan kan het toch een verschil maken.

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • Wilke
  • Registratie: December 2000
  • Laatst online: 22:15
Aetje schreef op 22 February 2003 @ 15:46:
Ik lees dit als:
Zolang 1:
Als fork (niets) lukt: Alloceer (1 leftshift 20 posities (=0!! 16 bits integer hier, dat bitje valt er buiten!) ), anders die execvp (kweenie wat die doet).
Wat er gebeurt is dat die Fork loop je process table vol laat lopen met lege processen. Die geen CPU tijd krijgen om zich af te sluiten (zijn immers leeg).


Dan lees je het niet goed. Een int is sowieso 32 bits op elke machine behalve zwaar antieke zooi (of misschien is het 64 op hele nieuwe), maar op x86-machines is hij zeker 32 bit. Dus er wordt wel degelijk 1 MB gealloceerd.

Ook moet je weten wat de instructie 'fork' doet, dat is namelijk een beetje lastig uit te leggen als je het nog nooit eerder hebt gezien :)

Je kunt de manualpage lezen, maar kort gezegd komt het er op neer dat je een kopie van het huidige proces start. De functie 'fork()' returned dus 2 keer (!) - een keer in het ouder-, en een keer in het kindproces. De ouder krijgt als result het process-ID van het kindproces (zodat 'ie bv. kan wachten tot het proces is afgelopen, en weet om welk procesnummer het gaat), terwijl bij het kind fork() 0 oplevert. Vandaar dat je dus met if-else kunt splitsen tussen de code die het child en de parent moeten uitvoeren. De 'if-else' constructie heeft dus niet te maken met het al of niet slagen van het 'forken' van het proces. Duidelijker zo?

Btw. als het forken niet lukt krijg je ipv. een processID of 0 een (negatieve) foutcode terug, namelijk:

code:
1
2
EAGAIN - fork cannot allocate sufficient memory to copy the parent's page tables and allocate a task structure for the child.
ENOMEM - fork failed to allocate the necessary kernel structures  because memory is tight


Dit zou op een gegeven moment dan ook gewoon moeten gebeuren. Beelzebubu: pas je code eens aan zodat hier op gecheckt wordt (moet je er even een switch()-statement van maken...) ? Ben benieuwd of je uberhaupt die foutcodes krijgt voordat de boel crasht namelijk.

Overigens groeit het aantal processen hier niet exponentieel, elk gestartte proces start ook weer precies 1 nieuw proces en alloceert precies 1 MB geheugen. Dus zo'n absurd experiment is dit op zich niet.

execvp 'overschrijft' de huidige proces-omgeving met die van een ander/nieuw gestart proces. Dus bij 'execvp' ontstaat niet een nieuw proces. Die vergissing maken mensen nog wel eens :) (daarom moet je dus eerst forken - een execvp returned als het goed is nooit, tenzij de aanroep ongeldig is natuurlijk).

[ Voor 13% gewijzigd door Wilke op 22-02-2003 16:24 ]


  • wzzrd
  • Registratie: Februari 2000
  • Laatst online: 08-02 16:57

wzzrd

The guy with the Red Hat

Ik wil dit wel een keertje testen op een FreeBSD-bak, maar alleen als ik er fysiek naast kan gaan staan. Niet eerder dan maandag dus :D

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 08-05 19:35

BoAC

Memento mori

Volgens mij valt je computer niet dood maar loopt hij constant in die while(1) loop.
En dat in al je processen.
Aangezien je niet checkt wat voor een error fork returned:

EAGAIN fork cannot allocate sufficient memory to copy the
parent's page tables and allocate a task structure
for the child.

ENOMEM fork failed to allocate the necessary kernel struc-
tures because memory is tight.

en ook niet checkt wat voor een error execvp returned loopt hij als beide failen gewoon door.
Dit vreet natuurlijk gigantisch veel processortijd waardoor de computer 'hangt' cq niet reageerd op input.

  • Cpt.Morgan
  • Registratie: Februari 2001
  • Laatst online: 23-11-2025
Wilke schreef op 22 February 2003 @ 16:22:Overigens groeit het aantal processen hier niet exponentieel, elk gestartte proces start ook weer precies 1 nieuw proces en alloceert precies 1 MB geheugen. Dus zo'n absurd experiment is dit op zich niet.
Hij voert het toch in een loop uit... Dus zodra het nieuwe proces gestart is, zijn er 2 van die processen, die elk weer een kloon maken, waarna het er 4 zijn. Enzovoorts:

1->2->4->8->16->32->64->128->256->512->1024->enz....

Dat is wel exponentiele groei, maar met basis 2 ipv 10....

  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Wilke schreef op 22 February 2003 @ 16:22:
[

Overigens groeit het aantal processen hier niet exponentieel, elk gestartte proces start ook weer precies 1 nieuw proces en alloceert precies 1 MB geheugen. Dus zo'n absurd experiment is dit op zich niet.

execvp 'overschrijft' de huidige proces-omgeving met die van een ander/nieuw gestart proces. Dus bij 'execvp' ontstaat niet een nieuw proces. Die vergissing maken mensen nog wel eens :) (daarom moet je dus eerst forken - een execvp returned als het goed is nooit, tenzij de aanroep ongeldig is natuurlijk).
Maar is argv[0] niet de naam van het eigen programma en start de kloon dus niet zichzelf op? (wat overigens overbodig zou zijn)
Met andere woorden doet de kloon niet precies het zelfde als zijn parent, in een oneindige while lus nieuwe kloontjes forken?
Exponentieel zou ik zeggen dus.

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

BoAC schreef op 22 February 2003 @ 16:27:
[...]
en ook niet checkt wat voor een error execvp returned loopt hij als beide failen gewoon door.
Dit vreet natuurlijk gigantisch veel processortijd waardoor de computer 'hangt' cq niet reageerd op input.

Het probleem is juist dat in zo'n geval de kernel zou moeten ingrijpen door processen af te gaan schieten - de 'OOM-killer'. Dat gebeurt in Beelzebubu's geval dus niet, en de vraag is waarom niet :).

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • serkoon
  • Registratie: April 2000
  • Niet online

serkoon

mekker.

Dit is gewoon een forkbom, vrij logisch dat je bak hiervan plat gaat, dat is de bedoeling zelfs van zo'n programma :)

De enige oplossing is het aantal processen en geheugengebruik per user te limiteren zodat een user niet je hele bak plat kan trekken.

  • Wilke
  • Registratie: December 2000
  • Laatst online: 22:15
Dawns_sister schreef op 22 February 2003 @ 16:36:
[...]

Maar is argv[0] niet de naam van het eigen programma en start de kloon dus niet zichzelf op? (wat overigens overbodig zou zijn)
Met andere woorden doet de kloon niet precies het zelfde als zijn parent, in een oneindige while lus nieuwe kloontjes forken?
Exponentieel zou ik zeggen dus.


Hmmm wacht, een goed punt wel :P

* Wilke slaat zichzelf |:(

Had niet op de while-lus gelet 8)7

Maar inderdaad, dan is het wel een heel ranzige forkbom. Toch moet een OS daar mee om kunnen gaan! Ik wil wedden dat FreeBSD niet crasht, en dat ook Linux met zo'n patch als ik hierboven noem (Odysseus, dat bedoel ik inderdaad! Dat zit er toch nog niet standaard in of kijk ik dan gewoon niet goed?) het prima moet kunnen hebben. Alleen ga ik niet mijn universiteits-account riskeren om het uit te testen, if you don't mind :P

[ Voor 7% gewijzigd door Wilke op 22-02-2003 17:05 ]


  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 08-05 19:35

BoAC

Memento mori

odysseus schreef op 22 februari 2003 @ 16:38:

[...]

Het probleem is juist dat in zo'n geval de kernel zou moeten ingrijpen door processen af te gaan schieten - de 'OOM-killer'. Dat gebeurt in Beelzebubu's geval dus niet, en de vraag is waarom niet :).
Wat nu als fork telkens failed. Dan wordt er dus telkens alleen weer een nieuw programma gestart met while(1) zonder dat er ook geheugen wordt gealloceerd.
Hierdoor gaat dus gewoon het systeem 'hangen'.

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

BoAC schreef op 22 februari 2003 @ 17:17:
Wat nu als fork telkens failed. Dan wordt er dus telkens alleen weer een nieuw programma gestart met while(1) zonder dat er ook geheugen wordt gealloceerd.
Hierdoor gaat dus gewoon het systeem 'hangen'.

Fork werkt niet meer op het moment dat er geen geheugen meer is. Op dat moment zou dus, onafhankelijk van het verdere gedrag van fork(), de OOM-killer aan de gang moeten gaan. Het is dan alleen de vraag of die sneller processen kan afsluiten dan ze met fork() worden aangemaakt...daar zou wel een probleem kunnen liggen :).
Wilke schreef op 22 februari 2003 @ 17:05:
(Odysseus, dat bedoel ik inderdaad! Dat zit er toch nog niet standaard in of kijk ik dan gewoon niet goed?)
Debian levert het in libpam-modules...van andere distributies weet ik het niet. Aangezien libpam-modules in de Required-afdeling zit, heeft elke Debian-installatie die limits.conf. Standaard wordt het aantal processen overigens niet begrensd, voor zover ik weet. Wel kwam ik er op een gegeven moment achter dat de bestandsgrootte voor normale gebruikers wel was gelimiteerd...ik maar proberen om een groot bestand aan te maken en het ding wilde maar niet boven de 100MB komen :7.

[ Voor 36% gewijzigd door odysseus op 22-02-2003 17:27 . Reden: om antwoord op Wilke te geven. ]

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 1.0.9                            File: /etc/limits                                         

# /etc/limits contains user resource limits.
# See limits(5).
#
# Format:
# <username> <limits-string>
#
# default entry is '*' for username
#
# Valid flags are:
# A: max address space (KB)
# C: max core file size (KB)
# D: max data size (KB)
# F: maximum filesize (KB)
# M: max locked-in-memory address space (KB) [only for root on Linux 2.0.x]
# N: max number of open files
# R: max resident set size (KB) [no effect on Linux 2.0.x]
# S: max stack size (KB)
# T: max CPU time (MIN)
# U: max number of processes
# L: max number of logins for this user
#
# Examples:
# the default entry
#* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0
# another way of suspending a user login
#guest   L0
# this account has no limits
#sysadm  -
* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0


Ik ga je code nu even uitvoeren, en zien wat het zegt :)

// Update

Excuses, mijn PAM werkt niet en ik heb geen zin/tijd om dat configureren. (Aangezien ik het ook niet nodig heb.). Als iemand zich geroepen voelt om z'n PAM in orde te bregen, en het te testen zou dat fijn zijn.

Mocht met PAM support je bak ook crashen op de (eeuwenoude) forkbom van BBBtje, dan is dat een bug in Pam en niet de kernel.

Natuurlijk schijft een ervaren progger als BBB wel snel ff een kernelpatch die limietensupport toevoegt. Alhoewel ik denk dat het eigelijk userspace werk is.

[ Voor 23% gewijzigd door XTerm op 22-02-2003 17:50 ]


Verwijderd

Helaas voor alle freebsd piepels, 5.0-RELEASE ging na +/- 5 minuten op z'n bek. Binnen een paar seconden was de hele ui bevroren, numlock had een latency van zo'n 40/50 secs, verder deed ie 3 x niks. (al was ie nog wel pingbaar)

[ Voor 55% gewijzigd door Verwijderd op 22-02-2003 18:13 ]


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

XTerm schreef op 22 februari 2003 @ 17:41:
code:
1
2
[i]bla[/i]
* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0


Ik ga je code nu even uitvoeren, en zien wat het zegt :)

Is dat een BSD-style limits.conf? De mijne volgt een ander formaat, lijkt het:
code:
1
<domain>      <type>  <item>         <value>

[ Voor 3% gewijzigd door odysseus op 22-02-2003 17:45 . Reden: beroerde nohtml-tag... ]

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • Thijsch
  • Registratie: Februari 2002
  • Laatst online: 01-01 18:43
Ik denk dat er geen OOM optreedt omdat dat ook "berekend" moet worden, er moet worden gekeken wat veel mem gebruikt. die exponentiele forkbomb neemt heel vaal CPU in beslag waardoor de kernel geen tijd cq. kracht heeft om te beseffen dat het schadelijk is.

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

ParaDot schreef op 22 February 2003 @ 18:11:
Ik denk dat er geen OOM optreedt omdat dat ook "berekend" moet worden, er moet worden gekeken wat veel mem gebruikt. die exponentiele forkbomb neemt heel vaal CPU in beslag waardoor de kernel geen tijd cq. kracht heeft om te beseffen dat het schadelijk is.

Daarom vroeg ik Beelzebubu ook om eens een keer een sleep() in de code te zetten...misschien dat het dan wel werkt om die processen te killen. Weet er iemand hoe de OOM-killer precies werkt?
• malloc() => minder dan x MB over => OOM-killer inschakelen
• fork() werkt niet meer door geheugengebrek => OOM inschakelen
• anders

* odysseus weet wel dat er in vroege 2.4-kernels problemen waren met de OOM-killer (en 2.2.19 had geloof ik ook wat), maar die draait de topicstarter als het goed is niet meer...geen idee hoe 2.5-kernels hier mee omgaan.

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • jep
  • Registratie: November 2000
  • Laatst online: 05-05 11:28

jep

Is het geen goed plan de bovenstaande code iets te wijzigen? :)

Ik ga 't zo wel even proberen op een bak met goede ulimits :).

offtopic:
In verband met jep's klantjes op GoT, met niet altijd hele lieve bedoelingen

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

jep schreef op 22 February 2003 @ 18:20:
Is het geen goed plan de bovenstaande code iets te wijzigen? :)

offtopic:
In verband met jep's klantjes op GoT, met niet altijd hele lieve bedoelingen

[google=fork bomb code linux]
'Resultaten 1 - 10 van circa 4,160.' => Elke idioot kan zo'n programma van het net plukken of zelf schrijven...er zijn zelfs oudere topics op GoT waarin de code voor forkbombs staat :).

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 13:24

deadinspace

The what goes where now?

Verwijderd schreef op 22 February 2003 @ 14:50:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
int
main (int   argc,
      char *argv[])
{
  while (1) {
    if (fork()) {
      malloc(1<<20);
    } else {
      execvp(argv[0], argv);
    }
  }
  return 0;
}
Achja, klassieke forkbomb. Ik heb nog geen OS gezien dat dat standaard een beetje fatsoenlijk overleeft.
Ik heb daar ooit mee geexperimenteerd... Verschillende taktieken bedacht en geprobeerd enzo. Vooral deze was gemeen (zo snel even uit mijn hoofd):
C:
1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>

int main( int argc, char **argv )
{
  for(;;)
  {
    fork();
    malloc( 4096 );
  }
}

Expontentiele process-groei, elk process (zowel child als parent) malloc()t, dus geen makkelijk doelwit voor een OOM-killer, en malloc()en gebeurt met kleine stappen, dus je geheugen zit helemaal vol (ipv dat er mogelijk iets minder dan een MB overblijft).

Waarom elk OS hier zo gevoelig voor is en er weinig aan gedaan wordt? Geen id.

Wel leuk om weer eens mee te spelen, maar ik heb atm geen computer over die dood mag. Ik wilde het ook even op mijn HPPA workstation met HP-UX proberen, maar de compiler die bij dat ding geleverd is vreet geen ANSI C :{
Wilke schreef op 22 februari 2003 @ 16:22:
Dan lees je het niet goed. Een int is sowieso 32 bits op elke machine behalve zwaar antieke zooi (of misschien is het 64 op hele nieuwe), maar op x86-machines is hij zeker 32 bit.
De lengte van een int verschilt niet alleen per platform, maar ook per OS. Windows heeft bijvoorbeeld 16 bit ints. Als je minstens 32 bit wil, gebruik dan een long int.

Niet dat het er toe doet, want het is een constante expressie. De compiler cast dit automatisch naar het argumenttype dat malloc() mee hoort te krijgen (een size_t, die altijd groot genoeg hoort te zijn om het gehele lineair adresseerbare geheugen te adresseren).
Btw. als het forken niet lukt krijg je ipv. een processID of 0 een (negatieve) foutcode terug, namelijk:
Nee, fork() returnt -1 als het niet lukt, net als alle andere POSIX systemcalls. De errorcode wordt opgeslagen in de globale variabele errno.
Wilke schreef op 22 February 2003 @ 17:05:
...en dat ook Linux met zo'n patch als ik hierboven noem (Odysseus, dat bedoel ik inderdaad! Dat zit er toch nog niet standaard in of kijk ik dan gewoon niet goed?)
Limieten op aantal processes en hoeveelheid geheugen (en ook CPU tijd btw) zitten echt al een kleine eeuwigheid in Linux (zeker sinds 2.2). PAM is de bekendste manier om hiervan gebruik te maken (alleen doet geen hond het).
odysseus schreef op 22 February 2003 @ 17:22:
Standaard wordt het aantal processen overigens niet begrensd, voor zover ik weet.
Jawel, maar op een andere manier. Linux 2.2 heeft op x86 sowieso een harde limiet van 8192 processes. In Linux 2.4 geldt een system-wide maximum (zie /proc/sys/kernel/threads-max). Als ik me goed herinner kan geen enkele user meer dan de helft van dat maximum gebruiken.

[ Voor 6% gewijzigd door deadinspace op 22-02-2003 18:50 ]


  • jep
  • Registratie: November 2000
  • Laatst online: 05-05 11:28

jep

odysseus schreef op 22 February 2003 @ 18:29:

[...]

[google=fork bomb code linux]
'Resultaten 1 - 10 van circa 4,160.' => Elke idioot kan zo'n programma van het net plukken of zelf schrijven...er zijn zelfs oudere topics op GoT waarin de code voor forkbombs staat :).
Ja, maar die van beelzebubu zijn altijd extra hardnekking :+.
offtopic:
Nee, je hebt gelijk inderdaad.

[ Voor 4% gewijzigd door jep op 22-02-2003 19:05 ]


  • MadCow*
  • Registratie: Januari 2001
  • Laatst online: 05-08-2025

MadCow*

<= icon space for rent

ik heb dat progje van deadinspace gedraaid op een FreeBSD 5.0-current bak van 16 feb.
resultaat: loop giganties vast (load van 56 in top toen ie "bevroor".
Nu nog iemand die 4.X kan testen :) /me heeft alleen 5.X bakjes.

[ Voor 15% gewijzigd door MadCow* op 22-02-2003 20:27 ]

Veni, Vidi, Et je n'en crois pas mes yeux! (ik kwam, ik zag, en ik geloofde mijn ogen niet!) - J. Caesar (Asterix en de gladiatoren) | Nu vernieuwd met toegevoegde lazyness.


  • serkoon
  • Registratie: April 2000
  • Niet online

serkoon

mekker.

Dit gaat elke bak down brengen. Default FreeBSD kan zo'n 1000 processen tegelijkertijd aan. Als er zo'n 1000 processen allemaal 100% van de CPU willen, geen wonder dat je top/sh/whatever procesje geen CPU tijd meer krijgt.

Als je die eerst reniced naar -20, zou je wellicht nog iets meer ermee kunnen :)

Ik heb ooit een perl forkbom gedraaid, kwam toen tot een load van een dikke 600 ofzo. Duurde een paar uur voordat m'n ctrl-c aankwam bij het proces waarna de hele zooi afgeschoten werd :)

Verwijderd

Even de knuppel in het hoenderhok gooien (lees: devjes pesten) >:)

Waarom kunnen de heren hier het niet eens worden over zo'n, ogenschijnlijk eenvoudig stukje code :P

P.s. ik ben zelf geen echte programmeur hoor. Ik kan lekker scripten in Bash enzo maar dan houdt het ook wel op O-)

[ Voor 4% gewijzigd door Verwijderd op 22-02-2003 20:34 ]


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 19:42

odysseus

Debian GNU/Linux Sid

Verwijderd schreef op 22 February 2003 @ 20:33:
Even de knuppel in het hoenderhok gooien (lees: devjes pesten) >:)

Waarom kunnen de heren hier het niet eens worden over zo'n, ogenschijnlijk eenvoudig stukje code :P

P.s. ik ben zelf geen echte programmeur hoor. Ik kan lekker scripten in Bash enzo maar dan houdt het ook wel op O-)

Volgens mij is iedereen het wel eens over de werking van de code ondertussen :). Het gaat er alleen om waarom deze code zijn werk mag doen: een goed besturingssysteem zou dit programma namelijk moeten afsluiten zodra het goed en wel begint te draaien...

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Verwijderd

Draai dit eens onder Windows NT/2000 >:) >:) >:) >:) >:) :D

[ Voor 29% gewijzigd door Verwijderd op 22-02-2003 20:54 ]


  • serkoon
  • Registratie: April 2000
  • Niet online

serkoon

mekker.

odysseus schreef op 22 February 2003 @ 20:36:

[...]

Volgens mij is iedereen het wel eens over de werking van de code ondertussen :). Het gaat er alleen om waarom deze code zijn werk mag doen: een goed besturingssysteem zou dit programma namelijk moeten afsluiten zodra het goed en wel begint te draaien...
Dit programma is na 2 seconden 1000 programma's, daar ligt het hele probleem. Daar zou natuurlijk ook wel een oplossing voor bedacht kunnen worden, maar dat kost weer extra boekhouding...

Verwijderd

Verwijderd schreef op 22 February 2003 @ 20:54:
Draai dit eens onder Windows NT/2000 >:) >:) >:) >:) >:) :D
was het niet zo dat windows niet eens KAN forken ?

  • serkoon
  • Registratie: April 2000
  • Niet online

serkoon

mekker.

Verwijderd schreef op 22 februari 2003 @ 20:58:
[...]


was het niet zo dat windows niet eens KAN forken ?
Windows kent geen fork() inderdaad. Je zou natuurlijk wel een programma kunnen schrijven wat zichzelf constant uitvoert, als nieuw proces dus. Dan heb je eigenlijk het zelfde effect :)

  • deadinspace
  • Registratie: Juni 2001
  • Laatst online: 13:24

deadinspace

The what goes where now?

serkoon schreef op 22 February 2003 @ 20:33:
Als er zo'n 1000 processen allemaal 100% van de CPU willen, geen wonder dat je top/sh/whatever procesje geen CPU tijd meer krijgt.
CPU starvation is het probleem niet. Als je nog maar 0.1% van de normale CPU tijd tot je beschikking hebt (dat zou het geval zijn met 1000 processes) dan kun je nog steeds die meuk killen, het duurt alleen lang.

Deze forkbombs richten zich op veel interessantere resources: geheugen en aantal processes. Vooral het geheugen heeft een grote invloed.
C:
1
2
3
4
5
6
7
#include <stdlib.h>

int main( int argc, char **argv )
{
  for(;;)
    malloc( 1024 );
}

Dit programmaatje vraagt constant geheugen aan. Het gevolg is dat je geheugen volloopt, en als dat eenmaal vol is wordt er vanalles uitgeswapt. Swappen is zeer vervelend voor de interactiviteit, omdat het OS (en dus processes en dus de user) telkens moet wachten op de HD. Als een computer zo hard aan het swappen is dat hij nergens anders meer aan toekomt, dan wordt dat "trashen" genoemd. Op een gegeven moment zit ook de swap vol; er kan dan geen geheugen meer geallocceerd worden, en programma's starten dan niet meer e.d.

Dit programmaatje is niet zo'n probleem, want als het hele geheugen en swap vol zit, dan (of misschien al eerder) grijpt de OOM-killer in, en die probeert de schuldige uit te kiezen en te maaien (in dit geval is de schuldige duidelijk aan te wijzen: bovenstaand progje).

Maar bij die forkbombs gaat dat niet op.... Stel dat de OOM-killer een van de geforkte processes als schuldige aanwijst en afmaakt... Dan wordt er gewoon weer een nieuwe geforkt, en heel snel ook. Daar komt nog eens ingewikkelde protected mode gebeuren bij (een geforkte child shared zijn geheugen copy-on-write met zijn parent, als de parent sterft moet het geheugen wel aanwezig blijven voor de children bijvoorbeeld), waardoor de kernel ook het nodige aan CPU gebruikt en dat komt het geheel niet ten goede.

Bovendien kan zo'n forkbomb ook het maximum aantal processes bezetten, waardoor andere programma's opstarten heel lastig wordt.

En als ik me niet vergis hebben Windows NT, 2000 en XP wel fork() (als onderdeel van een gedeeltelijke POSIX implementatie).
Of je gebruikt CreateNewProcess() (met een half miljoen argumenten, en voorafgegaan door de gebruikelijke lijst aan win32 en messages e.d. initialisatie... Jeuj voor de win32 API :P ).

  • _JGC_
  • Registratie: Juli 2000
  • Nu online
Heb dit ook ooit gedaan met een bash script:

code:
1
2
3
4
#!/bin/bash
./a &
./a &
./a &

bestand a noemen, 755 chmodden en dan uitvoeren met ./a

Heb het 2 minuten laten lopen op een Dual P133 met 128MB geheugen... load van over de 200, kon hem met moeite killen :)

Keek ik later de syslogs door: Sendmail: too much load, suspending tasks...

Ja, toen draaide ik nog sendmail ;)

Verwijderd

edit:
blup

[ Voor 98% gewijzigd door Verwijderd op 25-02-2003 18:34 ]


Verwijderd

Topicstarter
odysseus schreef op 22 February 2003 @ 18:19:
Daarom vroeg ik Beelzebubu ook om eens een keer een sleep() in de code te zetten...misschien dat het dan wel werkt om die processen te killen.
Het is een scheduled proces (het runt gewoon als user, niet als root, en krijgt geen hoge priority). Waar ik me dus over verbaas is het feit dat deze serie processen uberhaupt nog gescheduled worden. Ik zou verwachten dat OOM, zodra hij merkt dat 't fout gaat, steeds een proces afschiet, nog voordat deze een child kan creeren. De kernel is namelijk in alles boven dit programma, dus dit programma runt slechts bij gratie van de kernel scheduler. Ik zou dus verwachten dat - omdat de CPU/mem volloopt - er constant een child wordt afgeschoten en dat er dus een random vast aantal processen steeds openblijven (en zodra er een nieuw proces komt, is de mem load weer te hoog en wordt er weer een aantal tegelijk afgeschoten om weer op normaal niveau te komen).

Het kan natuurlijk zijn dat dit ook werkelijk gebeurd maar dat er zoveel processen zijn dat ze de CPU alsnog innemen en dat daarom geen UI/net response is. Dat zou ik vreemd vinden, want daarmee los je het probleem niet op ondanks dat je het wel erkent. Ik kreeg in elk geval geen antwoord meer van die bak. :P. Ik zal serkoon's tip eens proberen...
Weet er iemand hoe de OOM-killer precies werkt?
• malloc() => minder dan x MB over => OOM-killer inschakelen
• fork() werkt niet meer door geheugengebrek => OOM inschakelen
• anders
[/quote]

Geeeeeeeeen idee... Moet ik me eens in verdiepen.
* odysseus weet wel dat er in vroege 2.4-kernels problemen waren met de OOM-killer (en 2.2.19 had geloof ik ook wat), maar die draait de topicstarter als het goed is niet meer...geen idee hoe 2.5-kernels hier mee omgaan.
Ik draai 2.4.20. De OOM problemen hadden met de VM problemen te doen, die zijn al lang niet meer van toepassing hierop.

  • LollieStick
  • Registratie: Juni 2001
  • Laatst online: 28-02 12:09
deadinspace schreef op 22 February 2003 @ 18:49:

[...]

Limieten op aantal processes en hoeveelheid geheugen (en ook CPU tijd btw) zitten echt al een kleine eeuwigheid in Linux (zeker sinds 2.2). PAM is de bekendste manier om hiervan gebruik te maken (alleen doet geen hond het).

[...]
De eerste hond die vrijwillig achter een pc kruipt moet ik nog tegen komen :p ;)

  • Redlum
  • Registratie: Maart 2000
  • Laatst online: 31-03 10:48
Verwijderd schreef op 22 February 2003 @ 22:05:
Hmm, ik heb net 'per ongeluk' een shell server laten crashen hierdoor, ook al hadden ze hun resources afgeschermd met limits.
code:
1
2
3
4
5
6
7
8
9
10
11
core file size        (blocks, -c) 0
data seg size         (kbytes, -d) 16000
file size             (blocks, -f) 2097151
max locked memory     (kbytes, -l) 2097151
max memory size       (kbytes, -m) 16000
open files                    (-n) 128
pipe size          (512 bytes, -p) 8
stack size            (kbytes, -s) 8000
cpu time             (seconds, -t) 2147483647
max user processes            (-u) 24
virtual memory        (kbytes, -v) 2097151

Is dit normaal?
Ik kreeg namelijk een boos telefoontje dat ze de server hadden moeten rebooten :o
Die cpu time noem ik niet echt een limit :+ Welke shellserver is dit?
Daarnaast is dit soort dingen 'proberen' op productie machines natuurlijk een no-go, zeker als ze niet van jou zijn ;).

Verwijderd

Topicstarter
Ik heb het Sepans naar de betaalde support van RedHat laten sturen, benieuwd naar reacties. :).

  • Hmzaniac
  • Registratie: Januari 2002
  • Laatst online: 05-08-2023

Hmzaniac

Evil Admin

Om dit soort dingen te voorkomen, kijk eens naar /etc/limits.conf en gebruik eens de GrSecurity kernel patches. Ik heb dit zelf draaien, en het helpt erg goed tegen fork bombs, chroot breaking, en meer van dergelijke dingen.

Ik heb een WOS-post!


Verwijderd

GrimLord schreef op 24 February 2003 @ 02:11:
[...]
Die cpu time noem ik niet echt een limit :+ Welke shellserver is dit?
Daarnaast is dit soort dingen 'proberen' op productie machines natuurlijk een no-go, zeker als ze niet van jou zijn ;).
Ik denk dat dat picard.cistron.nl was.
Dit stond afgelopen zaterdagavond in cistron.general

<inofficiele announcement>

picard.cistron.nl (de shellserver) was gecrashed, en staat nu te
rebooten. 't ding zou met een beetje geluk zo weer up moeten zijn.

</inofficiele announcement>

[ Voor 4% gewijzigd door Verwijderd op 25-02-2003 01:31 ]


  • Ronald
  • Registratie: Juli 2000
  • Laatst online: 00:27
Nou dit is heel interessant...

Zit hier op Redhat Phoebe (8.1 beta 3) en die heeft in plaats van linuxthreads NPTL (en ik maar denken dat je daar glibc-cvs-HEAD en kernel 2.5.49+ voor nodig had :P)

Heb bommetje zoals BBB in eerste post geeft gecompiled en op de console (buiten X!) gerunt. Load knalde knetterent hard naar de 800 en hoger, MAAR console switches bleven redelijk werken. Na een tijdje kwam de OOM killer langs en die probeerde gedurende enige tijd procesjes af te knallen (steeds zelfde PID, schijnbaar zonder veel succes...) Ik ben terug gezapt naar de console waar ik de bom gestart had en kon hem gewoon van een control-C voorzien waarna hij keurig exitte en systeem weer prima werkte.

PV Output - Obdam; SolarEdge SE5K 'Voor korte strings'; 12x350Wp Oost-West 13°; 8x415Wp Zuid 10°; Totaal 7520Wp.


  • Paultje3181
  • Registratie: November 2002
  • Laatst online: 21:09
Het is een scheduled proces (het runt gewoon als user, niet als root, en krijgt geen hoge priority). Waar ik me dus over verbaas is het feit dat deze serie processen uberhaupt nog gescheduled worden. Ik zou verwachten dat OOM, zodra hij merkt dat 't fout gaat, steeds een proces afschiet, nog voordat deze een child kan creeren. De kernel is namelijk in alles boven dit programma, dus dit programma runt slechts bij gratie van de kernel scheduler. Ik zou dus verwachten dat - omdat de CPU/mem volloopt - er constant een child wordt afgeschoten en dat er dus een random vast aantal processen steeds openblijven (en zodra er een nieuw proces komt, is de mem load weer te hoog en wordt er weer een aantal tegelijk afgeschoten om weer op normaal niveau te komen).
Is het niet zo dat als je dit runt OOM-killer een tijdje wacht voordat ie door heeft dat het problematisch wordt, maar doordat het exponentieel is er 1 gekilled wordt en de rest door blijft gaan? M.a.w. het gaat langzamer, maar wel door?
Ik heb er totaal geeeeeeeeeeen verstand van (newbie) maar logisch redeneren lijkt me dat het zo gaat. lineair kan namelijk nooit op tegen een exponentieel verloop. En OOM-killer lijkt lineair als ik het zo hoor.

Verwijderd

Topicstarter
Paultje3181 schreef op 25 februari 2003 @ 15:02:
Is het niet zo dat als je dit runt OOM-killer een tijdje wacht voordat ie door heeft dat het problematisch wordt, maar doordat het exponentieel is er 1 gekilled wordt en de rest door blijft gaan? M.a.w. het gaat langzamer, maar wel door?
Ik heb er totaal geeeeeeeeeeen verstand van (newbie) maar logisch redeneren lijkt me dat het zo gaat. lineair kan namelijk nooit op tegen een exponentieel verloop. En OOM-killer lijkt lineair als ik het zo hoor.
Je vergeet dat de OOM in kernelspace werkt en dus boven userspace processen staat.

Zoals RonaldH net op NPTL testte, zo zou ik het dus verwachten. M.a.w.: leve NPTL!

offtopic:
Hoe kom ik bij NLPT? 8)7.

[ Voor 5% gewijzigd door Verwijderd op 25-02-2003 15:35 ]


Verwijderd

http://rexgrep.tripod.com/rexfbd.htm

Tada... Krijg alleen wat errors bij het compileren:( Forkbomb protectie...

Verwijderd

Verwijderd schreef op 05 March 2003 @ 19:01:
http://rexgrep.tripod.com/rexfbd.htm

Tada... Krijg alleen wat errors bij het compileren:( Forkbomb protectie...
Als je FreeBSD gebruikt kun je ook login.conf gebruiken om limits in te stellen. Ik heb daar net een beetje mee zitten spelen en het werkt goed. De forkbomb draait nu al een paar minuten en er is bijna niks van te merken

de cpu is zelfs 92.0% idle

---------------------------------------

Ik dacht dat er een cpulimit actief was, maar dat blijkt niet zo te zijn voor de user waarmee ik heb getest

$ /usr/bin/limits | grep cputime
Resource limits (current):
cputime infinity secs

Waarom deze bak dan niet onderuit gaat en al die andere uit deze thread wel begrijp ik niet. Ik heb een file executable gemaakt en vanuit die file de bomd 10 keer laten starten. Ook dat is voor het systeem geen probleem. Het enige dat erg hoog wordt is de load. Die ging een keer over de 200!
Het werd er allemaal niet merkbaar langzamer van. Internet ging nog met dezelfde snelheid. De SSH sessie ging nog net zo snel als altijd.

De specs zijn :
OS : FreeBSD 4.7-RELEASE-p3
CPU : PII 350MHz
RAM : 384 MB
Swap : 300 MB

[ Voor 49% gewijzigd door Verwijderd op 05-03-2003 19:31 ]


  • Martin Sturm
  • Registratie: December 1999
  • Laatst online: 30-04 16:11
RonaldH schreef op 25 februari 2003 @ 14:43:
Nou dit is heel interessant...

Zit hier op Redhat Phoebe (8.1 beta 3) en die heeft in plaats van linuxthreads NPTL (en ik maar denken dat je daar glibc-cvs-HEAD en kernel 2.5.49+ voor nodig had :P)

Heb bommetje zoals BBB in eerste post geeft gecompiled en op de console (buiten X!) gerunt. Load knalde knetterent hard naar de 800 en hoger, MAAR console switches bleven redelijk werken. Na een tijdje kwam de OOM killer langs en die probeerde gedurende enige tijd procesjes af te knallen (steeds zelfde PID, schijnbaar zonder veel succes...) Ik ben terug gezapt naar de console waar ik de bom gestart had en kon hem gewoon van een control-C voorzien waarna hij keurig exitte en systeem weer prima werkte.

fork() maakt nieuwe processen, geen threads als ik me niet vergis :P... Zou het niet gewoon kunnen dat de 2.5.49+ kernels er beter tegen kunnen.

Verwijderd

Kan iemand mij uitleggen hoe ik dat doe met pam en zo, of is d'r een degelijke howto? Want die module is nou niet echt super.. Krijg errors:( Met compileren...

[ Voor 9% gewijzigd door Verwijderd op 05-03-2003 21:47 ]

Pagina: 1