diff options
-rw-r--r-- | cppu/source/uno/copy.hxx | 26 | ||||
-rw-r--r-- | external/gpgmepp/UnpackedTarball_gpgmepp.mk | 1 | ||||
-rw-r--r-- | external/gpgmepp/ubsan.patch | 52 |
3 files changed, 76 insertions, 3 deletions
diff --git a/cppu/source/uno/copy.hxx b/cppu/source/uno/copy.hxx index b0811b5fab10..b24e0e337bf5 100644 --- a/cppu/source/uno/copy.hxx +++ b/cppu/source/uno/copy.hxx @@ -22,7 +22,9 @@ #include "prim.hxx" #include "constr.hxx" #include <cassert> +#include <cstddef> #include <cstdlib> +#include <type_traits> namespace cppu { @@ -30,6 +32,22 @@ namespace cppu //#### copy construction ########################################################################### +namespace { + +// The non-dynamic prefix of sal_Sequence (aka uno_Sequence): +struct SequencePrefix { + sal_Int32 nRefCount; + sal_Int32 nElements; +}; +static_assert(sizeof (SequencePrefix) < sizeof (uno_Sequence)); +static_assert(offsetof(SequencePrefix, nRefCount) == offsetof(uno_Sequence, nRefCount)); +static_assert( + std::is_same_v<decltype(SequencePrefix::nRefCount), decltype(uno_Sequence::nRefCount)>); +static_assert(offsetof(SequencePrefix, nElements) == offsetof(uno_Sequence, nElements)); +static_assert( + std::is_same_v<decltype(SequencePrefix::nElements), decltype(uno_Sequence::nElements)>); + +} inline uno_Sequence * allocSeq( sal_Int32 nElementSize, sal_Int32 nElements ) @@ -42,9 +60,11 @@ inline uno_Sequence * allocSeq( pSeq = static_cast<uno_Sequence *>(std::malloc( nSize )); if (pSeq != nullptr) { - // header init - pSeq->nRefCount = 1; - pSeq->nElements = nElements; + // header init, going via SequencePrefix to avoid UBSan insufficient-object-size + // warnings when `nElements == 0` and thus `nSize < sizeof (uno_Sequence)`: + auto const header = reinterpret_cast<SequencePrefix *>(pSeq); + header->nRefCount = 1; + header->nElements = nElements; } } return pSeq; diff --git a/external/gpgmepp/UnpackedTarball_gpgmepp.mk b/external/gpgmepp/UnpackedTarball_gpgmepp.mk index 9fc213c7e51c..1b0468fc6f23 100644 --- a/external/gpgmepp/UnpackedTarball_gpgmepp.mk +++ b/external/gpgmepp/UnpackedTarball_gpgmepp.mk @@ -32,5 +32,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,gpgmepp, \ $(if $(filter LINUX,$(OS)),external/gpgmepp/rpath.patch) \ external/gpgmepp/gcc9.patch \ external/gpgmepp/version.patch \ + external/gpgmepp/ubsan.patch \ )) # vim: set noet sw=4 ts=4: diff --git a/external/gpgmepp/ubsan.patch b/external/gpgmepp/ubsan.patch new file mode 100644 index 000000000000..5a6e6dcdc9b2 --- /dev/null +++ b/external/gpgmepp/ubsan.patch @@ -0,0 +1,52 @@ +--- src/engine-gpg.c ++++ src/engine-gpg.c +@@ -60,6 +60,15 @@ + building command line to this location. */ + char arg[1]; /* Used if data above is not used. */ + }; ++struct arg_without_data_s ++{ ++ struct arg_and_data_s *next; ++ gpgme_data_t data; ++ int inbound; ++ int dup_to; ++ int print_fd; ++ int *arg_locp; ++}; + + + struct fd_data_map_s +@@ -299,23 +308,24 @@ + a = malloc (sizeof *a - 1); + if (!a) + return gpg_error_from_syserror (); +- a->next = NULL; +- a->data = data; +- a->inbound = inbound; +- a->arg_locp = NULL; ++ struct arg_without_data_s *a2 = (struct arg_without_data_s *)a; ++ a2->next = NULL; ++ a2->data = data; ++ a2->inbound = inbound; ++ a2->arg_locp = NULL; + + if (dup_to == -2) + { +- a->print_fd = 1; +- a->dup_to = -1; ++ a2->print_fd = 1; ++ a2->dup_to = -1; + } + else + { +- a->print_fd = 0; +- a->dup_to = dup_to; ++ a2->print_fd = 0; ++ a2->dup_to = dup_to; + } + *gpg->argtail = a; +- gpg->argtail = &a->next; ++ gpg->argtail = &a2->next; + return 0; + } + |