[cfe-dev] Unexpected warning (confused by non-zero safemalloc?)
Eli Friedman
eli.friedman at gmail.com
Mon Jul 8 14:11:06 PDT 2013
On Fri, Jul 5, 2013 at 5:23 PM, <solo-clang at goeswhere.com> wrote:
> I have:
>
> $ clang --version
> Debian clang version 3.4-1~exp1 (trunk) (based on LLVM 3.4)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
>
> *** 1:3.4~svn185715-1~exp1 0
> 500 http://llvm.org/apt/wheezy/ llvm-toolchain-wheezy/main amd64 Packages
>
> ..and I'm trying to compile:
>
> #include <stdint.h>
> #include <string.h>
> #include <stdlib.h>
>
> void *smalloc(size_t size) {
> if (size == 0) {
> return malloc(1);
> } else {
> return malloc(size);
> }
> }
>
> char *dupstr(const char *s) {
> const int len = strlen(s);
> char *p = smalloc(len + 1);
> strcpy(p, s);
> return p;
> }
>
> I get:
>
> $ clang -Weverything --analyze -c misc.c
> misc.c:16:5: warning: String copy function overflows destination buffer
> strcpy(p, s);
> ^~~~~~~~~~~~
> 1 warning generated.
>
> It appears to be confused by the presence of that "if (size == 0)"
> block in smalloc. Basically any change to this code removes the warning,
> although size <= 1 leaves it.
>
> Is this a bug, or did I do something silly?
Well, the assignment from a size_t into an int is silly... but there's
still an issue reported even if you fix that.
The analyzer sees two paths here: one where strlen(s)+1 == 0, and one
where strlen(s)+1 != 0. On the strlen(s)+1 == 0 path, you're copying
a string of length SIZE_MAX into a buffer of length 1, an overflow.
Of course, strlen(s) == SIZE_MAX is impossible because s would cover
the entire address-space... so it's possible the analyzer should be a
bit smarter here.
-Eli
More information about the cfe-dev
mailing list