From: Milan Kyselica Date: Sat, 11 Apr 2026 08:26:13 +0000 (+0200) Subject: boot: fix loop bound and OOB in devicetree_get_compatible() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2c664b953163be5e8e18df3fd73ed7bfae229a37;p=thirdparty%2Fsystemd.git boot: fix loop bound and OOB in devicetree_get_compatible() The loop used the byte offset end (struct_off + struct_size) as the iteration limit, but cursor[i] indexes uint32_t words. This reads past the struct block when end > size_words. Use size_words (struct_size / sizeof(uint32_t)) which is the correct number of words to iterate over. Also fix a pre-existing OOB in the FDT_BEGIN_NODE handler: the guard i >= size_words is always false inside the loop (since the loop condition already ensures i < size_words), so cursor[++i] at the boundary reads one word past the struct block. Use i + 1 >= size_words to check before incrementing. Fixes: https://github.com/systemd/systemd/issues/41590 --- diff --git a/src/boot/devicetree.c b/src/boot/devicetree.c index 85fc07c49f3..a9dccd2a57c 100644 --- a/src/boot/devicetree.c +++ b/src/boot/devicetree.c @@ -141,10 +141,10 @@ static const char* devicetree_get_compatible(const void *dtb) { size_t size_words = struct_size / sizeof(uint32_t); size_t len, name_off, len_words, s; - for (size_t i = 0; i < end; i++) { + for (size_t i = 0; i < size_words; i++) { switch (be32toh(cursor[i])) { case FDT_BEGIN_NODE: - if (i >= size_words || cursor[++i] != 0) + if (i + 1 >= size_words || cursor[++i] != 0) return NULL; break; case FDT_NOP: