QPluginLoader/ELF: fix Clang ASan builds

Clang aligns the object at 32-byte boundaries even though we
specifically asked for alignof(void*), so tell it not to sanitize the
address of the plugin object. Tested with Clang 12 and 13.

GCC seems not to be affected, even when ASan is enabled.

If this doesn't work, we may need to accept reading a note that is
improperly aligned. I don't think the output will be actually a correct
note because the intra-note alignment will be wrong (I carefully chose
the ELF note name so it would not require alignment, but that's only
valid up to 8-byte alignments).

Fixes: QTBUG-97941
Change-Id: Ice04365c72984d07a64dfffd16b422fe074d8a70
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2021-11-03 13:23:59 -07:00 committed by Andrei Golubev
parent 9f559699cc
commit 0ab3c5c250
2 changed files with 12 additions and 2 deletions

View File

@ -199,7 +199,15 @@ template <auto (&PluginMetaData)> class QPluginMetaDataV2
# define QT_PLUGIN_METADATAV2_SECTION
using Payload = StaticPayload;
#elif defined(Q_OF_ELF)
# define QT_PLUGIN_METADATAV2_SECTION __attribute__((section(".note.qt.metadata"), used, aligned(alignof(void*))))
# ifdef Q_CC_CLANG
// the metadata section doesn't work well with clang's sanitizer - QTBUG-97941
# define QT_PLUGIN_METADATAV2_SECTION \
__attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *)), \
no_sanitize("address")))
# else
# define QT_PLUGIN_METADATAV2_SECTION \
__attribute__((section(".note.qt.metadata"), used, aligned(alignof(void *))))
# endif
using Payload = ElfNotePayload;
#else
# define QT_PLUGIN_METADATAV2_SECTION QT_PLUGIN_METADATA_SECTION

View File

@ -50,7 +50,9 @@ static constexpr bool IsDebug = false;
#endif
#if defined(__ELF__) && PLUGIN_VERSION >= 1
__attribute__((section(".note.qt.metadata"), used, aligned(4)))
// GCC will produce:
// fakeplugin.cpp:64:3: warning: no_sanitize_address attribute ignored [-Wattributes]
__attribute__((section(".note.qt.metadata"), used, no_sanitize("address"), aligned(sizeof(void*))))
static const struct {
unsigned n_namesz = sizeof(name);
unsigned n_descsz = sizeof(payload);