diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-09-29 18:37:15 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-09-30 10:44:16 +0200 |
commit | 43b02c4532d88ef24c688ecd32bc8bfd6e1f57ff (patch) | |
tree | bae93f748bbcdf70d52eb33f230c39733c565433 | |
parent | e6e01b50f5f20154ada1414cc70b1cf54b500262 (diff) |
Make sure space handed to C/C++ ABI is padded large enough
PythonTest_pyuno_pytests_testcollections had failed with -fsanitize=address:
> ==6341==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffe5cf77048 at pc 0x7f6be12e51ba bp 0x7ffe5cf76810 sp 0x7ffe5cf76808
> WRITE of size 8 at 0x7ffe5cf77048 thread T0
> #0 0x7f6be12e51b9 in x86_64::fill_struct(_typelib_TypeDescriptionReference*, unsigned long const*, double const*, void*) bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
> #1 0x7f6be1307f03 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:171:17
> #2 0x7f6be130346d in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233:13
> #3 0x7f6be1301c56 in bridges::cpp_uno::shared::unoInterfaceProxyDispatch(_uno_Interface*, _typelib_TypeDescription const*, void*, void**, _uno_Any**) bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:420:13
> #4 0x7f6be0be09ff in stoc_corefl::IdlInterfaceMethodImpl::invoke(com::sun::star::uno::Any const&, com::sun::star::uno::Sequence<com::sun::star::uno::Any>&) stoc/source/corereflection/criface.cxx:679:9
> #5 0x7f6be0be304c in non-virtual thunk to stoc_corefl::IdlInterfaceMethodImpl::invoke(com::sun::star::uno::Any const&, com::sun::star::uno::Sequence<com::sun::star::uno::Any>&) stoc/source/corereflection/criface.cxx
> #6 0x7f6be0375ef9 in (anonymous namespace)::IntrospectionAccessStatic_Impl::getPropertyValueByIndex(com::sun::star::uno::Any const&, int) const stoc/source/inspect/introspection.cxx:609:33
> #7 0x7f6be03753eb in (anonymous namespace)::IntrospectionAccessStatic_Impl::getPropertyValue(com::sun::star::uno::Any const&, rtl::OUString const&) const stoc/source/inspect/introspection.cxx:519:16
> #8 0x7f6be036bd75 in (anonymous namespace)::ImplIntrospectionAccess::getPropertyValue(rtl::OUString const&) stoc/source/inspect/introspection.cxx:1040:26
> #9 0x7f6be037102c in non-virtual thunk to (anonymous namespace)::ImplIntrospectionAccess::getPropertyValue(rtl::OUString const&) stoc/source/inspect/introspection.cxx
> #10 0x7f6be0f95805 in stoc_inv::Invocation_Impl::getValue(rtl::OUString const&) stoc/source/invocation/invocation.cxx:495:35
> #11 0x7f6be0f95fcc in non-virtual thunk to stoc_inv::Invocation_Impl::getValue(rtl::OUString const&) stoc/source/invocation/invocation.cxx
> #12 0x7f6be665d69a in pyuno::PyUNO_getattr(_object*, char*) pyuno/source/module/pyuno.cxx:1424:52
> #13 0x7f6bf34b1a5f in PyObject_GetAttr workdir/UnpackedTarball/python3/Objects/object.c:894:16
> #14 0x7f6bf39f10f9 in PyEval_EvalFrameEx workdir/UnpackedTarball/python3/Python/ceval.c:2793:29
...
Change-Id: I7c8aa0f0e153a022c19c981165730725a566a0b2
Reviewed-on: https://gerrit.libreoffice.org/42946
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r-- | stoc/source/corereflection/criface.cxx | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/stoc/source/corereflection/criface.cxx b/stoc/source/corereflection/criface.cxx index 841cb235eb90..9ead12622f54 100644 --- a/stoc/source/corereflection/criface.cxx +++ b/stoc/source/corereflection/criface.cxx @@ -18,6 +18,11 @@ */ #include <sal/config.h> + +#include <cassert> +#include <cstddef> +#include <limits> + #ifdef SAL_UNX #include <sal/alloca.h> #endif @@ -40,6 +45,15 @@ using namespace css::lang; using namespace css::reflection; using namespace css::uno; +namespace { + +std::size_t multipleOf16(std::size_t n) { + assert(n <= std::numeric_limits<std::size_t>::max() - 15); + return (n + 15) & ~std::size_t(15); +} + +} + namespace stoc_corefl { @@ -586,7 +600,12 @@ Any SAL_CALL IdlInterfaceMethodImpl::invoke( const Any & rObj, Sequence< Any > & TYPELIB_DANGER_GET( &pReturnType, getMethodTypeDescr()->pReturnTypeRef ); - void * pUnoReturn = alloca( pReturnType->nSize ); + // C/C++ ABIs typically assume that structs are padded at the end, and + // that those padding bytes may be written to (e.g., to write into the + // end of a "short" struct by writing the full contents of a "long" + // register); so create enough space here (assuming that no ABI requires + // padding larger than 16 byte boundaries): + void * pUnoReturn = alloca( multipleOf16(pReturnType->nSize) ); void ** ppUnoArgs = static_cast<void **>(alloca( sizeof(void *) * nParams *2 )); typelib_TypeDescription ** ppParamTypes = reinterpret_cast<typelib_TypeDescription **>(ppUnoArgs + nParams); |