-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix buffer overruns in GC code #74847
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
Conversation
|
Tagging subscribers to this area: @dotnet/gc Issue DetailsUnder some conditions we may either create or try to create too many GC heaps, which may lead to buffer overruns in GC code. For example, a user may override the number of processors available to the process (e.g., by setting proc_no_to_numa_node[proc_no[i]] = cur_node_no;in case we exited the previous loop early and left the The fix is to ensure that
Footnotes
|
| uint16_t procIndex = 0; | ||
| size_t cnt = heap_number; | ||
| for (uint16_t i = 0; i < GCToOSInterface::GetTotalProcessorCount(); i++) | ||
| for (uint16_t i = 0; i < MAX_SUPPORTED_CPUS; i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with the implementation in gcenv.os.cpp; see also #206 for the context.
This assert is a generic sign of GC heap corruption that can have many different root causes. All past instances of this crash are believed to be fixed. We do not have an active issue on it. If you believe that this is unrelated, you should get a new active issue created on it. |
|
I have opened #74895, but I cannot get the call stack from the dump. LLDB on Ubuntu ARM64 displays |
|
You cannot open a dump taken on a MUSL based distro on a Glibc based ones. And in fact, to get meaningful stack trace, you need to use exactly the same distro and version of the distro (it also has to have the same version of glibc) where the core was taken. |
|
Docker is the way I use in these cases. |
janvorli
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thank you!
|
/backport to release/7.0 |
|
Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/2975767222 |
Do we have instructions written anywhere? If not, we should document them. |
Under some conditions we may either create or try to create too many GC heaps, which may lead to buffer overruns in GC code. For example, a user may override the number of processors available to the process (e.g., by setting
DOTNET_PROCESSOR_COUNT=100andDOTNET_GCNoAffinitize=1). Or an app may be running under Windows 11 on a machine with asymmetric processor groups, whereGetSystemInfoandGetProcessAffinityMaskcalls may return inconsistent results1. In those cases,g_num_active_processors(the number of heaps we create if not additionally overridden) may become greater thang_num_processors(the number of slots we allocate for handle tables). That leads to buffer overruns when a thread with the home heap number that is greater or equal tog_num_processorstries to create a GC handle.Additionally, the
heap_select::initfunction ingc.cppmay overrun theproc_no_to_numa_nodearray at this line:in case we exited the previous loop early and left the
proc_no[i]value uninitialized.The fix is to ensure that
g_num_active_processorsis never greater thang_num_processorsand to iterate only through the initialized part of theproc_noarray.Footnotes
We may want to address that separately. ↩