UBSan vptr check nuisance reports when calling member functions of COM interfaces #101026
Open
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?