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
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: