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>