Skip to content

genStructPutArgUnroll will go out of bounds on mis-sized struct loads #65937

@SingleAccretion

Description

@SingleAccretion

Reproduction:

[MethodImpl(MethodImplOptions.NoInlining)]
private static void Problem(NineByteStruct* p)
{
    CallForNineByteStructs(*p, *p, *p, *p);
}

struct NineByteStruct
{
    public byte ByteOne;
    public byte ByteTwo;
    public byte ByteThree;
    public byte ByteFour;
    public byte ByteFive;
    public byte ByteSix;
    public byte ByteSeven;
    public byte ByteEight;
    public byte ByteNine;
}

Compile with CG2 and a debug/checked Jit, targetos:Linux targetarch:x64 --codegenopt NgenDump=Problem.

Expected result: we're only loading 9 bytes of the struct to pass on the stack.
Actual result: we're loading 16, leading, possibly, to out-of-bounds memory access (crossing page boundaries).

Generating: N003 (???,???) [000043] ------------                 IL_OFFSET void   INLRT @ 0x000[E-] REG NA
Generating: N005 (  1,  1) [000006] ------------         t6 =    LCL_VAR   long   V00 arg0         u:1 rdi REG rdi $80
                                                              /--*  t6     long
Generating: N007 (  7,  5) [000007] -c-XG-------         t7 = *  OBJ       struct<RyuJitReproduction.Program+NineByteStruct, 9> REG NA <l:$1c1, c:$1c0>
                                                              /--*  t7     struct
Generating: N009 (???,???) [000045] ---XG-------              *  PUTARG_STK [+0x00] void   (2 slots), (16 stackByteSize), (0 slot), (0 byteOffset) (Unroll) REG NA
IN0001:        vmovdqu  xmm0, qword ptr [rdi]
IN0002:        vmovdqu  qword ptr [V01 rsp], xmm0

Cause: genStructPutArgUnroll always uses the argument's size (including padding / alignment) when deciding how many bytes to copy. It needs to use the exact size in case the source is not local.

Once that's fixed, we should also delete code from morph which copies mis-sized structs on x86, it will no longer be needed.

Metadata

Metadata

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIbug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions