How to dismantle a compiler bomb

main[-1u]={1};

You have heard of “zip bombs” (a tiny ZIP file that decompresses to multiple gigabytes) and “XML bombs” (small XML file abusing the entities to consume lots of memory), and now there is a “compiler bomb” to follow suit.  The idea is quite similar — the source code is only 14 bytes, but the generated executable will be over 16 GB in size.

Who wrote it?

The code is attributed to Stack Exchange user Digital Trauma.  It was posted here on January 12, 2016.

How does it work?

In the code main is not a function, but an array of ints.  The value of -1u, that is, negative one as unsigned, is exactly 0xFFFFFFFF — the maximum value of unsigned int.  The array will contain 4294967295 integers, each with the size of four bytes, taking up 17179869180 bytes in total.

The important element of the code is the array initialization — {1}. The first element of the array will be initialized to 1, and all the remaining elements will be set to 0.  It is necessary for the compiler to place the entire array inside the executable.  (Try removing the initialization and compiling the code by yourself.)

What is surprising is that main does not have to be a function.  You can throw just about anything called main at the compiler and it will produce a valid executable — but don’t expect much more than a segmentation fault when you run it.

Getting it to compile

The author advises to compile the code with gcc, as follows:

gcc -mcmodel=medium cbomb.c -o cbomb

Turns out 8 gigabytes of RAM is not enough — the compilation fails with an error.

cbomb.c:1:1: warning: data definition has no type or storage class
 main[-1u]={1};
 ^~~~
cbomb.c:1:1: warning: type defaults to ‘int’ in declaration of ‘main’ [-Wimplicit-int]
/usr/bin/ld: final link failed: Memory exhausted
collect2: error: ld returned 1 exit status

Let’s make a diet bomb

To consume a little bit less of the memory while still being able to play with the code, let’s try and modify it a little bit.

int main[10000]={1};

This code should produce an executable with the array having the size of 10000 integers, that is, 40000 bytes.  Let’s see this in practice!

% cc ./dietbomb.c
% wc -c a.out
48296 a.out
% ./a.out 
zsh: segmentation fault ./a.out

As you can see, the compiled binary is 48K in size and gives a beautiful segfault when ran.

An exercise for the reader

What happens when you move the array declaration to the inside of the main() function and why?

Advertisements

6 thoughts on “How to dismantle a compiler bomb

  1. Pingback: New top story on Hacker News: 14 bytes of C code that compiles to 16GB binary – Tech + Hckr News

  2. That’s the first time I’m seeing a compiler bomb and it’s quite a neat hack. Thanks for both sharing and explaining it, it’s really intriguing how the compiler works in this case.

    Like

  3. Pingback: How to dismantle a compiler bomb | Softwares Bloggers | Softwares Reviews | Best Online Softwares

  4. Pingback: How to dismantle a compiler bomb - Moon Merchant

  5. Pingback: New top story on Hacker News: How to dismantle a compiler bomb – ÇlusterAssets Inc.,

  6. this certainly used to be impossible in the past … having limits on use of the static data area is a problem I had to work around multiple times in the past, though perhaps with cl, clang or other non-gcc.

    I’m actually amazed this works … at a guess this is gcc, 64-bit and elf specific

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s