From d34dae1817f589014bca224230bfd5bb81dfc6a6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 13:08:33 +0100 Subject: [PATCH 01/12] tree-wide: use gcc attribute macros where appropriate We have these macros already, hence use them. --- src/basic/hashmap.c | 2 +- src/basic/process-util.c | 2 +- src/basic/static-destruct.h | 4 ++-- src/basic/util.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c index eba56add1f..edcdfb8652 100644 --- a/src/basic/hashmap.c +++ b/src/basic/hashmap.c @@ -276,7 +276,7 @@ static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = { }; #if VALGRIND -__attribute__((destructor)) static void cleanup_pools(void) { +_destructor_ static void cleanup_pools(void) { _cleanup_free_ char *t = NULL; int r; diff --git a/src/basic/process-util.c b/src/basic/process-util.c index d1a34338f6..981628504b 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -1172,7 +1172,7 @@ void reset_cached_pid(void) { * headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against * libpthread, as it is part of glibc anyway. */ extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void *dso_handle); -extern void* __dso_handle __attribute__ ((__weak__)); +extern void* __dso_handle _weak_; pid_t getpid_cached(void) { static bool installed = false; diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h index cad838083f..b780985d11 100644 --- a/src/basic/static-destruct.h +++ b/src/basic/static-destruct.h @@ -32,8 +32,8 @@ typedef struct StaticDestructor { /* Beginning and end of our section listing the destructors. We define these as weak as we want this to work even if * there's not a single destructor is defined in which case the section will be missing. */ -extern const struct StaticDestructor __attribute__((__weak__)) __start_SYSTEMD_STATIC_DESTRUCT[]; -extern const struct StaticDestructor __attribute__((__weak__)) __stop_SYSTEMD_STATIC_DESTRUCT[]; +extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT[]; +extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT[]; /* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in the same * linking unit as the variables we want to destroy. */ diff --git a/src/basic/util.h b/src/basic/util.h index 2f3d1eeab8..43f4081190 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -173,7 +173,7 @@ static inline void _reset_errno_(int *saved_errno) { } #define PROTECT_ERRNO \ - _cleanup_(_reset_errno_) __attribute__((__unused__)) int _saved_errno_ = errno + _cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno static inline int negative_errno(void) { /* This helper should be used to shut up gcc if you know 'errno' is From d752090f3efebe6d71e5baf994f694f6dc9bd43c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 13:10:09 +0100 Subject: [PATCH 02/12] macro: add macros for a couple of more gcc attributes we use --- src/basic/macro.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/basic/macro.h b/src/basic/macro.h index f54f13e4fe..4e37bed9ca 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -15,6 +15,8 @@ # define _alloc_(...) __attribute__ ((__alloc_size__(__VA_ARGS__))) #endif #define _sentinel_ __attribute__ ((__sentinel__)) +#define _section_(x) __attribute__((__section__(x))) +#define _used_ __attribute__((__used__)) #define _unused_ __attribute__ ((__unused__)) #define _destructor_ __attribute__ ((__destructor__)) #define _pure_ __attribute__ ((__pure__)) @@ -28,7 +30,9 @@ #define _public_ __attribute__ ((__visibility__("default"))) #define _hidden_ __attribute__ ((__visibility__("hidden"))) #define _weakref_(x) __attribute__((__weakref__(#x))) +#define _align_(x) __attribute__((__aligned__(x))) #define _alignas_(x) __attribute__((__aligned__(__alignof(x)))) +#define _alignptr_ __attribute__((__aligned__(sizeof(void*)))) #define _cleanup_(x) __attribute__((__cleanup__(x))) #if __GNUC__ >= 7 #define _fallthrough_ __attribute__((__fallthrough__)) From 2ee1c55d6c35c813e161787b6c147715377d8b29 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 13:15:09 +0100 Subject: [PATCH 03/12] tree-wide: drop redundant space between __attribute__ and (( We follow no general rule, but in most cases we do not place a space outside of macro.h. Hence let's stick to that, and adapt macro.h too, and follow the rule systematically that there shall not be a space between __attribute__ and ((... Yes, this does not matter at all, and is purely OCD cosmetics. But then again, the uses of __attribute__ are very local only, hence the changes cleaning this up are small and are unlikely to have to be repeated too often... --- src/basic/macro.h | 26 +++++++++++++------------- src/boot/efi/measure.c | 4 ++-- src/systemd/_sd-common.h | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 4e37bed9ca..f8a8145de5 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -8,27 +8,27 @@ #include #include -#define _printf_(a, b) __attribute__ ((__format__(printf, a, b))) +#define _printf_(a, b) __attribute__((__format__(printf, a, b))) #ifdef __clang__ # define _alloc_(...) #else -# define _alloc_(...) __attribute__ ((__alloc_size__(__VA_ARGS__))) +# define _alloc_(...) __attribute__((__alloc_size__(__VA_ARGS__))) #endif -#define _sentinel_ __attribute__ ((__sentinel__)) +#define _sentinel_ __attribute__((__sentinel__)) #define _section_(x) __attribute__((__section__(x))) #define _used_ __attribute__((__used__)) -#define _unused_ __attribute__ ((__unused__)) -#define _destructor_ __attribute__ ((__destructor__)) -#define _pure_ __attribute__ ((__pure__)) -#define _const_ __attribute__ ((__const__)) -#define _deprecated_ __attribute__ ((__deprecated__)) -#define _packed_ __attribute__ ((__packed__)) -#define _malloc_ __attribute__ ((__malloc__)) -#define _weak_ __attribute__ ((__weak__)) +#define _unused_ __attribute__((__unused__)) +#define _destructor_ __attribute__((__destructor__)) +#define _pure_ __attribute__((__pure__)) +#define _const_ __attribute__((__const__)) +#define _deprecated_ __attribute__((__deprecated__)) +#define _packed_ __attribute__((__packed__)) +#define _malloc_ __attribute__((__malloc__)) +#define _weak_ __attribute__((__weak__)) #define _likely_(x) (__builtin_expect(!!(x), 1)) #define _unlikely_(x) (__builtin_expect(!!(x), 0)) -#define _public_ __attribute__ ((__visibility__("default"))) -#define _hidden_ __attribute__ ((__visibility__("hidden"))) +#define _public_ __attribute__((__visibility__("default"))) +#define _hidden_ __attribute__((__visibility__("hidden"))) #define _weakref_(x) __attribute__((__weakref__(#x))) #define _align_(x) __attribute__((__aligned__(x))) #define _alignas_(x) __attribute__((__aligned__(__alignof(x)))) diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index 9cb24f2fec..243c80a835 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -132,13 +132,13 @@ typedef struct { UINT16 HeaderVersion; UINT32 PCRIndex; UINT32 EventType; -} __attribute__ ((packed)) EFI_TCG2_EVENT_HEADER; +} __attribute__((packed)) EFI_TCG2_EVENT_HEADER; typedef struct tdEFI_TCG2_EVENT { UINT32 Size; EFI_TCG2_EVENT_HEADER Header; UINT8 Event[1]; -} __attribute__ ((packed)) EFI_TCG2_EVENT; +} __attribute__((packed)) EFI_TCG2_EVENT; typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This, IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability); diff --git a/src/systemd/_sd-common.h b/src/systemd/_sd-common.h index b026b5c551..6fd9244a01 100644 --- a/src/systemd/_sd-common.h +++ b/src/systemd/_sd-common.h @@ -25,7 +25,7 @@ #ifndef _sd_printf_ # if __GNUC__ >= 4 -# define _sd_printf_(a,b) __attribute__ ((__format__(printf, a, b))) +# define _sd_printf_(a,b) __attribute__((__format__(printf, a, b))) # else # define _sd_printf_(a,b) # endif From 90b365cee03bab9b4925f2e918c362c4183f8e92 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 13:17:28 +0100 Subject: [PATCH 04/12] json: use new _align_() macro --- src/shared/json.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/json.h b/src/shared/json.h index 278ff77d30..4a21a411ac 100644 --- a/src/shared/json.h +++ b/src/shared/json.h @@ -274,9 +274,9 @@ int json_log_internal(JsonVariant *variant, int level, int error, const char *fi #define JSON_VARIANT_STRING_CONST(x) _JSON_VARIANT_STRING_CONST(UNIQ, (x)) -#define _JSON_VARIANT_STRING_CONST(xq, x) \ +#define _JSON_VARIANT_STRING_CONST(xq, x) \ ({ \ - __attribute__((__aligned__(2))) static const char UNIQ_T(json_string_const, xq)[] = (x); \ + _align_(2) static const char UNIQ_T(json_string_const, xq)[] = (x); \ assert((((uintptr_t) UNIQ_T(json_string_const, xq)) & 1) == 0); \ (JsonVariant*) ((uintptr_t) UNIQ_T(json_string_const, xq) + 1); \ }) From a898603563ffb21af5cf8dc91f9a516a41743991 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 13:22:15 +0100 Subject: [PATCH 05/12] sd-bus,static-destruct: clean up how we do our ELF section magic This cleans up a bit how we set up things for the ELF section magic: 1. Let's always use our gcc macros, instead of __attribute__ directly 2. Align our structures to sizeof(void*), i.e. the pointer size, rather than a fixed 8 or __BIGGEST_ALIGNMENT__. The former is unnecessarily high for 32bit systems, the latter too high for 64bit systems. gcc seems to use ptr alignment for static variables itself, hence this should be good enough for us too. Moreover, the Linux kernel also uses pointer alginment for all its ELF section registration magic, hence this should be good enough for us too. 3. Let's always prefix the sections we create ourself with SYSTEMD_, just to make clear where they come from. 4. Always align the pointer we start from when iterating through these lists. This should be unnecessary, but makes things nicely systematic, as we'll align all pointers we use to access these sections properly. --- src/basic/static-destruct.h | 10 +++++----- src/libsystemd/sd-bus/bus-error.c | 10 +++++----- src/libsystemd/sd-bus/bus-error.h | 8 ++++---- src/libsystemd/sd-bus/test-bus-error.c | 10 +++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h index b780985d11..5c0bea31a6 100644 --- a/src/basic/static-destruct.h +++ b/src/basic/static-destruct.h @@ -22,9 +22,9 @@ typedef struct StaticDestructor { func(q); \ } \ /* The actual destructor structure */ \ - __attribute__ ((__section__("SYSTEMD_STATIC_DESTRUCT"))) \ - __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) \ - __attribute__ ((__used__)) \ + _section_("SYSTEMD_STATIC_DESTRUCT") \ + _alignptr_ \ + _used_ \ static const StaticDestructor UNIQ_T(static_destructor_entry, uq) = { \ .data = &(variable), \ .destroy = UNIQ_T(static_destructor_wrapper, uq), \ @@ -43,9 +43,9 @@ static inline void static_destruct(void) { if (!__start_SYSTEMD_STATIC_DESTRUCT) return; - d = ALIGN_TO_PTR(__start_SYSTEMD_STATIC_DESTRUCT, __BIGGEST_ALIGNMENT__); + d = ALIGN_TO_PTR(__start_SYSTEMD_STATIC_DESTRUCT, sizeof(void*)); while (d < __stop_SYSTEMD_STATIC_DESTRUCT) { d->destroy(d->data); - d = ALIGN_TO_PTR(d + 1, __BIGGEST_ALIGNMENT__); + d = ALIGN_TO_PTR(d + 1, sizeof(void*)); } } diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 5ef643134e..06097d0b48 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -54,8 +54,8 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_standard_errors[] = { }; /* GCC maps this magically to the beginning and end of the BUS_ERROR_MAP section */ -extern const sd_bus_error_map __start_BUS_ERROR_MAP[]; -extern const sd_bus_error_map __stop_BUS_ERROR_MAP[]; +extern const sd_bus_error_map __start_SYSTEMD_BUS_ERROR_MAP[]; +extern const sd_bus_error_map __stop_SYSTEMD_BUS_ERROR_MAP[]; /* Additional maps registered with sd_bus_error_add_map() are in this * NULL terminated array */ @@ -89,9 +89,9 @@ static int bus_error_name_to_errno(const char *name) { return m->code; } - m = __start_BUS_ERROR_MAP; + m = ALIGN_TO_PTR(__start_SYSTEMD_BUS_ERROR_MAP, sizeof(void*)); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - while (m < __stop_BUS_ERROR_MAP) { + while (m < __stop_SYSTEMD_BUS_ERROR_MAP) { /* For magic ELF error maps, the end marker might * appear in the middle of things, since multiple maps * might appear in the same section. Hence, let's skip @@ -99,7 +99,7 @@ static int bus_error_name_to_errno(const char *name) { * boundary, which is the selected alignment for the * arrays. */ if (m->code == BUS_ERROR_MAP_END_MARKER) { - m = ALIGN8_PTR(m+1); + m = ALIGN_TO_PTR(m + 1, sizeof(void*)); continue; } diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index e8e743c0d7..c1758c46bb 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -31,13 +31,13 @@ int bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_lis */ #define BUS_ERROR_MAP_ELF_REGISTER \ - __attribute__ ((__section__("BUS_ERROR_MAP"))) \ - __attribute__ ((__used__)) \ - __attribute__ ((__aligned__(8))) + _section_("SYSTEMD_BUS_ERROR_MAP") \ + _used_ \ + _alignptr_ #define BUS_ERROR_MAP_ELF_USE(errors) \ extern const sd_bus_error_map errors[]; \ - __attribute__ ((__used__)) \ + _used_ \ static const sd_bus_error_map * const CONCATENATE(errors ## _copy_, __COUNTER__) = errors; /* We use something exotic as end marker, to ensure people build the diff --git a/src/libsystemd/sd-bus/test-bus-error.c b/src/libsystemd/sd-bus/test-bus-error.c index 8f1fc54520..f464b5b23d 100644 --- a/src/libsystemd/sd-bus/test-bus-error.c +++ b/src/libsystemd/sd-bus/test-bus-error.c @@ -113,18 +113,18 @@ static void test_error(void) { assert_se(!sd_bus_error_is_set(&error)); } -extern const sd_bus_error_map __start_BUS_ERROR_MAP[]; -extern const sd_bus_error_map __stop_BUS_ERROR_MAP[]; +extern const sd_bus_error_map __start_SYSTEMD_BUS_ERROR_MAP[]; +extern const sd_bus_error_map __stop_SYSTEMD_BUS_ERROR_MAP[]; static void dump_mapping_table(void) { const sd_bus_error_map *m; printf("----- errno mappings ------\n"); - m = __start_BUS_ERROR_MAP; - while (m < __stop_BUS_ERROR_MAP) { + m = ALIGN_TO_PTR(__start_SYSTEMD_BUS_ERROR_MAP, sizeof(void*)); + while (m < __stop_SYSTEMD_BUS_ERROR_MAP) { if (m->code == BUS_ERROR_MAP_END_MARKER) { - m = ALIGN8_PTR(m+1); + m = ALIGN_TO_PTR(m + 1, sizeof(void*)); continue; } From f36c39aae548a9189e5acbfdc010e4e347b5de84 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 13:37:18 +0100 Subject: [PATCH 06/12] test: add test for static destructor --- src/test/meson.build | 4 ++++ src/test/test-static-destruct.c | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/test/test-static-destruct.c diff --git a/src/test/meson.build b/src/test/meson.build index f1115d7b64..9863ecc8f0 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -177,6 +177,10 @@ tests += [ [], []], + [['src/test/test-static-destruct.c'], + [], + []], + [['src/test/test-sigbus.c'], [], []], diff --git a/src/test/test-static-destruct.c b/src/test/test-static-destruct.c new file mode 100644 index 0000000000..eb0523d87a --- /dev/null +++ b/src/test/test-static-destruct.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "alloc-util.h" +#include "static-destruct.h" +#include "tests.h" + +static int foo = 0; +static int bar = 0; +static int baz = 0; +static char* memory = NULL; + +static void test_destroy(int *b) { + (*b)++; +} + +STATIC_DESTRUCTOR_REGISTER(foo, test_destroy); +STATIC_DESTRUCTOR_REGISTER(bar, test_destroy); +STATIC_DESTRUCTOR_REGISTER(bar, test_destroy); +STATIC_DESTRUCTOR_REGISTER(baz, test_destroy); +STATIC_DESTRUCTOR_REGISTER(baz, test_destroy); +STATIC_DESTRUCTOR_REGISTER(baz, test_destroy); +STATIC_DESTRUCTOR_REGISTER(memory, freep); + +int main(int argc, char *argv[]) { + test_setup_logging(LOG_INFO); + + assert_se(memory = strdup("hallo")); + + assert_se(foo == 0 && bar == 0 && baz == 0); + static_destruct(); + assert_se(foo == 1 && bar == 2 && baz == 3); + + return EXIT_SUCCESS; +} From 289acab951c5937fdf6d3a2666f411fd66dd20e5 Mon Sep 17 00:00:00 2001 From: Evgeny Vereshchagin Date: Sun, 2 Dec 2018 08:28:24 +0100 Subject: [PATCH 07/12] util-lib: introduce HAS_FEATURE_ADDRESS_SANITIZER https://clang.llvm.org/docs/AddressSanitizer.html#conditional-compilation-with-has-feature-address-sanitizer --- src/basic/macro.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/basic/macro.h b/src/basic/macro.h index f8a8145de5..42ee753532 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -60,6 +60,17 @@ # endif #endif +#if !defined(HAS_FEATURE_ADDRESS_SANITIZER) +# if defined(__has_feature) +# if __has_feature(address_sanitizer) +# define HAS_FEATURE_ADDRESS_SANITIZER 1 +# endif +# endif +# if !defined(HAS_FEATURE_ADDRESS_SANITIZER) +# define HAS_FEATURE_ADDRESS_SANITIZER 0 +# endif +#endif + /* Temporarily disable some warnings */ #define DISABLE_WARNING_FORMAT_NONLITERAL \ _Pragma("GCC diagnostic push"); \ From be5f77b26e22a806179c7b03e03d424682ed325c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 17:30:19 +0100 Subject: [PATCH 08/12] macro: define HAS_FEATURE_ADDRESS_SANITIZER also on gcc Let's make differences between compilers more minimal. --- src/basic/macro.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 42ee753532..2213d4b9ac 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -61,7 +61,9 @@ #endif #if !defined(HAS_FEATURE_ADDRESS_SANITIZER) -# if defined(__has_feature) +# ifdef __SANITIZE_ADDRESS__ +# define HAS_FEATURE_ADDRESS_SANITIZER 1 +# elif defined(__has_feature) # if __has_feature(address_sanitizer) # define HAS_FEATURE_ADDRESS_SANITIZER 1 # endif From 026c2677fc9ad6baf32dadc640c58a11dfc09bf1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 17:30:43 +0100 Subject: [PATCH 09/12] macro: add macro for llvm no_sanitize_address attribute We want it for global variables, which LLVM supports and GCC currently does not (GCC does support it for functions, but we care about global variables here). Why is this relevant? When asan is used global variables are padded with hotzones before and after. But we can't have that for the registration variables we place in special ELF sections: we want them tightly packed so that we can iterate through them. Note that for gcc this isn't an issue, as it will pack stuff in non-standard sections anyway, even if asan is used. --- src/basic/macro.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/basic/macro.h b/src/basic/macro.h index 2213d4b9ac..05956a50bf 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -73,6 +73,16 @@ # endif #endif +/* Note: on GCC "no_sanitize_address" is a function attribute only, on llvm it may also be applied to global + * variables. We define a specific macro which knows this. Note that on GCC we don't need this decorator so much, since + * our primary usecase for this attribute is registration structures placed in named ELF sections which shall not be + * padded, but GCC doesn't pad those anyway if AddressSanitizer is enabled. */ +#if HAS_FEATURE_ADDRESS_SANITIZER && defined(__clang__) +#define _variable_no_sanitize_address_ __attribute__((__no_sanitize_address__)) +#else +#define _variable_no_sanitize_address_ +#endif + /* Temporarily disable some warnings */ #define DISABLE_WARNING_FORMAT_NONLITERAL \ _Pragma("GCC diagnostic push"); \ From 7fdf40d247361a510661915fbbddddb97b9aa8ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 17:33:28 +0100 Subject: [PATCH 10/12] static-destruct: turn on new _variable_no_sanitize_address_ variable for STATIC_DESTRUCTOR_REGISTER --- src/basic/static-destruct.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/basic/static-destruct.h b/src/basic/static-destruct.h index 5c0bea31a6..9f7392121d 100644 --- a/src/basic/static-destruct.h +++ b/src/basic/static-destruct.h @@ -21,10 +21,14 @@ typedef struct StaticDestructor { typeof(variable) *q = p; \ func(q); \ } \ - /* The actual destructor structure */ \ + /* The actual destructor structure we place in a special section to find it */ \ _section_("SYSTEMD_STATIC_DESTRUCT") \ + /* We pick pointer alignment, since that is apparently what gcc does for static variables */ \ _alignptr_ \ + /* Make sure this is not dropped from the image because not explicitly referenced */ \ _used_ \ + /* Make sure that AddressSanitizer doesn't pad this variable: we want everything in this section packed next to each other so that we can enumerate it. */ \ + _variable_no_sanitize_address_ \ static const StaticDestructor UNIQ_T(static_destructor_entry, uq) = { \ .data = &(variable), \ .destroy = UNIQ_T(static_destructor_wrapper, uq), \ From 02e062262f39a3002c1242954d4b04a5061d69bf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 17:33:42 +0100 Subject: [PATCH 11/12] sd-bus: use _variable_no_sanitize_address_ also for BUS_ERROR_MAP_ELF_REGISTER --- src/libsystemd/sd-bus/bus-error.c | 2 -- src/libsystemd/sd-bus/bus-error.h | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c index 06097d0b48..dc952375b6 100644 --- a/src/libsystemd/sd-bus/bus-error.c +++ b/src/libsystemd/sd-bus/bus-error.c @@ -90,7 +90,6 @@ static int bus_error_name_to_errno(const char *name) { } m = ALIGN_TO_PTR(__start_SYSTEMD_BUS_ERROR_MAP, sizeof(void*)); -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION while (m < __stop_SYSTEMD_BUS_ERROR_MAP) { /* For magic ELF error maps, the end marker might * appear in the middle of things, since multiple maps @@ -108,7 +107,6 @@ static int bus_error_name_to_errno(const char *name) { m++; } -#endif return EIO; } diff --git a/src/libsystemd/sd-bus/bus-error.h b/src/libsystemd/sd-bus/bus-error.h index c1758c46bb..a6523e57a2 100644 --- a/src/libsystemd/sd-bus/bus-error.h +++ b/src/libsystemd/sd-bus/bus-error.h @@ -33,7 +33,8 @@ int bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_lis #define BUS_ERROR_MAP_ELF_REGISTER \ _section_("SYSTEMD_BUS_ERROR_MAP") \ _used_ \ - _alignptr_ + _alignptr_ \ + _variable_no_sanitize_address_ #define BUS_ERROR_MAP_ELF_USE(errors) \ extern const sd_bus_error_map errors[]; \ From 0df54921bc3567db80eb894b01b2b5a6ea3d7c02 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 3 Dec 2018 17:38:50 +0100 Subject: [PATCH 12/12] tree-wide: use new macro HAS_FEATURE_ADDRESS_SANITIZER everywhere --- src/journal/lookup3.c | 6 +++--- src/libsystemd/sd-bus/test-bus-marshal.c | 2 +- src/test/test-capability.c | 2 +- src/test/test-execute.c | 2 +- src/test/test-sigbus.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/journal/lookup3.c b/src/journal/lookup3.c index ff194dd951..6c61f17c7d 100644 --- a/src/journal/lookup3.c +++ b/src/journal/lookup3.c @@ -319,7 +319,7 @@ uint32_t jenkins_hashlittle( const void *key, size_t length, uint32_t initval) * still catch it and complain. The masking trick does make the hash * noticeably faster for short strings (like English words). */ -#if !VALGRIND && !defined(__SANITIZE_ADDRESS__) +#if !VALGRIND && !HAS_FEATURE_ADDRESS_SANITIZER switch(length) { @@ -504,7 +504,7 @@ void jenkins_hashlittle2( * still catch it and complain. The masking trick does make the hash * noticeably faster for short strings (like English words). */ -#if !VALGRIND && !defined(__SANITIZE_ADDRESS__) +#if !VALGRIND && !HAS_FEATURE_ADDRESS_SANITIZER switch(length) { @@ -680,7 +680,7 @@ uint32_t jenkins_hashbig( const void *key, size_t length, uint32_t initval) * still catch it and complain. The masking trick does make the hash * noticeably faster for short strings (like English words). */ -#if !VALGRIND && !defined(__SANITIZE_ADDRESS__) +#if !VALGRIND && !HAS_FEATURE_ADDRESS_SANITIZER switch(length) { diff --git a/src/libsystemd/sd-bus/test-bus-marshal.c b/src/libsystemd/sd-bus/test-bus-marshal.c index d1c674b223..1e9810ce4f 100644 --- a/src/libsystemd/sd-bus/test-bus-marshal.c +++ b/src/libsystemd/sd-bus/test-bus-marshal.c @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) { log_info("message size = %zu, contents =\n%s", sz, h); #if HAVE_GLIB -#ifndef __SANITIZE_ADDRESS__ +#if !HAS_FEATURE_ADDRESS_SANITIZER { GDBusMessage *g; char *p; diff --git a/src/test/test-capability.c b/src/test/test-capability.c index 5bfcc385d9..dae85f2f91 100644 --- a/src/test/test-capability.c +++ b/src/test/test-capability.c @@ -20,7 +20,7 @@ static uid_t test_uid = -1; static gid_t test_gid = -1; -#ifdef __SANITIZE_ADDRESS__ +#if HAS_FEATURE_ADDRESS_SANITIZER /* Keep CAP_SYS_PTRACE when running under Address Sanitizer */ static const uint64_t test_flags = UINT64_C(1) << CAP_SYS_PTRACE; #else diff --git a/src/test/test-execute.c b/src/test/test-execute.c index fdde079cef..2115061add 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -759,7 +759,7 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); -#ifdef __SANITIZE_ADDRESS__ +#if HAS_FEATURE_ADDRESS_SANITIZER if (is_run_on_travis_ci()) { log_notice("Running on TravisCI under ASan, skipping, see https://github.com/systemd/systemd/issues/10696"); return EXIT_TEST_SKIP; diff --git a/src/test/test-sigbus.c b/src/test/test-sigbus.c index 33c9d42e9e..d2666dd1d8 100644 --- a/src/test/test-sigbus.c +++ b/src/test/test-sigbus.c @@ -19,7 +19,7 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_INFO); -#ifdef __SANITIZE_ADDRESS__ +#if HAS_FEATURE_ADDRESS_SANITIZER return log_tests_skipped("address-sanitizer is enabled"); #endif #if HAVE_VALGRIND_VALGRIND_H