Skip to content

[mono] Prevent memory corruption when decoding UCO entry point #86266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2023

Conversation

ivanpovazan
Copy link
Member

Description

This PR fixes an issue with memory corruption when MonoAOT compiler decodes the name of the exported symbols specified via EntryPoint of a UnmanagedCallersOnly method.

The offending lines were assuming that the entry point string in the metadata blob is null terminated, which caused sprintf to corrupt the memory around export_name.

I haven't been able to reproduce the issue with a smaller example other than how it is described in the tracking issue. If I manage to find a simple repro, I will add a unit test.

PS Not sure how this was not noticed before. One possibility is that the UCOs causing the problem have different encoding in the metadata blob, as they are generated by Cecil library not Roslyn.


Fixes #86264

@ivanpovazan
Copy link
Member Author

/azp run runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@@ -5352,10 +5352,16 @@ MONO_RESTORE_WARNING
for (j = 0; j < decoded_args->named_args_num; ++j) {
if (decoded_args->named_args_info [j].field && !strcmp (decoded_args->named_args_info [j].field->name, "EntryPoint")) {
named = (const char *)decoded_args->named_args[j]->value.primitive;
slen = mono_metadata_decode_value (named, &named) + (int)strlen(acfg->user_symbol_prefix);
export_name = (char *)g_malloc (slen + 1);
sprintf (export_name, "%s%s", acfg->user_symbol_prefix, named);
Copy link
Member

@filipnavara filipnavara May 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW this could have been modified to

namedlen = mono_metadata_decode_value (named, &named);
slen = namedlen + (int)strlen(acfg->user_symbol_prefix);
export_name = (char *)g_malloc (slen + 1);
sprintf (export_name, "%s%.*s", acfg->user_symbol_prefix, namedlen, named);

(+ declaration of namedlen)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your suggestion.
However, even though it achieves the same thing, I prefer not to use sprintf as originally it hid the underlying problem that was difficult to track down. So for that reason, I will keep it as is (simple and easily debuggable).

@ivanpovazan
Copy link
Member Author

Failures are known and unrelated.

@ivanpovazan ivanpovazan merged commit 4bca828 into dotnet:main May 16, 2023
@ivanpovazan ivanpovazan deleted the fix-uco-name-decoding branch June 9, 2023 12:15
@ghost ghost locked as resolved and limited conversation to collaborators Jul 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[mono] FullAOT compilation of Microsoft.iOS.dll crashes with managed static registrar
4 participants