From a56212b5ae6fe272e3b1738a65edd90f31f27d4f Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Sat, 4 Mar 2017 11:03:56 -0600 Subject: [PATCH] [metadata] Fix a possible crash when looking up a p/invoke function. (#4471) It's possible for two threads to modify the same MonoMethodPInvoke.addr in mono_lookup_pinvoke_call, with one thread setting it to NULL inside the loop, and the other thread having completed the loop and expecting it to be non-NULL. Use an intermediate variable to prevent addr becoming non-NULL. --- mono/metadata/loader.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index a2d671c6839..e0b18174a12 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -1166,6 +1166,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char int i,j; MonoDl *module = NULL; gboolean cached = FALSE; + gpointer addr = NULL; g_assert (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL); @@ -1474,7 +1475,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char "Searching for '%s'.", import); if (piinfo->piflags & PINVOKE_ATTRIBUTE_NO_MANGLE) { - error_msg = mono_dl_symbol (module, import, &piinfo->addr); + error_msg = mono_dl_symbol (module, import, &addr); } else { char *mangled_name = NULL, *mangled_name2 = NULL; int mangle_charset; @@ -1496,7 +1497,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char #endif for (mangle_param_count = 0; mangle_param_count <= (need_param_count ? 256 : 0); mangle_param_count += 4) { - if (piinfo->addr) + if (addr) continue; mangled_name = (char*)import; @@ -1547,9 +1548,9 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "Probing '%s'.", mangled_name2); - error_msg = mono_dl_symbol (module, mangled_name2, &piinfo->addr); + error_msg = mono_dl_symbol (module, mangled_name2, &addr); - if (piinfo->addr) + if (addr) mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "Found as '%s'.", mangled_name2); else @@ -1568,7 +1569,7 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char } } - if (!piinfo->addr) { + if (!addr) { g_free (error_msg); if (exc_class) { *exc_class = "EntryPointNotFoundException"; @@ -1576,7 +1577,8 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char } return NULL; } - return piinfo->addr; + piinfo->addr = addr; + return addr; } /* -- 2.11.4.GIT