views:

386

answers:

5

Lets us consider the following program :

#include <stdlib.h>

int main(int argc, char **argv){
   int a,b;

   if (argc != 3)
       return -1;

   a = atoi(argv[1]);
   b = atoi(argv[2]);

   a = b ? a/b : 0;

   return a;
}

The task is to crash the program by providing arguments in command-line.

+16  A: 

Pass a as the platform's INT_MIN and b as -1. Then you get an overflow error on any two's complement machine, although that's not necessarily a crash.

Potatoswatter
I'm surprised to see this issue in an interview that is not meant for security experts. But admittedly, I use Java and Python where this isn't much of an issue.
Uri
+5  A: 

The answer to this question is: It depends.

One of the critical pieces of information you need to know is how atoi is implemented and if it's standards compliant. The standard says very little about implementation details and is more specific on the input output behavior. Lets assume for a minute it's indeed standards compliant and focus on the implementation.

There are several methods which can be validly used and one of them is recursively. Lets assume for a second that it's implemented as a head recursive algorithm which forces a build up of stack. I could then cause this program to crash by providing a long enough argument that it forced atoi to recurse deep enough to stack overflow and hence crash the application.

JaredPar
+2  A: 

You could work backwards via a process of elimination:

1) Can you end up with a division by zero? Not likely. If b is 0, the last expression is 0, and if it is not 0, you would not get a divide by zero.

2) Can you provide an incorrect number of arguments and crash on the array access? Not really because of the earlier argc check

3) If your arguments don't translate to a number, atoi should return a numeric value. I think this is part of the library specification and thus not open to implementation variation but I could be wrong.

So I don't see how you would crash here.

The only thing I like about this question is the division by zero part - it checks that you understand the ?: operator and that 0 is a false. I dislike the atoi part without giving you access to a reference manual. I had to check the docs to be sure.

The potential for an underflow/overflow is too tricky IMHO. It's great if you are interviewing for a software security engineer, but I would not ask an entry level candidate or even just for a standard programming job. If you come from other languages (e.g., Python), it is particularly difficult.

Update: I did an online search on several references and it seems that atoi should return 0 on bad input. For example, from MSDN:

Each function returns the int value produced by interpreting the input characters as a number. The return value is 0 for atoi and _wtoi, if the input cannot be converted to a value of that type.

Uri
re: 3) no. Passing something to atoi that cannot be converted to an int is not required to return a numeric value. It invokes undefined behavior. An implementation is free to crash your program, burn your harddrive if you do so.
nos
@nos: Is that the case? I checked Wikipedia and MSDN and it seems to indicate otherwise: "Each function returns the int value produced by interpreting the input characters as a number. The return value is 0 for atoi and _wtoi, if the input cannot be converted to a value of that type."
Uri
It's the case according to the C standard, yes. "[1] The functions atof, atoi, atol, and atoll need not affect the value of the integer expression errno on an error. If the value of the result cannot be represented, the behavior is undefined."
nos
@nos: you should submit that as an answer - the behavior of `atoi()` is just as undefined (in Standard C) as the integer overflow operation. And it's a whole lot easier to pass in something that `atoi()` can't handle than it is to type in whatever `INT_MIN` is...
Michael Burr
This makes me appreciate Java - there's only one "official vendor"
Uri
A: 

The only possible weakness I am seeing is atoi(). Perhaps if it were passed a large enough string, it would misbehave in some way internal to it. Beyond that, divide by 0 is covered as is argument count. The only other thing I can think of is somehow overflowing the operating systems buffers by spamming garbage into the arguments. Not too likely.

Michael Dorgan
A: 

I don't know how most OS's pass the argv data. Is it allocated on the stack? Is it inherently limited in length?

Could you pass a really long command-line parameter and create a stack-overflow?

abelenky