]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-journal: introduce simple loop detection for entry array objects
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 1 May 2023 05:18:08 +0000 (14:18 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 1 May 2023 06:46:59 +0000 (15:46 +0900)
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.

src/libsystemd/sd-journal/journal-file.c

index 1413f7014f1e78da32e4f3b5c4950bf271240bf6..fe2610be96fe2f609a793712bce9b4a73498aac7 100644 (file)
@@ -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;