dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.08k stars 4.7k forks source link

ubsan failure when calling through pointer to member function #73927

Open RobertHenry6bev opened 2 years ago

RobertHenry6bev commented 2 years ago

Description

on ubuntu x64 using gcc-10 through gcc-12, compiled -O0 -ggdb -fsanitize=undefined

causes a runtime error when a pointer to a member function is called.

/mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.h:100:10: runtime error: member access within address 0x7fbeb726e070 which does not point to an object of type 'Phase'
0x7fbeb726e070: note: object has invalid vptr
 ff c9 c3 90  f3 0f 1e fa 55 48 89 e5  41 55 41 54 53 48 83 ec  18 48 89 7d d8 48 8b 45  d8 48 83 7d
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr

The relevant top ~10 frames are below.

I suspect that one of the three+ pointers in the expression

  (comp->*action)()

may point to de-allocated or scribbled-upon storage. I can not tell if it is the memory pointed to by

  1. this (eg, a CompilerPhase)
  2. this->comp (eg, a Compiler)
  3. this->action (a closure/thunk of some kind, with a vptr / vtbl, plus pointer to the function itself, namely Compiler::fgAddInternal()

The attached program reproduces the ubsan runtime error message when one of the instances has been deleted.

I do not see this behavior with clang+ubsan, using clang 10-clang-14

The invocation of gcc -fsanitize=address has put in at least 7 checks for this call.

==========frames================

3  0x00007fbeb726e6f0 in CompilerPhase::DoPhase (this=0x7fffffffb840)
    at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.h:100
100         (comp->*action)();
(gdb) up
#4  0x00007fbeb72740eb in Phase::Run (this=0x7fffffffb840) at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.cpp:61
61      PhaseStatus status = DoPhase();
(gdb) where
#0  __ubsan::ScopedReport::~ScopedReport (this=this@entry=0x7fffffffb500, __in_chrg=<optimized out>)
    at ../../../../src/libsanitizer/ubsan/ubsan_diag.cpp:388
#1  0x00007ffff7995438 in HandleDynamicTypeCacheMiss (Data=<optimized out>, Pointer=140457093292144, Hash=<optimized out>, Opts=...)
    at ../../../../src/libsanitizer/ubsan/ubsan_handlers_cxx.cpp:81
#2  0x00007ffff799578f in __ubsan::__ubsan_handle_dynamic_type_cache_miss (Data=<optimized out>, Pointer=<optimized out>, 
    Hash=<optimized out>) at ../../../../src/libsanitizer/ubsan/ubsan_handlers_cxx.cpp:87
#3  0x00007fbeb726e6f0 in CompilerPhase::DoPhase (this=0x7fffffffb840)
    at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.h:100
#4  0x00007fbeb72740eb in Phase::Run (this=0x7fffffffb840) at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.cpp:61
#5  0x00007fbeb726e979 in DoPhase (_compiler=0x5555556c6318, _phase=PHASE_MORPH_ADD_INTERNAL, 
    _action=(void (Compiler::*)(Compiler * const)) 0x7fbeb74bb758 <Compiler::fgAddInternal()>)

Reproduction Steps

This program generates the same ubsan runtime error. The small program reference through a deleted object ubsan.txt

Expected behavior

no runtime errors

Actual behavior

see runtime errors

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

/cc @AaronRobinsonMSFT

category:correctness theme:intrinsics skill-level:beginner cost:small impact:small

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 2 years ago

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.

Issue Details
### Description on ubuntu x64 using gcc-10 through gcc-12, compiled -O0 -ggdb -fsanitize=undefined causes a runtime error when a pointer to a member function is called. /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.h:100:10: runtime error: member access within address 0x7fbeb726e070 which does not point to an object of type 'Phase' 0x7fbeb726e070: note: object has invalid vptr ff c9 c3 90 f3 0f 1e fa 55 48 89 e5 41 55 41 54 53 48 83 ec 18 48 89 7d d8 48 8b 45 d8 48 83 7d ^~~~~~~~~~~~~~~~~~~~~~~ invalid vptr The relevant top ~10 frames are below. I suspect that one of the three+ pointers in the expression (comp->*action)() may point to de-allocated or scribbled-upon storage. I can not tell if it is the memory pointed to by 1. this (eg, a CompilerPhase) 2. this->comp (eg, a Compiler) 3. this->action (a closure/thunk of some kind, with a vptr / vtbl, plus pointer to the function itself, namely Compiler::fgAddInternal()> The attached program reproduces the ubsan runtime error message when one of the instances has been deleted. I do not see this behavior with clang+ubsan, using clang 10-clang-14 The invocation of `gcc -fsanitize=address` has put in at least 7 checks for this call. ==========frames================ 3 0x00007fbeb726e6f0 in CompilerPhase::DoPhase (this=0x7fffffffb840) at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.h:100 100 (comp->*action)(); (gdb) up #4 0x00007fbeb72740eb in Phase::Run (this=0x7fffffffb840) at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.cpp:61 61 PhaseStatus status = DoPhase(); (gdb) where #0 __ubsan::ScopedReport::~ScopedReport (this=this@entry=0x7fffffffb500, __in_chrg=) at ../../../../src/libsanitizer/ubsan/ubsan_diag.cpp:388 #1 0x00007ffff7995438 in HandleDynamicTypeCacheMiss (Data=, Pointer=140457093292144, Hash=, Opts=...) at ../../../../src/libsanitizer/ubsan/ubsan_handlers_cxx.cpp:81 #2 0x00007ffff799578f in __ubsan::__ubsan_handle_dynamic_type_cache_miss (Data=, Pointer=, Hash=) at ../../../../src/libsanitizer/ubsan/ubsan_handlers_cxx.cpp:87 #3 0x00007fbeb726e6f0 in CompilerPhase::DoPhase (this=0x7fffffffb840) at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.h:100 #4 0x00007fbeb72740eb in Phase::Run (this=0x7fffffffb840) at /mnt/robhenry/dotnet/clang11.a/runtime/src/coreclr/jit/phase.cpp:61 #5 0x00007fbeb726e979 in DoPhase (_compiler=0x5555556c6318, _phase=PHASE_MORPH_ADD_INTERNAL, _action=(void (Compiler::*)(Compiler * const)) 0x7fbeb74bb758 ) ### Reproduction Steps This program generates the same ubsan runtime error. The small program reference through a deleted object [ubsan.txt](https://github.com/dotnet/runtime/files/9335139/ubsan.txt) ### Expected behavior no runtime errors ### Actual behavior see runtime errors ### Regression? _No response_ ### Known Workarounds _No response_ ### Configuration _No response_ ### Other information /cc @aaronrobin
Author: RobertHenry6bev
Assignees: -
Labels: `area-CodeGen-coreclr`, `untriaged`
Milestone: -
RobertHenry6bev commented 2 years ago

/cc @mangod9 I looked at this some more. It is increasingly looking like a bug in ubsan.

The error message the ubsan runtime generates doesn't make sense. it is talking about an invalid vptr, and dumps what I presume is the *vptr, eg to the vtbl itself. But the pointer point to the code making up the called-to function, and the dumped bytes are the bytes at the entry of the function.

The message complains about a mangled object of type Phase, but as far as I can tell, Phase::Phase was called for the this pointer, and Phase::~Phase has not been called yet. (There is a lot of storage reuse for Phase allocator.)

The issue is found by gcc-10 through gcc-12, but not by clang.

JulieLeeMSFT commented 2 years ago

@kunalspathak PTAL and triage quickly. cc @dotnet/jit-contrib

kunalspathak commented 2 years ago

@RobertHenry6bev - Is the repro to compile coreclr using gcc -fsanitize=undefined and any console application would hit this error? I can definitely try out and see all the places where we hit them, but it is unlikely that we will be able to fix in .NET 7. Having .NET 8 as milestone is suitable for this.

RobertHenry6bev commented 2 years ago

This problem seems to occur on x64 using gcc-12 -fsanitize=undefined, but not using clang-14 -fsanitize=undefined

RobertHenry6bev commented 2 years ago

The member function is successfully called on x64 when there are no sanitizers given to gcc12.

RobertHenry6bev commented 2 years ago

gcc snapshot 13-20220814 on x64 behaves the same way as gcc-12 does

kunalspathak commented 1 year ago

@RobertHenry6bev - can you please confirm the full command you used to repro this?

RobertHenry6bev commented 1 year ago

That was quite a while ago, and the hacky infrastructure I threw together to compile dotnet core runtime with different g++ invocations may have fallen apart. I'll see what I can do.

On Mon, Jun 5, 2023 at 11:37 AM Kunal Pathak @.***> wrote:

@RobertHenry6bev https://github.com/RobertHenry6bev - can you please confirm the full command you used to repro this?

— Reply to this email directly, view it on GitHub https://github.com/dotnet/runtime/issues/73927#issuecomment-1577280356, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBLLY4MBSBNFSSXPJKJRXDXJYRNTANCNFSM56RB5MXQ . You are receiving this because you were mentioned.Message ID: @.***>

kunalspathak commented 1 year ago

@AaronRobinsonMSFT - were you able to include ubsan in CI pipeline at all?

AaronRobinsonMSFT commented 1 year ago

@kunalspathak @jkoritzinsky is working on adding ubsan to the CI. I was able to reproduce this when it was first reported. Perhaps something has changed. Are you using g++12? I had to build a local copy at the time.

kunalspathak commented 1 year ago

@kunalspathak @jkoritzinsky is working on adding ubsan to the CI. I was able to reproduce this when it was first reported. Perhaps something has changed. Are you using g++12? I had to build a local copy at the time.

I am not sure what is the right command to do this? Can you please confirm and I can see if it repros or not.

kunalspathak commented 1 year ago

Assigning to @jkoritzinsky since he is working on test leg.

jkoritzinsky commented 1 year ago

I'm likely not going to have time to get to setting up the UBSan leg until .NET 9.

jkoritzinsky commented 4 months ago

Moving to infra as this is first blocked by getting the test leg up.

dotnet-policy-service[bot] commented 4 months ago

Tagging subscribers to this area: @dotnet/runtime-infrastructure See info in area-owners.md if you want to be subscribed.

RobertHenry6bev commented 4 months ago

I'm retiring from MSFT in ~3 weeks.

On Thu, May 16, 2024 at 3:29 PM dotnet-policy-service[bot] < @.***> wrote:

Tagging subscribers to this area: @dotnet/runtime-infrastructure https://github.com/orgs/dotnet/teams/runtime-infrastructure See info in area-owners.md https://github.com/dotnet/runtime/blob/main/docs/area-owners.md if you want to be subscribed.

— Reply to this email directly, view it on GitHub https://github.com/dotnet/runtime/issues/73927#issuecomment-2116307793, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBLLY27LBDY7JQ3VZ3MXCLZCUXLZAVCNFSM56RB5MX2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMJRGYZTANZXHEZQ . You are receiving this because you were mentioned.Message ID: @.***>