Comments on: The myth of signed arithmetic wraparound http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/ After all, it could only cost you your life, and you got that for free. Mon, 28 Jan 2013 23:45:58 +0000 hourly 1 http://wordpress.org/?v=3.8.5 By: Ryan http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4525 Wed, 15 Jun 2011 00:41:36 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4525 Hehe, Renee

]]>
By: Renee http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4524 Tue, 14 Jun 2011 04:40:21 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4524 That is *exactly* what I was thinking, Paul. Great minds, dude.

]]>
By: Paul Kuliniewicz http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4523 Tue, 14 Jun 2011 02:15:42 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4523 Interesting. On my system (x86_64), if I insert a “printf(“%p\n”,string);” right after the call to malloc, I see that malloc is returning NULL. But if I just call malloc(2147483648) directly, I get a valid pointer. This probably has something to do with the fact that on my system, sizeof(int) == 4 and sizeof(size_t) == 8.

Even though Linux overcommits memory, it still seems that it will fail on extremely large values passed to it: malloc(18446744073709551615) returns NULL (where 18446744073709551615 is the maximum value of size_t). So there is some point where Linux doesn’t even pretend to be able to satisfy the request.

Hmm, so what may be happening is that size + 1 gets treated as INT_MIN, which then gets extended to 64 bits and treated as an unsigned value, resulting in a sufficiently enormous value that Linux’s malloc can’t cope with. So in the course of trying not to allocate INT_MAX bytes, the incorrect bounds-checking actually lets it try to allocate some 230 times more memory than that.

]]>
By: Keith Thompson http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4522 Tue, 14 Jun 2011 01:45:10 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4522 “On x86 Linux, malloc returns NULL when it receives a negative argument”

Not exactly. malloc() *cannot* receive a negative argument, since its parameter is of type size_t, an unsigned type.

In the call malloc(size + 1), size is of type int, and in this case has the value INT_MAX. size + 1 is still of type int, but has an undefined value (worse than that, the program’s behavior is undefined). *If* size + 1 yields some int value, that value will be converted to size_t. Conversion to an unsigned type is well defined; it wraps around. So without optimization, malloc() is probably called with an argument of 2147483648 (of type size_t).

And in fact, on my x86 Linux system, when I remove the abort() call, malloc(2147483648)) *doesn’t* return a null pointer. This is because Linux malloc() allocates virtual memory. If I actually tried to use that memory, it wouldn’t be able to map all of it to physical memory, and the OOM killer would start shutting down processes (not necessarily the offending one).

]]>
By: Ryan http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4521 Mon, 13 Jun 2011 21:47:27 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4521 elseiffor!

]]>
By: Paul Kuliniewicz http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4520 Mon, 13 Jun 2011 09:54:05 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4520 Yes, this is a bit of a contrived example to illustrate how when a program invoked undefined behavior, the compiler is free to do whatever it wants, and as a result changing the optimization level can change the run-time behavior of the program. The example doesn’t work with the more sensible size_t, since the C standard does specify that wraparound happens with unsigned integral types.

]]>
By: Samantha Peters http://www.kuliniewicz.org/blog/archives/2011/06/11/the-myth-of-signed-arithmetic-wraparound/comment-page-1/#comment-4519 Mon, 13 Jun 2011 03:45:11 +0000 http://www.kuliniewicz.org/blog/?p=2219#comment-4519 That’s a silly example … surely the problem is in the API, which should look like this:

int process_something(int fd, size_t size)

]]>