This is an archive of the discontinued LLVM Phabricator instance.

[static analyzer] Emit buffer overflow warning in strcpy fucntion when uninitialized source array of known length(> dest length) is used
Needs ReviewPublic

Authored by mayurp on Oct 28 2014, 2:49 AM.

Details

Summary

Enable static analyzer to throw warnings when uninitialized source array of known length is given as the argument to strcpy function, where dest size < source size.
char x[3] = "abc";
char y[4];
strcpy(x,y); // emit buffer overflow warning

Diff Detail

Event Timeline

mayurp updated this revision to Diff 15519.Oct 28 2014, 2:49 AM
mayurp retitled this revision from to [static analyzer] Emit buffer overflow warning in strcpy fucntion when uninitialized source array of known length(> dest length) is used.
mayurp updated this object.
mayurp edited the test plan for this revision. (Show Details)
mayurp added reviewers: krememek, zaks.anna, jordan_rose.
mayurp added a subscriber: Unknown Object (MLST).

Your test cases and commit message look wrong to me.

char x[3] = "abc";
char y[4] = "ab";
strcpy(x,y);  // This should not warn, or at least should give a suppressible diagnostic,
              // since no overflow occurs: "ab" fits into x just fine

char x[3] = "abc";
char y[4];
strcpy(x,y);  // This should give a use-before-def diagnostic for y

char x[3] = "abc";
char y[100];
strcpy(y, x);  // This should give the "overflow" diagnostic, since it definitely attempts to strcpy an array of char that is not null-terminated

Hi Arthur,

Thanks for reviewing the patch and providing valuable comments. Actually what I meant by uninitialized source array was an source array which does not contain proper string or is not properly null terminated, so probably need to change the commit message. The testcase that would appropriately test the patch would be :

char x[10] = "abcd";
char y[100] ;
memset(y,'a',100);
strcpy(x,y); // string overflow warning

when we execute the same code we get segmentation fault:
$ cat strcpy3.c
#include<string.h>

int main ()
{

char x[10] = "abcd";
char y[100] ;
memset(y,'a',100);
strcpy(x,y);
return 0;

}
$ clang strcpy3.c
$ ./a.out
Segmentation fault (core dumped)
$

And the behaviour in test cases you mentioned would be:

char x[3] = "abc";
char y[4] = "ab";
strcpy(x,y); // this will not throw warning as it fits finely into x

char x[3] = "abc";
char y[4];
strcpy(x,y); // as you pointed correctly, this would throw use-before-def for y (i had not enabled alpha checker earlier so i was getting overflow warning)

char x[3] = "abc";
char y[100];
strcpy(y, x); // the patch does not handle this as per your comments. On checking the behaviour with clang this does not seem to be buffer-overflow, I might be wrong though.

please review

Thanks,
Mayur

Mayur, you wrote:

The testcase that would appropriately test the patch would be ...

but you didn't actually revise your patch.
Now, I'm pretty sure that this patch is just entirely wrong (e.g. you wrote it without being aware that char a[3]="xyz" is not a null-terminated string), but certainly it's bad form to "ping" before you've addressed the previous round's comments.

mayurp updated this revision to Diff 15755.Nov 4 2014, 3:08 AM
mayurp added a reviewer: arthur.j.odwyer.

Hi Arthur,

Sorry for not updating the patch last time. I was waiting for your comments before updating it. Updated the patch now.
And for this case:

char x[3] = "abc";
char y[100];
strcpy(y, x); 

I had mentioned that this does not seem to be buffer-overflow, as when i checked the same with clang, strcpy is inserting a null terminator after copying the contents of source array.

$ cat strcpy.c
#include<string.h>
#include<stdio.h>
int main ()
{

char x[3]; // non-null terminated array
x[0] = 'a';
x[1] = 'b';
x[2] = 'c';
char y[100] ;
memset(y,'a',100);
strcpy(y,x);
printf("%s \n",y);
printf("%c\n",y[0]);
printf("%c\n",y[1]);
printf("%c\n",y[2]);
printf("%c\n",y[3]);
printf("%c\n",y[4]);
return 0;

}
$ clang strcpy.c
$ ./a.out
abc
a
b
c

a

In this example it is seen that clang is inserting null terminator and hence even while copying non-null terminated string to another array, buffer-overflow is not caused.
Please provide comments on whether this analysis is correct or not.

Thanks,
Mayur