-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fix string.strlen #22397
Fix string.strlen #22397
Conversation
|
|
||
| if (Avx2.IsSupported) | ||
| { | ||
| if ((((nuint)Unsafe.AsPointer(ref searchSpace) + (nuint)offset) & (nuint)(Vector256<byte>.Count - 1)) != 0) |
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.
The object couldn't be moved after the AsPointer check?
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.
string.strlen uses byte* so its fixed data; for public use I don't think this method offers any guarantees for reading out of bounds over unfixed managed data.
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.
e.g. the issue is that string.strlen calls this with length int.MaxValue; if the reads are not aligned then reading the Vector can cross a page boundary into a non-allocated page; creating a segfault, even if the part of the Vector in the page contains the null terminator.
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.
The method is used by public API https://source.dot.net/#System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs,253f89d386c4359c,references
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.
Yes, but the public api uses don't suggest you can use a length larger than the memory allocated for the array/span. This method will not read passed the length passed in.
The issue is because strlen is looking for a null terminator in an unknown length of memory; without this change it can page fault into non-process memory; with this change it can't (unless the string doesn't have a null terminator)
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.
Specifically
coreclr/src/System.Private.CoreLib/shared/System/String.cs
Lines 658 to 659 in e78994d
| // IndexOf processes memory in aligned chunks, and thus it won't crash even if it accesses memory beyond the null terminator. | |
| int length = SpanHelpers.IndexOf(ref *ptr, (byte)'\0', int.MaxValue); |
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.
Aah..
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.
Right, we had two options on how to implement strlen: Either reuse IndexOf and make sure that it handles the int.MaxValue buffer size as unknown buffer size, or create a separate implementation for it that would be almost identical to IndexOf. We have chosen the first one.
|
coreclr-ci failure in eventpipeandetw_eventpipeandetw_eventpipeandetw_cmd https://github.com/dotnet/coreclr/issues/19302#issuecomment-460358752 |
It should be possible to write platform-neutral test for this using System.IO.MemoryMappedFiles. It can live in either CoreCLR or CoreFX. I think our default choice would be CoreFX since it is an API test. |
|
Probably why I couldn't get the char version wcslen to work #21730; likely needs to be tweaked in similar way |
|
@dotnet-bot test Windows_NT x64 Checked jitx86hwintrinsicnoavx @dotnet-bot test Windows_NT x86 Checked jitx86hwintrinsicnoavx @dotnet-bot test Ubuntu x64 Checked jitx86hwintrinsicnoavx |
|
Ubuntu x64 Checked Build and Test (Jit - TieredCompilation=0 EnableIncompleteISAClass=1 EnableAVX=0) and Ubuntu x64 Checked Build and Test (Jit - TieredCompilation=0 EnableIncompleteISAClass=1 FeatureSIMD=0) Failed with: Don't think its related? |
* Add explanation comment Fixes dotnet#22393 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Add explanation comment Fixes #22393 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Add explanation comment Fixes #22393 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Add explanation comment Fixes #22393 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Add explanation comment Fixes #22393 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Add explanation comment Fixes #22393 Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
|
This change causes x86/x64 JitStress=2 tests to fail: https://github.com/dotnet/coreclr/issues/22436. I'm going to disable the tests for now with #22438, but an alternative is to back this change out until the JIT is fixed. |
|
Causes an access volition https://github.com/dotnet/coreclr/issues/22393 without this change :-/ |
|
Right, going from intermittent AV to JIT-stress failure is an improvement. We should suppress the JIT stress failures until the JIT is fixed as @BruceForstall has done. |
* Add explanation comment Fixes dotnet/coreclr#22393 Commit migrated from dotnet/coreclr@cc8bcb2
Fixes #22393
What's the best approach for adding a coreclr test for this? (e.g. the code from #22393); as the coreclr tests are a little different than corefx.
/cc @jkotas @stephentoub