[marshal] Fix race between delegate marshaling and finalization
commite113ce925bafedca751fe6d2c21f5ad59d79bd62
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 2 May 2019 13:09:31 +0000 (2 16:09 +0300)
committerMarek Safar <marek.safar@gmail.com>
Fri, 31 May 2019 10:06:02 +0000 (31 12:06 +0200)
tree8d70a459a9d75ead4801b1d0fd8c4eeda349269e
parentbab25c0a80f7a9ad8f1f18be227119384e3ec0a0
[marshal] Fix race between delegate marshaling and finalization

When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes https://github.com/mono/mono/issues/13231
mono/metadata/marshal.c