[cfe-dev] Clang doesn't warn about wrong sized mallocs

Arthur O'Dwyer via cfe-dev cfe-dev at lists.llvm.org
Mon Aug 16 15:46:20 PDT 2021


The relevant prior art here is -Wsizeof-pointer-memaccess (supported by
both GCC and Clang):

    // https://godbolt.org/z/ccf3W3dvd
    #include <stdlib.h>
    #include <string.h>
    struct S { void *field; };
    int main() {
        struct S s1;
        struct S *s2 = malloc(sizeof(s2));  // no warning, oops
        memcpy(s2, &s1, sizeof(s2));  // -Wsizeof-pointer-memaccess
        memset(s2, '\0', sizeof(s2));  // -Wsizeof-pointer-memaccess
    }

Both GCC and Clang warn on memcpy and memset, but neither one warns on the
original malloc. My guess is that the original malloc is harder, because
the relevant relationship is no longer between *two arguments to the same
call*, but rather between the argument and *the left-hand side of the
assignment where the result is actually used*. To me this smells a lot more
like "dataflow analysis" than the existing memcpy/memset case does.
However, if people are interested in pursuing this, I'd definitely
recommend looking at -Wsizeof-pointer-memaccess and thinking about how to
generalize it beyond argument-argument relationships.

my $.02,
–Arthur


On Mon, Aug 16, 2021 at 5:51 PM Joerg Sonnenberger via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Mon, Aug 16, 2021 at 05:19:45PM +0000, Leander Besting wrote:
> > The following doesn't produce any warnings but I don't know about
> clang-tidy.
> >
> > $ clang a.c --analyze --analyzer-output text
> >
> > // a.c
> > #include <stdlib.h>
> > struct S {
> >     int x, y, z;
> > };
> > int main() {
> >     // sizeof (struct S) == 12
> >     // sizeof (s) == 8
> >     struct S *s = malloc(sizeof(struct S) * 2);
> >     free(s);
> > }
>
> This is fine, because the compiler can statically assert that no
> overflow can happen. But the following IMO should have a warning:
>
> #include <stdlib.h>
>
> struct S {
>   int x, y, z;
> };
>
> size_t len;
>
> int main() {
>     struct S *s = malloc(sizeof(struct S) * len);
>     free(s);
> }
>
> At least for the static analyzer. It's a very common category of bugs.
>
> Joerg
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210816/0616feee/attachment.html>


More information about the cfe-dev mailing list