user_data: improve how returned data is handled
commit60f28307ac7d8ddbfe07e29481fd8926eecc85a7
authorDan Carpenter <dan.carpenter@oracle.com>
Wed, 8 Aug 2018 12:57:47 +0000 (8 15:57 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Wed, 8 Aug 2018 12:57:47 +0000 (8 15:57 +0300)
tree33d250c355bd0c8bf7ed25d4ad1d89bb851eb3c4
parent99145469de95998831ffe5b80fe1731e1b0082a6
user_data: improve how returned data is handled

There were three issues here.  Returns weren't handled properly if you
had a return like "return simple_strtol();".  Second is that nla_data()
wasn't marked as returning user data.  Third if you had a dereference like
*(u8 *)nla_data() that wasn't handled correctly.

The simple_strtol() function was only being hooked in when it was used in
an assignment.  This might be a bigger issue that I could handle better by
faking an assignment when we hit a return...  Anyway, for now I've just
made a list of function which return user data.

So now there are three ways that simple_strtol() is hooked in.  If you have
an assignment that's saved.  If it's called at all then we mark the
function as setting user data.  And if we call
__smatch_user_rl(simple_strtol()); then it just looks up the function from
the list in the returns_use_data[] array.  There is some overlap and
duplication here, but I think it doesn't affect the output.

Then when we hit a return, if we return a function call we can look that
information up separately and return the range list.

The next problem is that nla_data() wasn't marked as returning user data.
The reason for this is because nlmsg_data() does pointer math and smatch
can't handle it.  In the olden days, we maybe would have marked *nlh as
user data and we could have made that work, but I removed that code because
it kind of duplicated looking up the struct members and it wasn't clear
which information should trump the other.

Anyway, nla_data() is normally verified early, on but Smatch is crap at
tracking arrays so we lose that information.  Before Spectre, it wasn't
useful to know that nla_data() was user information because we trusted it
but now I want to mark it as user data but trusted so that we don't get
hundreds of array overflow warnings.  So I manually went into
smatch_capped.c and marked all the functions with "nla_get_" in the name
as capped.

The final change is that in var_user_rl() if we have a "*foo" dereference
we look up "foo" to see if it's marked as user data, and if so then "*foo"
is also user data.

Reported-by: Sabrina Dubroca <sdubroca@redhat.com>
Reported-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
check_user_data2.c
smatch_capped.c