diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-05-01 07:18:08 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-05-01 08:46:59 +0200 |
commit | a8fbcc0e3c033a43e511550052cace6b0dcf3df7 (patch) | |
tree | a62cec0597ef86818cf3c3fccc4b0e6ba90d9ee2 /src | |
parent | sd-journal: tighten variable scope (diff) | |
download | systemd-a8fbcc0e3c033a43e511550052cace6b0dcf3df7.tar.xz systemd-a8fbcc0e3c033a43e511550052cace6b0dcf3df7.zip |
sd-journal: introduce simple loop detection for entry array objects
If .next_entry_array_offset points to one of the previous entry or the
self entry, then the loop for entry array objects may run infinitely.
Let's assume that the offsets of each entry array object are in
increasing order, and check that in loop.
Fixes #27470.
Diffstat (limited to 'src')
-rw-r--r-- | src/libsystemd/sd-journal/journal-file.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index 1413f7014f..fe2610be96 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -2591,10 +2591,18 @@ static int bump_entry_array( assert(offset); assert(ret); + /* Return 1 when a non-zero offset found, 0 when the offset is zero. + * Here, we assume that the offset of each entry array object is in strict increasing order. */ + if (direction == DIRECTION_DOWN) { assert(o); - *ret = le64toh(o->entry_array.next_entry_array_offset); - return 0; + + p = le64toh(o->entry_array.next_entry_array_offset); + if (p > 0 && p <= offset) + return -EBADMSG; + + *ret = p; + return p > 0; } /* Entry array chains are a singly linked list, so to find the previous array in the chain, we have @@ -2609,6 +2617,8 @@ static int bump_entry_array( q = p; p = le64toh(o->entry_array.next_entry_array_offset); + if (p <= q) + return -EBADMSG; } /* If we can't find the previous entry array in the entry array chain, we're likely dealing with a @@ -2617,8 +2627,7 @@ static int bump_entry_array( return -EBADMSG; *ret = q; - - return 0; + return 1; /* found */ } static int generic_array_get( @@ -2661,7 +2670,7 @@ static int generic_array_get( * array and start iterating entries from there. */ r = bump_entry_array(f, NULL, a, first, DIRECTION_UP, &a); - if (r < 0) + if (r <= 0) return r; i = UINT64_MAX; @@ -2677,7 +2686,10 @@ static int generic_array_get( i -= k; t += k; - a = le64toh(o->entry_array.next_entry_array_offset); + + r = bump_entry_array(f, o, a, first, DIRECTION_DOWN, &a); + if (r <= 0) + return r; } /* If we've found the right location, now look for the first non-corrupt entry object (in the right @@ -2727,7 +2739,7 @@ static int generic_array_get( } while (bump_array_index(&i, direction, k) > 0); r = bump_entry_array(f, o, a, first, direction, &a); - if (r < 0) + if (r <= 0) return r; t += k; |