Hisham Hijjawi
Hisham Hijjawi

Reputation: 2415

GCC: Specified bound depends on the length of the source argument

The following code:

while (node)
{
    if (node->previous== NULL) break;
    struct Node* prevNode = node->previous;
    len = strlen(prevNode->entity);
    //pp is a char* fyi
    pp-=len;
    strncpy(pp, prevNode->entity, len+1);
    *(--pp) = '/';
    node = prevNode;
}

Generates the following warning/error in GCC (I treat all warnings as errors):

../someFile.C:1116:24: error: 'char* strncpy(char*, const char*, size_t)' specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
 1116 |                 strncpy(pp, prevNode->entity, len+1);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../someFile.C:1114:29: note: length computed here
 1114 |                 len = strlen(prevNode->entity);
      |                       ~~~~~~^~~~~~~~~~~~~~~~~~~~

Why is GCC giving me a warning? What is wrong with relieing on the size of a source argument for the buffer size? Can someone give an example of what issues this may cause? Code does what it should I'm just curious why I'm getting a warning.

Upvotes: 16

Views: 21192

Answers (3)

Ron Wellman
Ron Wellman

Reputation: 545

I realize this is an old thread but couldn't help but point out that the warning is: -Werror=stringop-overflow=. This is an indication that you are potentially about to overflow your destination buffer because you are looking to your source buffer to determine how much data to copy.

In the source example:

len = strlen(prevNode->entity);
//pp is a char* fyi
pp-=len;
strncpy(pp, prevNode->entity, len+1);
*(--pp) = '/';

We actually have no idea how large the buffer reference by pp is at this point. What we do know is the len was subtracted from pp. By relying on the strlen(prevNode->entity) we could attempt to copy 64 bytes into a 32 byte buffer, causing an overflow. What is interesting here is that instead of overflowing the end of the buffer like most buffer overflows, we may actually write into memory space before the actual start of the buffer.

By switching to memcpy or strcpy all you're doing is ignoring the warning. You're covering up the fact that an overflow is possible. The warning is there for a reason. It means, pay attention, "here be dragons!".

Upvotes: 2

user1261695
user1261695

Reputation: 59

According the man page,

"The stpncpy() and strncpy() functions copy at most len characters from src into dst. If src is less than len characters long, the remainder of dst is filled with `\0' characters. Otherwise, dst is not terminated."

This has nothing to do with the amount of space in the destination buffer, but rather the number of characters needed to be copied. If one wishes to copy len characters from src into dst and src has more than len characters, then substituting strcpy will not produce the same results. Also, if the dst buffer's size was allocated with the expected size, then strcpy will produce a buffer overflow.

In this case the warning is misleading and should be ignored or silenced.

Upvotes: 3

TonyK
TonyK

Reputation: 17114

The point is that the length bound passed to strncpy should depend on the size of the destination argument, not the source argument. Otherwise, what is it even for? The compiler correctly recognises that there is no point to using strncpy here, and gives you an informative error message to that effect.

Upvotes: 18

Related Questions