summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-05-01 14:18:08 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-05-01 15:46:59 +0900
commita8fbcc0e3c033a43e511550052cace6b0dcf3df7 (patch)
treea62cec0597ef86818cf3c3fccc4b0e6ba90d9ee2 /src/libsystemd
parente758735d330044402826ac2e8c2a0814b02fec92 (diff)
downloadsystemd-a8fbcc0e3c033a43e511550052cace6b0dcf3df7.tar.gz
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/libsystemd')
-rw-r--r--src/libsystemd/sd-journal/journal-file.c26
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;