Fernando J. Pereda’s blag

August 24, 2008

Security Trivia IV

Filed under: blag — Tags: , — Fernando J. Pereda @ 2:02 pm

This one is easy and sweet. Your goal is to make this program crash and explain why that happened, good luck:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
	if (argc != 4) {
		fprintf(stderr, "DIAF\n");
		return EXIT_FAILURE;

	char c[3];
	unsigned i;
	for (i = 0; i < sizeof(c); i++)
		c[i] = atoi(argv[i + 1]);

	if (c[0] + c[1] + c[2] == 0) {
		fprintf(stderr, "No no\n");
		return EXIT_FAILURE;

	c[1] += c[0] + c[2];
	printf("%d\n", c[0]/c[1]);


Before spoling your own fun looking at the comments, try to do it yourself. Really, it is easy, and will make you understand C better.

— ferdy


  1. 127 127 2

    Comment by scaryreasoner — August 24, 2008 @ 2:42 pm

  2. That’s only half of it. It is quite easy to script that out, the real question here is “why?”.

    — ferdy

    Comment by Fernando J. Pereda — August 24, 2008 @ 2:45 pm

  3. Hum, obviously the problem comes from the checking the sum equal to zero. It seems that C doesn’t care for the type when checking the condition. If you use a temporary value, it works.
    But I’d like to know why.
    When the sum of all equals 256 and none of the number is greater than 127, it fails.
    When two are greater than 128 and one is negative, it fails, when only one is greater than 127 and one is negative, it works. There must be something with the sign bit…
    I’m waiting to see a more detailed answer…

    Comment by kopp — August 24, 2008 @ 4:07 pm

  4. Hum, sorry for double commenting. But sizeof(c[0] + c[1] + c[2]) is 4. I guess C doesn’t cast the operation to char.
    By typecasting in the if confition : if ( (char) (c[0] + c[1] + c[2]) == 0)
    It doesn’t fail.

    Is it expected behaviour from C ?

    Comment by kopp — August 24, 2008 @ 4:14 pm

  5. Ok last one (I should have thought all over the problem first, then posted :))
    The numbers are cast to char when read, if one is greater than 127 and loops around to -128 so when they are summed in the condition, the sum actually makes 0. (example 127 130 -1 -> 127 -126 -1 ) while when two of them are >127, they both become engatives and do not sum to zero.
    Last comment, for real.

    Comment by kopp — August 24, 2008 @ 4:26 pm

  6. comment #4 is on the right track. It is almost there.

    — ferdy

    Comment by Fernando J. Pereda — August 24, 2008 @ 5:01 pm

  7. Hmm, I’m not sure I really understand the one you posted. Here is another one I read a long, long time ago that has always impressed me:

    Comment by Ira Snyder — August 24, 2008 @ 5:11 pm

  8. @Ira: That’s a very nice one (no wonder it is, coming from taviso).

    — ferdy

    Comment by Fernando J. Pereda — August 24, 2008 @ 8:56 pm

  9. The arithmetic expressions cause widening conversions to occur. In the first case — the if test — since the result isn’t stored in a smaller type, no overflow occurs. In the second case, the result is assigned to a signed value of a smaller type, which causes overflow, changing the sign.

    The mistake can be avoided by user a integer type to begin with, or minimally doing the same narrowing conversion in the test by converting the result of the addition to char.

    Comment by Some guy — August 26, 2008 @ 6:51 am

  10. Exactly. Thanks.

    — ferdy

    Comment by Fernando J. Pereda — August 26, 2008 @ 9:44 am

RSS feed for comments on this post. TrackBack URI

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 )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: