Skip to content

UBSan vptr check nuisance reports when calling member functions of COM interfaces #101026

Open
@alvinhochun

Description

When calling member functions of COM interfaces, the vptr check gets triggered. Demo:

#include <windows.h>
#include <shlobj.h>

int main(int argc, char *argv[]) {
    CoInitialize(nullptr);
    IShellLinkW *shell_link;
    CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IShellLinkW), (void **)&shell_link);
    shell_link->SetPath(L"C:\\");
    IPersistFile *persist_file;
    shell_link->QueryInterface(__uuidof(IPersistFile), (void **)&persist_file);
    wchar_t path[4096];
    GetFullPathNameW(L"vptr_test.lnk", 4096, path, nullptr);
    persist_file->Save(path, false);
    return 0;
}

Using llvm-mingw:

> clang++ -fsanitize=undefined,vptr vptr_test.cpp -o vptr_test.exe -lole32

> vptr_test.exe
vptr_test.cpp:8:17: runtime error: member call on address 0x0255481a1ca0 which does not point to an object of type 'IShellLinkW'
0x0255481a1ca0: note: object has a possibly invalid vptr: abs(offset to top) too big
 fe 7f 00 00  c8 8a 59 2f fe 7f 00 00  88 8a 59 2f fe 7f 00 00  68 8a 59 2f fe 7f 00 00  20 8a 59 2f
              ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vptr_test.cpp:8:17
vptr_test.cpp:10:17: runtime error: member call on address 0x0255481a1ca0 which does not point to an object of type 'IUnknown'
0x0255481a1ca0: note: object has a possibly invalid vptr: abs(offset to top) too big
 fe 7f 00 00  c8 8a 59 2f fe 7f 00 00  88 8a 59 2f fe 7f 00 00  68 8a 59 2f fe 7f 00 00  20 8a 59 2f
              ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vptr_test.cpp:10:17
vptr_test.cpp:13:19: runtime error: member call on address 0x0255481a1cb8 which does not point to an object of type 'IPersistFile'
0x0255481a1cb8: note: object has a possibly invalid vptr: abs(offset to top) too big
 fe 7f 00 00  20 8a 59 2f fe 7f 00 00  00 8a 59 2f fe 7f 00 00  c0 89 59 2f fe 7f 00 00  88 89 59 2f
              ^~~~~~~~~~~~~~~~~~~~~~~
              possibly invalid vptr
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vptr_test.cpp:13:19

Maybe the reports are correct in the strictest sense, but this is fundamentally how COM works on Windows. This practically makes the vptr check unusable if any code uses any native APIs that are accessed through COM interfaces. Could it be possible for UBSan to detect that these types are COM interfaces (say, checks that the type inherits IUnknown) and suppress the check?

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions