I spend most of my day coding in some variation of C for small systems (mobiles, IoT, etc). From time to time I come across some funny things that makes you go WOAH.

One of the funny things to do is to find so-called bombs – ways of getting something small to take up ALOT of space.

Lets dig right into my latest simple finding:

const int main[255<21] = {195};

this is only a few bytes of code, but will compile into a 2gb file using simple gcc compiler.

So what really happens?  A few tricks are used here:

  • const is there to remove the write flag from the pages in the segment. This makes it possible to execute main
  • The number¬† “195” in the array is the machine code (Intel) for a return so basically the array is filled with return.

So basically it abuses that this is on Intel(x86) architecture which is little-endian. Here the “return” is the first byte so basically the program just exits with whatever return value it finds in the eax register (most of the time this would be 0). This ends up being around 2gb when compiled and is the maximum you can do without having to tell gcc that you will be working with large chunks of memory. If that is not relevant for you and you have more than enough memory, then you can easily extend it to compile into 16gb binary.

const int main[-1u] = {195};

here we tell it to have the maximum size of an unsigned int (-1u). in order to compile this you will need around 20gb memory for the linker + 16gb free disk space. Compile it like

gcc -mcmodel=medium -o bomb test.c

The outcome of all of this could differ from compiler to compiler, so the exercise for the reader today could be to try this out in clang, visual c++ arm-gcc etc. and see if the outcome differ.

Have fun.