From 6a5b28def26171a378d3d1012c3921ac4ffeca8e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 May 2020 18:08:21 +0200 Subject: [PATCH 1/5] json: use our regular way to turn off compiler warnings --- src/basic/macro.h | 4 ++++ src/shared/json.c | 32 ++++++++++++++------------------ src/test/test-json.c | 5 ++--- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 6ee2286833..97481b77ed 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -114,6 +114,10 @@ _Pragma("GCC diagnostic push") #endif +#define DISABLE_WARNING_FLOAT_EQUAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") + #define REENABLE_WARNING \ _Pragma("GCC diagnostic pop") diff --git a/src/shared/json.c b/src/shared/json.c index 330ad456ee..c269cc992f 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -253,10 +253,9 @@ static JsonVariant *json_variant_formalize(JsonVariant *v) { return json_variant_unsigned(v) == 0 ? JSON_VARIANT_MAGIC_ZERO_UNSIGNED : v; case JSON_VARIANT_REAL: -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; return json_variant_real(v) == 0.0 ? JSON_VARIANT_MAGIC_ZERO_REAL : v; -#pragma GCC diagnostic pop + REENABLE_WARNING; case JSON_VARIANT_STRING: return isempty(json_variant_string(v)) ? JSON_VARIANT_MAGIC_EMPTY_STRING : v; @@ -353,13 +352,12 @@ int json_variant_new_real(JsonVariant **ret, long double d) { assert_return(ret, -EINVAL); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; if (d == 0.0) { -#pragma GCC diagnostic pop *ret = JSON_VARIANT_MAGIC_ZERO_REAL; return 0; } + REENABLE_WARNING; r = json_variant_new(&v, JSON_VARIANT_REAL, sizeof(d)); if (r < 0) @@ -896,11 +894,10 @@ intmax_t json_variant_integer(JsonVariant *v) { converted = (intmax_t) v->value.real; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; if ((long double) converted == v->value.real) -#pragma GCC diagnostic pop return converted; + REENABLE_WARNING; log_debug("Real %Lg requested as integer, and cannot be converted losslessly, returning 0.", v->value.real); return 0; @@ -944,11 +941,10 @@ uintmax_t json_variant_unsigned(JsonVariant *v) { converted = (uintmax_t) v->value.real; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; if ((long double) converted == v->value.real) -#pragma GCC diagnostic pop return converted; + REENABLE_WARNING; log_debug("Real %Lg requested as unsigned integer, and cannot be converted losslessly, returning 0.", v->value.real); return 0; @@ -1137,14 +1133,15 @@ bool json_variant_has_type(JsonVariant *v, JsonVariantType type) { if (rt == JSON_VARIANT_UNSIGNED && type == JSON_VARIANT_REAL) return (uintmax_t) (long double) v->value.unsig == v->value.unsig; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; + /* Any real that can be converted losslessly to an integer and back may also be considered an integer */ if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_INTEGER) return (long double) (intmax_t) v->value.real == v->value.real; if (rt == JSON_VARIANT_REAL && type == JSON_VARIANT_UNSIGNED) return (long double) (uintmax_t) v->value.real == v->value.real; -#pragma GCC diagnostic pop + + REENABLE_WARNING; return false; } @@ -1298,10 +1295,9 @@ bool json_variant_equal(JsonVariant *a, JsonVariant *b) { return json_variant_unsigned(a) == json_variant_unsigned(b); case JSON_VARIANT_REAL: -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; return json_variant_real(a) == json_variant_real(b); -#pragma GCC diagnostic pop + REENABLE_WARNING; case JSON_VARIANT_BOOLEAN: return json_variant_boolean(a) == json_variant_boolean(b); diff --git a/src/test/test-json.c b/src/test/test-json.c index c72cd74274..032619a425 100644 --- a/src/test/test-json.c +++ b/src/test/test-json.c @@ -231,10 +231,9 @@ static void test_zeroes(JsonVariant *v) { assert_se(json_variant_integer(w) == 0); assert_se(json_variant_unsigned(w) == 0U); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + DISABLE_WARNING_FLOAT_EQUAL; assert_se(json_variant_real(w) == 0.0L); -#pragma GCC diagnostic pop + REENABLE_WARNING; assert_se(json_variant_is_integer(w)); assert_se(json_variant_is_unsigned(w)); From 56e577c62ff358d2abcc966559014e9e7d36d90c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 May 2020 18:16:33 +0200 Subject: [PATCH 2/5] tree-wide: use DISABLE_WARNING_FORMAT_NONLITERAL where appropriate --- src/core/selinux-access.c | 6 +++--- src/fstab-generator/fstab-generator.c | 6 +++--- src/journal-remote/microhttpd-util.c | 5 ++--- src/locale/localed.c | 5 ++--- src/udev/udev-builtin-net_id.c | 5 ++--- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index c6043943f1..abfab14dab 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -123,12 +123,12 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) { fmt2 = strjoina("selinux: ", fmt); va_start(ap, fmt); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" + + DISABLE_WARNING_FORMAT_NONLITERAL; log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, PROJECT_FILE, __LINE__, __FUNCTION__, fmt2, ap); -#pragma GCC diagnostic pop + REENABLE_WARNING; va_end(ap); return 0; diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 36a8ff23d4..77b90e1a9b 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -263,10 +263,10 @@ static int write_dependency( res = strv_join(units, " "); if (!res) return log_oom(); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" + + DISABLE_WARNING_FORMAT_NONLITERAL; fprintf(f, format, res); -#pragma GCC diagnostic pop + REENABLE_WARNING; } return 0; diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c index 939af12572..027f2c8ff5 100644 --- a/src/journal-remote/microhttpd-util.c +++ b/src/journal-remote/microhttpd-util.c @@ -78,10 +78,9 @@ int mhd_respondf(struct MHD_Connection *connection, errno = -error; fmt = strjoina(format, "\n"); va_start(ap, format); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" + DISABLE_WARNING_FORMAT_NONLITERAL; r = vasprintf(&m, fmt, ap); -#pragma GCC diagnostic pop + REENABLE_WARNING; va_end(ap); if (r < 0) diff --git a/src/locale/localed.c b/src/locale/localed.c index a6aa3bae8c..8ffcf306b5 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -499,10 +499,9 @@ static void log_xkb(struct xkb_context *ctx, enum xkb_log_level lvl, const char const char *fmt; fmt = strjoina("libxkbcommon: ", format); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" + DISABLE_WARNING_FORMAT_NONLITERAL; log_internalv(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, fmt, args); -#pragma GCC diagnostic pop + REENABLE_WARNING; } #define LOAD_SYMBOL(symbol, dl, name) \ diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 169d6ce8f7..b3c0ec827b 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -449,11 +449,10 @@ static int names_platform(sd_device *dev, struct netnames *names, bool test) { * The Vendor (3 or 4 char), followed by hexdecimal model number : instance id. */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" + DISABLE_WARNING_FORMAT_NONLITERAL; if (sscanf(syspath, pattern, vendor, &model, &instance, ðid) != 4) return -EINVAL; -#pragma GCC diagnostic pop + REENABLE_WARNING; if (!in_charset(vendor, validchars)) return -ENOENT; From 6028d766d15c616b8b938d4e5e57afc3dfe304dd Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 May 2020 18:20:52 +0200 Subject: [PATCH 3/5] macro: introduce DISABLE_WARNING_TYPE_LIMITS and make use of it everywhere --- src/basic/macro.h | 4 ++++ src/core/dbus-cgroup.c | 5 ++--- src/shared/json.c | 5 ++--- src/test/test-fileio.c | 5 ++--- src/test/test-sizeof.c | 2 +- src/timedate/timedatectl.c | 5 ++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 97481b77ed..73b391c27c 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -118,6 +118,10 @@ _Pragma("GCC diagnostic push"); \ _Pragma("GCC diagnostic ignored \"-Wfloat-equal\"") +#define DISABLE_WARNING_TYPE_LIMITS \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") + #define REENABLE_WARNING \ _Pragma("GCC diagnostic pop") diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index 27dc9e43c3..080f6fb1ae 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -707,8 +707,7 @@ static int bus_cgroup_set_boolean( return 1; \ } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" +DISABLE_WARNING_TYPE_LIMITS; BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID); BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID); BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID); @@ -716,7 +715,7 @@ BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEI BUS_DEFINE_SET_CGROUP_LIMIT(memory, CGROUP_MASK_MEMORY, physical_memory_scale, 1); BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection, CGROUP_MASK_MEMORY, physical_memory_scale, 0); BUS_DEFINE_SET_CGROUP_LIMIT(swap, CGROUP_MASK_MEMORY, physical_memory_scale, 0); -#pragma GCC diagnostic pop +REENABLE_WARNING; static int bus_cgroup_set_tasks_max( Unit *u, diff --git a/src/shared/json.c b/src/shared/json.c index c269cc992f..a3ad5b996a 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -4091,10 +4091,9 @@ int json_dispatch_uid_gid(const char *name, JsonVariant *variant, JsonDispatchFl assert_cc(sizeof(uid_t) == sizeof(uint32_t)); assert_cc(sizeof(gid_t) == sizeof(uint32_t)); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" + DISABLE_WARNING_TYPE_LIMITS; assert_cc(((uid_t) -1 < (uid_t) 0) == ((gid_t) -1 < (gid_t) 0)); -#pragma GCC diagnostic pop + REENABLE_WARNING; if (json_variant_is_null(variant)) { *uid = UID_INVALID; diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c index 8c04346721..af9696ef59 100644 --- a/src/test/test-fileio.c +++ b/src/test/test-fileio.c @@ -633,8 +633,7 @@ static void test_tempfn(void) { static const char chars[] = "Aąę„”\n루\377"; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" +DISABLE_WARNING_TYPE_LIMITS; static void test_fgetc(void) { _cleanup_fclose_ FILE *f = NULL; @@ -665,7 +664,7 @@ static void test_fgetc(void) { assert_se(safe_fgetc(f, &c) == 0); } -#pragma GCC diagnostic pop +REENABLE_WARNING; static const char buffer[] = "Some test data\n" diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c index 1020e0cb31..b9d63d6b41 100644 --- a/src/test/test-sizeof.c +++ b/src/test/test-sizeof.c @@ -14,7 +14,7 @@ /* Print information about various types. Useful when diagnosing * gcc diagnostics on an unfamiliar architecture. */ -#pragma GCC diagnostic ignored "-Wtype-limits" +DISABLE_WARNING_TYPE_LIMITS; #define info(t) \ printf("%s → %zu bits%s, %zu byte alignment\n", STRINGIFY(t), \ diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 9c9791c706..3f34a91a7e 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -363,10 +363,9 @@ static const char * const ntp_leap_table[4] = { [3] = "not synchronized", }; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" +DISABLE_WARNING_TYPE_LIMITS; DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(ntp_leap, uint32_t); -#pragma GCC diagnostic pop +REENABLE_WARNING; static int print_ntp_status_info(NTPStatusInfo *i) { char ts[FORMAT_TIMESPAN_MAX], jitter[FORMAT_TIMESPAN_MAX], From 8e2fa6e2236ec81c86612f75103f36ba699193c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 May 2020 18:21:08 +0200 Subject: [PATCH 4/5] json: turn off ubsan for json_variant_has_type() Fixes: #15907 --- src/basic/macro.h | 8 ++++++++ src/shared/json.c | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/basic/macro.h b/src/basic/macro.h index 73b391c27c..b48d399097 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -84,6 +84,14 @@ #define _variable_no_sanitize_address_ #endif +/* Apparently there's no has_feature() call defined to check for ubsan, hence let's define this + * unconditionally on llvm */ +#if defined(__clang__) +#define _function_no_sanitize_float_cast_overflow_ __attribute__((no_sanitize("float-cast-overflow"))) +#else +#define _function_no_sanitize_float_cast_overflow_ +#endif + /* Temporarily disable some warnings */ #define DISABLE_WARNING_FORMAT_NONLITERAL \ _Pragma("GCC diagnostic push"); \ diff --git a/src/shared/json.c b/src/shared/json.c index a3ad5b996a..27a3a518fe 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -1093,9 +1093,12 @@ JsonVariantType json_variant_type(JsonVariant *v) { return v->type; } -bool json_variant_has_type(JsonVariant *v, JsonVariantType type) { +_function_no_sanitize_float_cast_overflow_ bool json_variant_has_type(JsonVariant *v, JsonVariantType type) { JsonVariantType rt; + /* Note: we turn off ubsan float cast overflo detection for this function, since it would complain + * about our float casts but we do them explicitly to detect conversion errors. */ + v = json_variant_dereference(v); if (!v) return false; From e5af586f49dedf14981c8ada0477fc3957850cf6 Mon Sep 17 00:00:00 2001 From: Evgeny Vereshchagin Date: Mon, 25 May 2020 13:38:36 +0200 Subject: [PATCH 5/5] add a test triggering https://github.com/systemd/systemd/issues/15907 --- test/fuzz/fuzz-json/github-15907 | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/fuzz/fuzz-json/github-15907 diff --git a/test/fuzz/fuzz-json/github-15907 b/test/fuzz/fuzz-json/github-15907 new file mode 100644 index 0000000000..b247ccd199 --- /dev/null +++ b/test/fuzz/fuzz-json/github-15907 @@ -0,0 +1 @@ +[7E73] \ No newline at end of file