From 0b8218b901a44f3e6a7d76f25038fb0526e8b1d7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Sep 2022 14:09:54 +0200 Subject: [PATCH] json: explicitly support offsets relative to NULL when dispatching Let's trick out UndefinedBehaviourSanitizer: https://github.com/systemd/systemd/pull/24853#issuecomment-1263380745 --- src/shared/json.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/shared/json.c b/src/shared/json.c index 40c6f723eec..950be9485d5 100644 --- a/src/shared/json.c +++ b/src/shared/json.c @@ -4211,6 +4211,19 @@ int json_log_internal( NULL); } +static void *dispatch_userdata(const JsonDispatch *p, void *userdata) { + + /* When the the userdata pointer is passed in as NULL, then we'll just use the offset as a literal + * address, and convert it to a pointer. Note that might as well just add the offset to the NULL + * pointer, but UndefinedBehaviourSanitizer doesn't like pointer arithmetics based on NULL pointers, + * hence we code this explicitly here. */ + + if (userdata) + return (uint8_t*) userdata + p->offset; + + return SIZE_TO_PTR(p->offset); +} + int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallback bad, JsonDispatchFlags flags, void *userdata) { size_t m; int r, done = 0; @@ -4274,7 +4287,7 @@ int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallba found[p-table] = true; if (p->callback) { - r = p->callback(json_variant_string(key), value, merged_flags, (uint8_t*) userdata + p->offset); + r = p->callback(json_variant_string(key), value, merged_flags, dispatch_userdata(p, userdata)); if (r < 0) { if (merged_flags & JSON_PERMISSIVE) continue; -- 2.47.3