[cfe-dev] static analyzer invalidating entire structs

Deep Majumder via cfe-dev cfe-dev at lists.llvm.org
Sun Oct 3 00:55:52 PDT 2021


Hi Max,
Consider the following (somewhat contrived) example:
#include <stddef.h>

struct foo {
int val1;
int val2;
};

void sneaky(int *val) {
// Suppose I know I am always going to be passed
// val2 of an instance of struct foo here
size_t val2_off;
char *val2_ptr, *base_ptr;
struct foo *foo_ptr;
val2_off = offsetof(struct foo, val2);
val2_ptr = (char *) val;
// Sneak level: 100
base_ptr = val2_ptr - val2_off;
// I have found the struct instance pointer!
foo_ptr = (struct foo *) base_ptr;
// And now I can mangle every field of the
// struct instance as I please.
foo_ptr->val1 = rand();
}

void bar() {
struct foo fooer = { .val1 = 100, .val2 = 200 };
sneaky(&(fooer.val2));
// If CSA were to perform conservative eval of sneaky,
// it can have no idea what happened to the other fields
// of the struct instance.
As you can see, conservative evaluation has no choice but to invalidate all
struct members.
Btw, the example I have given is less contrived than it seems. In C, with
intrusive data structures, usually something very similar is done. The
"linked-list", which is an ubiquitous data-structure in the Linux kernel,
uses something like this (as a macro) to reach the struct from the list
node.
Warm regards,
Deep

On Sun, Oct 3, 2021 at 12:47 PM Max Schrötter via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hi,
>
> I noticed that conservativeEvallCall invalidates all items in a
> cluster(struct) in the example below instead of invalidating
> only the item passed as argument.
>
> I think the following Code should report a NonNullParamChecker warning.
> However t.mem is invalidated in the conservativeEvallCall of the scanf
> call.
>
> Example:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> struct test{
>     int* mem;
>     int value;
> };
>
>
> int main(int argc, char** argv, char** envp)
> {
>     struct test t;
>     t.value=8;
>     t.mem = NULL;
>     scanf("%d",&t.value);
>     memcpy(t.mem,&t.value,sizeof(int));
>     free(t.mem);
> }
>
> Is this a known limitation?
>
> I'm trying to debug this, but haven't fully understood the RegionStore
> yet. Is there more documentation besides the RegionStore.rst?
>
> Thanks
> Max
> _______________________________________________
> 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/20211003/36de72b9/attachment.html>


More information about the cfe-dev mailing list