views:

126

answers:

3

Hi,

I have this line of code (splits is an instance variable):

splits = [[NSMutableArray alloc] initWithObjects:[NSMutableArray array]];

This code is obviously wrong (it should be nil-terminated), however it runs fine in the simulator, even though it throws an EXC_BAD_ACCESS on the device. My question is why does the simulator not throw an error?

Kyle

A: 

Buffer overflows result in undefined behavior. They are not guaranteed to cause an access violation (or even a noticeable bug). On modern machines, they will cause an access violation if you happen to step on "someone else's" memory, but probably not if you're just reading junk from your own stack.

Basically, you just need to be careful, and can try tools like Mudflap and Valgrind to help you out (these particular two are more meant for C/C++, and I don't know how well they apply to Obj-C).

Matthew Flaschen
I guess this is not exactly buffer overflow – the va_arg macro responsible for taking the arguments simply walks past the last argument without overwriting anything.
zoul
I would still consider it a buffer overflow. It's just that a /read/ is overflowing the end of the buffer, not a /write/. If you want to be technical, it's CWE-126, buffer over-read (cwe.mitre.org/data/definitions/126.html) or CWE-125, Out-of-bounds Read (http://cwe.mitre.org/data/definitions/125.html).
Matthew Flaschen
+1  A: 

The iPhone has much less memory than your computer. The area in memory for the stack could have been set to 0x00 (nil) before being used by the initWithObjects function. When the parameters are sent to the initWithObjects function and the stack is alloated, that memory space on the computer is more likely to be preset to 0x00 than the iPhone because the same memory space is used less often. So it is likely that the nil is being read from a spot in memory set to 0 already.

If you fill up your memory on your computer, and then run the simulator, the simulator may be more likely to crash like the iPhone.

Robert
The computer will clean used memory, before it passes the memory to a process such as the simulator ... if a process requests memory from the O/S, and the O/S doesn't clean the memory before passing it to the requesting process, that would be a security/privacy risk.
ChrisW
+4  A: 

The actual outcome depends on the memory contents. It is quite possible that the memory layout on the simulator contains a zero right after the address of the first parameter (the anonymous array). This zero gets interpreted as if you would close the argument list with nil and everything works fine. (P.S. There is an interesting macro called NS_REQUIRES_NIL_TERMINATION for such cases, although it obviously would not help here.)

zoul