trailofbits / multiplier

Code auditing productivity multiplier.
Apache License 2.0
439 stars 27 forks source link

Assert on serializing the CallExpr #488

Open kumarak opened 11 months ago

kumarak commented 11 months ago

The serialization of the CallExpr fails while getting the CallReturnType. This is because the callee type is an elaborate type for Class template specialization and can't be cast to FunctionType

    frame #0: 0x00007ff80945f7a2 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007ff809497f30 libsystem_pthread.dylib`pthread_kill + 262
    frame #2: 0x00007ff8093b6a49 libsystem_c.dylib`abort + 126
    frame #3: 0x00007ff8093b5d30 libsystem_c.dylib`__assert_rtn + 314
    frame #4: 0x00000001019372a0 mx-index`clang::FunctionType const* clang::Type::castAs<clang::FunctionType>(this=0x00007fb06d2adbf0) const at Type.h:7544:3
  * frame #5: 0x0000000104aa4a3d mx-index`clang::CallExpr::getCallReturnType(this=0x00007fb06d2ae3d0, Ctx=0x00007fb0800e2e00) const at Expr.cpp:1639:44
    frame #6: 0x0000000101a8935c mx-index`pasta::CallExpr::CallReturnType(this=0x00007000255b8aa0) const at Stmt.cpp:14062:29
    frame #7: 0x000000010002b63e mx-index`indexer::(anonymous namespace)::FragmentBuilder::VisitCallExpr(this=0x00007000255b8e98, entity=0x00007000255b8aa0) at Visitor.inc.h:15711:3
    frame #8: 0x0000000100026d67 mx-index`indexer::(anonymous namespace)::FragmentBuilder::Accept(this=0x00007000255b8e98, entity=0x00007000255b8aa0) at BuildPendingFragment.cpp:195:5
    frame #9: 0x00000001000265fa mx-index`auto indexer::BuildPendingFragment(indexer::PendingFragment&)::$_0::operator()<std::__1::vector<pasta::Stmt, std::__1::allocator<pasta::Stmt>>>(this=0x00007000255b8c28, list=size=4, prev_size=0x0000600000945d38, changed=0x00007000255b8c1e) const at BuildPendingFragment.cpp:515:15

CallExpr node:

CallExpr 0x7fb06d2ae3d0 '<dependent type>'
|-CXXTemporaryObjectExpr 0x7fb06d2ae278 '__less<>':'struct std::__less<void, void>' 'void (void) noexcept' zeroing
|-DeclRefExpr 0x7fb06d2ae390 'const _Up *' lvalue ParmVar 0x7fb06d2ad270 '__ptr' 'const _Up *'
`-DeclRefExpr 0x7fb06d2ae3b0 'const _Tp *' lvalue ParmVar 0x7fb06d2ad180 '__begin' 'const _Tp *'
kumarak commented 11 months ago

We patched the clang for handling the Callee that are of Builtin Type. In the case of Builtin, we get the direct callee and get the return type for it. For handling this case we may need to add further patch in clang and probably return the constructor type for the temporary object.

This is how the source code looks like:

template <class _Tp, class _Up, __enable_if_t<__is_less_than_comparable<const _Tp*, const _Up*>::value, int> = 0>
constexpr __attribute__((__visibility__("hidden"))) __attribute__((__exclude_from_explicit_instantiation__)) __attribute__((__abi_tag__("ue170004"))) __attribute__((__no_sanitize__("address"))) bool __is_pointer_in_range(
    const _Tp* __begin, const _Tp* __end, const _Up* __ptr) {
  if (__libcpp_is_constant_evaluated()) {
    ((void)0);
    if (!__builtin_constant_p(__begin <= __ptr && __ptr < __end))
      return false;
  }
  return !__less<>()(__ptr, __begin) && __less<>()(__ptr, __end);
}

where __less<> is the class template specialization.