expressions: don't set the ->parent to a fake expression
commit03e80606674ea76b560d9f570edf4ce68d347dc1
authorDan Carpenter <dan.carpenter@oracle.com>
Tue, 17 Apr 2018 12:32:20 +0000 (17 15:32 +0300)
committerDan Carpenter <dan.carpenter@oracle.com>
Wed, 18 Apr 2018 10:46:19 +0000 (18 13:46 +0300)
tree5d2622e48f90f0022439bb658eeae0865abe54e8
parentb630de7d895ce24be2cfb6e8cc4e9f651f7156c0
expressions: don't set the ->parent to a fake expression

This fixes a use after free bug.  People probably don't notice the bug in
the released version of Smatch, but I trigger it in some new stuff I'm
working on.

The problem is that in smatch_condition.c we have expression structs which
are on the stack and the ->left and ->right objects can outlive the fake
expression.  Or if we allocate a tmp_expression then that gets freed when
we finish parsing an inline function.  Then when we parse the inline again
the ->parent pointer are still set but they're point to freed memory.  (We
can sometimes look up the ->parent pointers before the expression has been
parsed by smatch_flow and the ->parent pointers get set.  For example,
see get_array_expr().)

So the fix is to not save temporary expression structs as parents.

This has a side effect, that probably the ->parent now points to the real
->parent instead of the fake parent?  I haven't tested this code very
completely but it feels like the way that it probably doesn't make a huge
difference either way.

I changed is_assigned_call() to deal with this.  It's a bit of a hack.  :(
The problem is that when we're faking initializations, there is no *real*
assignment for the ->parent struct to point to.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
expression.h
smatch_conditions.c
smatch_expressions.c
smatch_flow.c