views:

585

answers:

4

The static analysis tool we use is flagging C code similar to the following as a critical buffer overflow.

#define size 64
char  buf [size + 1] = "";
memset (buf, 0, size + 1);

The tool's error message is: Buffer Overflow (Array Index Out of Bounds): The array 'buf' size is 1. Array 'buf' may use the 0..64 index.

Is this legitimate? Does the assignment of the character array to the empty string really result in its length being reduced to a single byte, as if it were defined as char buf [] = "";?

+12  A: 

Aside from the fact that char buf[size+1] won't compile because size is a runtime value, assuming you could build buf as a size 65 array, then memset(buf, 0, 65) would not be an overflow.

Odds are your tool is confused by your syntactic issues.

[Edit: more information]

Based on comments to my original post, I suggest the following:

#define size 64
char buf[size+1];
strcpy(buf, "");
memset(buf, 0, size+1);

I believe Rob Kennedy is correct; your tool is using the empty string initializer value as the array size rather than the static array declaration.

Randolpho
C99 has dynamically sized arrays.
Logan Capaldo
Really? Well color me out of the game. Clearly I haven't done C in far too long.
Randolpho
The reason it won't compile is that you can't initialize a dynamically sized array. Dynamically sized arrays are allowed for almost 10 years now.
Rob Kennedy
That said, the tool might not realize that. It could be using the initializer to determine the array's size.
Rob Kennedy
That's a good point.
Randolpho
The call to strcpy is redundant; memset will just overwrite the (empty) string anyway.
Matthew Crumley
Flash Sheridan
A constant expression can be evaluated during translation… may be used in any place that a constant may be.… An integer constant expression* shall have integer type and shall only have operands that are integer constants,… * An integer constant expression is used to specify… the size of an array, …
Flash Sheridan
@Flash Sheridan: You're correct. However, when I wrote my answer, size was size_t, not #define. The question has been edited. Check the history. :)
Randolpho
A: 

It's legal - the buffer is big enough. The tool is warning you that size_t might be bigger than int and trying to use it as indexer may lead to unpredictable results.

sharptooth
I don't think that's what the tool is warning about. It clearly says that the array size is 1 and that indices 0 through 64 are being used. It's not complaining about sizes of integers.
Rob Kennedy
revised example to avoid future confusion with size_t.
Andrew
Well, the tool shows paranoia about the array size which is not correct. This may just be a bug in the tool - the tool's source could tell for sure.The problem with size_t however is a well known one and it hits painfully in some cases especially while porting to 64-bit platforms.
sharptooth
+4  A: 

Assigning "" to buf[size+1] does not reset the size of buf, but it is pointless, because it is duplicating a small portion of what the subsequent memset does (and it confuses your static analysis tool - you might want to file a bug report against it).

dave-ilsw
+4  A: 

It is not a buffer overflow.

This is probably a cleaner way to do it. Certainly it takes less lines of code.

#define size 64
char buf[size + 1] = {0};
EvilTeach