]> git.ipfire.org Git - thirdparty/systemd.git/commit
shared/options: fix crash by aligning struct to sizeof(void*)
authorLuca Boccassi <luca.boccassi@gmail.com>
Sun, 24 May 2026 11:01:24 +0000 (12:01 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sun, 24 May 2026 18:36:56 +0000 (20:36 +0200)
commita7ecad77cbb00ecd388d6d4bbc924704ecbe1ebc
treeb060999df78ad979b314fdfe2571b71a5bc42e51
parent112453b9a2f86d3e20c0f898203365388a5c6656
shared/options: fix crash by aligning struct to sizeof(void*)

On some architectures like m68k, alignof(void*) is 2, not sizeof(void*)
(which is 4). So the natural alignment of struct Option is 2 and
sizeof(Option) == 26.

However, each variable placed in the SYSTEMD_OPTIONS ELF section via
_OPTION() carries _alignptr_ (= __attribute__((aligned(sizeof(void*))))),
which forces each entry to start at a 4-byte boundary. The linker
therefore inserts 2 bytes of padding between adjacent entries, producing
an actual stride of 28 in the section.

option_parse() iterates over the section with pointer arithmetic
("opt++"), which advances by sizeof(Option) == 26 and lands inside the
padding. The fields read back as zero, and since commit cf88903637
("tree-wide: get rid of most uses of ALIGN_PTR") added the ordering
assertion below, the resulting "0 < 0" trips it when running --help:

 Assertion 'opt->id < (opt + 1)->id' failed at src/shared/options.c:116, function option_parse(). Aborting.

 #0  0xc0a7b248 in ?? () from /usr/lib/m68k-linux-gnu/libc.so.6
 #1  0xc0a7b2ce in pthread_kill () from /usr/lib/m68k-linux-gnu/libc.so.6
 #2  0xc0a2edc6 in raise () from /usr/lib/m68k-linux-gnu/libc.so.6
 #3  0xc0a1c128 in abort () from /usr/lib/m68k-linux-gnu/libc.so.6
 #4  0xc05c6f78 in option_parse (options=0x0, options_end=0x0, state=0xc09ca968) at ../src/shared/options.c:116

Fix this by applying _alignptr_ to the struct definition itself, so that
sizeof(Option) is padded up to a multiple of sizeof(void*) and matches
the actual on-disk stride. Add an assert_cc() so any future regression
is caught at compile time.

The same latent bug applies to Verb and TestFunc, which use the same
section-placement pattern. Their natural sizeof was already a multiple
of sizeof(void*) so no crash was observed, but apply the same fix
defensively.

Follow-up for cf889036377092cbec6c5ec86fdf0dc1c9326032

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
src/basic/static-destruct.h
src/shared/options.h
src/shared/tests.h
src/shared/verbs.h