forkbomb.c (3063B)
1 // $Id$ 2 3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> 4 // based on tests/forkbomb.cc by Jacques Gelinas 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2, or (at your option) 9 // any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 #include <stdlib.h> 21 #include <errno.h> 22 #include <string.h> 23 #include <sys/types.h> 24 #include <sys/wait.h> 25 #include <unistd.h> 26 #include <stdio.h> 27 28 typedef enum {MODE_SLEEP,MODE_LOOP,MODE_FORK, MODE_FORKSHELL} MODE; 29 30 31 static void forkbomb_userfork (MODE mode) 32 { 33 pid_t pid = fork(); 34 if (pid==-1){ 35 fprintf (stderr,"Fork failed (%s)\n",strerror(errno)); 36 }else if (pid == 0){ 37 if (mode == MODE_SLEEP){ 38 sleep(20); 39 }else if (mode == MODE_LOOP){ 40 int k=0; 41 while (1) k++; 42 }else if (mode == MODE_FORKSHELL){ 43 system ("/bin/false"); 44 } 45 _exit (0); 46 } 47 } 48 49 50 int main (int argc, char *argv[]) 51 { 52 if (argc != 4){ 53 fprintf (stderr,"formboom N M mode\n" 54 "where N is the number of process to start\n" 55 "and M is the number of user to start\n" 56 "Each user will try to start N process\n" 57 "\n" 58 "mode is:\n" 59 " sleep: Each process sleeps for 20 seconds and exits\n" 60 " loop: Each process loops forever\n" 61 " fork: Each process exits immediatly and is restarted\n" 62 " by the parent\n" 63 " forkshell: Each process runs /bin/false in a shell and\n" 64 " exits, then the parent start a new one\n" 65 ); 66 }else{ 67 MODE mode; 68 int i; 69 if (strcmp(argv[3],"sleep")==0){ 70 mode = MODE_SLEEP; 71 }else if (strcmp(argv[3],"loop")==0){ 72 mode = MODE_LOOP; 73 }else if (strcmp(argv[3],"fork")==0){ 74 mode = MODE_FORK; 75 }else if (strcmp(argv[3],"forkshell")==0){ 76 mode = MODE_FORKSHELL; 77 }else{ 78 fprintf (stderr,"Invalid mode\n"); 79 exit (-1); 80 } 81 for (i=0; i<atoi(argv[2]); i++){ 82 if (fork()==0){ 83 if (setuid (i+1)==-1){ 84 fprintf (stderr,"Can't setuid to uid %d (%s)\n",i+1 85 ,strerror(errno)); 86 }else{ 87 int j; 88 for (j=0; j<atoi(argv[1]); j++){ 89 forkbomb_userfork (mode); 90 } 91 if (mode == MODE_FORK || mode == MODE_FORKSHELL){ 92 // Ok, all processes are started, in MODE_FORK 93 // we create a new one all the time 94 int status; 95 while (wait(&status)!=-1) forkbomb_userfork(mode); 96 } 97 } 98 _exit (0); 99 } 100 } 101 system ("ps ax | wc -l"); 102 printf ("All the process are running now\n"); 103 printf ("Exit to end all processes\n"); 104 system ("/bin/sh"); 105 system ("killall forkbomb"); 106 } 107 return 0; 108 } 109