Skip to content

Commit b41d940

Browse files
[release/9.0-staging] [mono] Missing memory barrier leads to crash in multi-threaded scenarios (#113740)
Backport of #113140 Issue #109410 appears to be a case where klass is 0 when we perform an isinst operation, but the cache and obj are nonzero and look like valid addresses. klass is either a compile-time (well, jit-time) constant or being fetched out of the cache (it looks like it can be either depending on some sort of rgctx condition). This PR adds null checks in two places along with a memory barrier in the location where we believe an uninitialized cache is being published to other threads. --------- Co-authored-by: Katelyn Gadd <[email protected]>
1 parent 51e319d commit b41d940

File tree

2 files changed

+7
-1
lines changed

2 files changed

+7
-1
lines changed

src/mono/mono/metadata/object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6806,6 +6806,7 @@ mono_object_handle_isinst (MonoObjectHandle obj, MonoClass *klass, MonoError *er
68066806
{
68076807
error_init (error);
68086808

6809+
68096810
if (!m_class_is_inited (klass))
68106811
mono_class_init_internal (klass);
68116812

src/mono/mono/mini/jit-icalls.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1702,7 +1702,7 @@ mono_throw_type_load (MonoClass* klass)
17021702
mono_error_set_type_load_class (error, klass, "Attempting to load invalid type '%s'.", klass_name);
17031703
g_free (klass_name);
17041704
}
1705-
1705+
17061706
mono_error_set_pending_exception (error);
17071707
}
17081708

@@ -1743,6 +1743,11 @@ mini_init_method_rgctx (MonoMethodRuntimeGenericContext *mrgctx, MonoGSharedMeth
17431743
mono_method_get_context (m), m->klass);
17441744
g_assert (data);
17451745

1746+
// we need a barrier before publishing data via mrgctx->infos [i] because the contents of data may not
1747+
// have been published to all cores and another thread may read zeroes or partially initialized data
1748+
// out of it, even though we have a barrier before publication of entries in mrgctx->entries below
1749+
mono_memory_barrier();
1750+
17461751
/* The first few entries are stored inline, the rest are stored in mrgctx->entries */
17471752
if (i < ninline)
17481753
mrgctx->infos [i] = data;

0 commit comments

Comments
 (0)