[llvm-bugs] [Bug 33221] New: [UBSAN] segfault with -fsanitize=undefined

via llvm-bugs llvm-bugs at lists.llvm.org
Tue May 30 01:45:10 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=33221

            Bug ID: 33221
           Summary: [UBSAN] segfault with -fsanitize=undefined
           Product: compiler-rt
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: compiler-rt
          Assignee: unassignedbugs at nondot.org
          Reporter: d.khalikov at partner.samsung.com
                CC: llvm-bugs at lists.llvm.org

Created attachment 18534
  --> https://bugs.llvm.org/attachment.cgi?id=18534&action=edit
ubsan fix for vptr check

Hello everyone.

I have a situation when UBSAN got segfault.

Test case (that code actually close example of the code in package
groff-1.22.3.)

$cat test.cc

class Base {
public:
  Base *next;
  virtual void print() {}
};

class Derived : public Base {
public:
  void print() {}
};

enum { SIZE = 2 };

int main() {
  Derived *list = (Derived *)new char[SIZE * sizeof(Derived)];
  list->next = list + 1;
  return 0;
}

$clang++ -o test test.cc -fsanitize=undefined -fsanitize=address
$./test

And we will get following backtrace:

==3737==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc
0x00000051a9f2 bp 0x000000531bf8 sp 0x7ffc38852540 T0)
==3737==The signal is caused by a READ memory access.
==3737==Hint: address points to the zero page.
    #0 0x51a9f1 in getVtablePrefix
/llvm/projects/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc:200
    #1 0x51a9f1 in __ubsan::checkDynamicType(void*, void*, unsigned long)
/llvm/projects/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc:223
    #2 0x518942 in
HandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long,
unsigned long, __ubsan::ReportOptions)
/llvm/projects/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc:37
    #3 0x519232 in __ubsan_handle_dynamic_type_cache_miss
/llvm/projects/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc:87
    #4 0x51addd in main (/test/ubsan/test+0x51addd)
    #5 0x7ff8cad7ef44 in __libc_start_main
/build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287
    #6 0x41ac9b in _start (/test/ubsan/test+0x41ac9b)


As far as I understood vptr is initializing by constructor of the object. In
this code that doesn't happen, this code use operator new () of type char which
doesn't have default constructor. Standard says:
if default constructor is not specified
(7.3) no initialization is performed.
So, vptr could have a junk data, at the beginning of the object, which 
cause a segfault in function getVtablePrefix.

Should we check Vptr with 
if (!IsAccessibleMemoryRange((uptr)Vptr, sizeof(VtablePrefix)))
instead 
if (!Vptr)

I've attached patch for this issue.

Thanks.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170530/8ae1619e/attachment.html>


More information about the llvm-bugs mailing list