[verifier] Implement verification of byref returns.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 11 Sep 2017 22:53:14 +0000 (15:53 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 11 Sep 2017 22:53:14 +0000 (15:53 -0700)
commit8493513ad3876e73163f64ecab0299bd5e6e0346
tree8d7ac0264c50e69678a3830bdbf0903c14445c40
parent4a20e930afc89aba911f43fb14cce2feeeab65cc
[verifier] Implement verification of byref returns.

The verification algorithm is inspired on internal specs by the Roslyn team but adapted to what it generates today.
Here's how this patch works:

We introduce a new verification type, SAFE_BYREF, that's used for a byref value that is safe to return from the stack.

It's unverifiable to return a byref value that is not marked SAFE_BYREF.

We mark the following values are SAFE_BYREF:
- byref arguments, unless it's the `this` arg of a valuetype instance method
- return values of method calls when all byref arguments have SAFE_BYREF values - the this arg is ignored.
- the address of a static field (LDSFLDA)
- the address of an array element (LDELEMA)
- the address of a field if the receiver is either a SAFE_BYREF value or a reference

Notoriously from the above is the value of local variables. We took a conservative approach of unsafe tainting.
We do this by associating 3 states to a local: unassigned (initial value of zero), assigned and safe (SAFE_BYREF_LOCAL), assigned and unsafe (UNSAFE_BYREF_LOCAL)
When loading a local, we set its value as SAFE_BYREF if the local is in the SAFE_BYREF_LOCAL state.

When storing to a local, we set it to SAFE_BYREF_LOCAL if, only if, it's not marked as UNSAFE_BYREF_LOCAL and the value is SAFE_BYREF.
If we store a non-safe value to a local, we mark it as UNSAFE_BYREF_LOCAL.
If we store a non-safe value to a SAFE_BYREF_LOCAL local, we mark the method as unverifiable.

This algorithm makes sure we don't mix safe and unsafe byref and side with safety in case of control-flow dependent values.
mono/metadata/verify.c
mono/tests/verifier/valid_ref_return.cs [new file with mode: 0644]
tools/pedump/Makefile.am