Uh oh!
There was an error while loading. Please reload this page.
Validate IntPtr and ByRef field overlap - #65246
Conversation
Uh oh!
There was an error while loading. Please reload this page.
MichalStrehovsky
commented
Feb 12, 2022
Is ByRef and IntPtr overlap a problem? We decided not to check this for ByRef-like types. ByRef pointing to unmanaged memory or other garbage should be fine because that's what happens for Span pointing to unmanaged memory. Or is this futureproofing for when we allow byrefs on the GC heap and we'll need to make sure these writes go through a write barriers when that happens? |
AaronRobinsonMSFT
commented
Feb 12, 2022
I think the same thing can currently occur. For example, if a @davidwrighton and I discussed this, and I was convinced it was a real issue. Feel free to push back though. |
MichalStrehovsky
commented
Feb 13, 2022
I don't have an opinion either way. But if we do this, we should probably also revisit this for byref-like types too so that we don't end up with a situation where: refstructFoo{[Offset(0)]refintField1;[Offset(0)]IntPtrField2}is disallowed but, refstructHiddenRef{refintField;}refstructFoo{[Offset(0)]HiddenRefField1;[Offset(0)]IntPtrField2}is allowed, even though they're basically the same thing. There was some conversation about it at #12842 (comment). |
MichalStrehovsky
commented
Feb 13, 2022
Or maybe your pull request already does this - I don't read C++ on weekends. |
AaronRobinsonMSFT
commented
Feb 13, 2022
@MichalStrehovsky I get it, that's okay. However, it does handle your query above. |
@MichalStrehovsky the problem with ByRef/ByRefLike and IntPtr overlap is that it becomes possible (without the use of unsafe) to generate a byref that points to something in the GC heap which isn't actually an object. (The GC has an invariant that ByRef pointers passed into it must either be within an object on the GC heap or not within the memory regions of the GC Heap at all.) If we've explicitly been permitting ByRefLike structure overlap with IntPtr for the purpose of doing funky things with |
MichalStrehovsky
commented
Feb 14, 2022
No, it was just decided that validating that wasn't worth the hassle at that time: #12842 (comment) This test is going to fail on NativeAOT if we're not adding a check for that to the managed type system. I would be okay with that if it's not observable with crossgen2. The test is doing a FWIW, we've been mirroring these checks in the past (dotnet/coreclr#27054). |
lambdageek
left a comment
There was a problem hiding this comment.
I don't think we should recurse into reference types when computing has_ref_fields. Otherwise mono bits LGTM
Uh oh!
There was an error while loading. Please reload this page.
AaronRobinsonMSFT
commented
Feb 15, 2022
These tests pass under CrossGen2. I'm assuming that is what is meant here. |
MichalStrehovsky
commented
Feb 15, 2022
No, as I wrote above "The test is doing a typeof and that's an obvious type load that will let CoreCLR throw the exception no matter if the code was AOT'd". I meant: usingSystem;usingSystem.Runtime.InteropServices;Explicitex=newExplicit{Guid=Guid.NewGuid(),};returnex.Bytes.Length;[StructLayout(LayoutKind.Explicit)]refstructExplicit{[FieldOffset(0)]publicSpan<byte>Bytes;[FieldOffset(0)]publicGuidGuid;}I just tried this: C:\git\runtime\artifacts\bin\coreclr\windows.x64.Debug>csc /nologo /noconfig /nostdlib test.cs /r:System.Private.CoreLib.dll
C:\git\runtime\artifacts\bin\coreclr\windows.x64.Debug>corerun test.exe
Unhandled exception. System.TypeLoadException: Could not load type'Explicit' from assembly 'test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
at Program.<Main>$(String[] args)
C:\git\runtime\artifacts\bin\coreclr\windows.x64.Debug>crossgen2\crossgen2.exe test.exe -o:test.ni.exe -r:System.Private.CoreLib.dll
Emitting R2R PE file: test.ni.exe
C:\git\runtime\artifacts\bin\coreclr\windows.x64.Debug>corerun test.exe
C:\git\runtime\artifacts\bin\coreclr\windows.x64.Debug>echo %ERRORLEVEL%
985271193So ReadyToRun currently can bypass the checks. |
Support here could be enabled with the conservative GC but instead of permitting that, CoreCLR will block support in the type loader.
Confirmed tests pass locally on mono, CoreCLR, and with CrossGen.
/cc @davidwrighton@MichalStrehovsky @dotnet/interop-contrib