[marshal] Fix race between delegate marshaling and finalization
commitcaa4a753ca8e15d43baaa01adb0f56f374b74a2b
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:05:37 +0000 (31 12:05 +0200)
treec622689341e78df19d08aea3e3e10ee41b821d07
parent8d858b20c555da92798a243a871528906368d2b0
[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