]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-journal: always put verified object into the chain cache
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 2 Jan 2024 19:30:24 +0000 (04:30 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 9 Feb 2024 15:26:17 +0000 (00:26 +0900)
Let's consider the case that
- the first array contains valid entries,
- all entries in the second array are corrupted.

Then, when we are going to upwards, and a call of generic_array_bisect()
matches the last entry of the first array, then the second array was
cached with last_index == UINT64_MAX, instead of the first array with
its last entry.
Hence, when generic_array_bisect() is called next time, the function call
of test() always fail. So, the cache entry is mostly meaningless.

Let's always store valid cache entry.

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

index d3ce5fa7ec9863df7f00bfdebca36f1e1b17a55f..24a02c74c2c4648a5c57fe79fced9aa301ceaed4 100644 (file)
@@ -3162,10 +3162,21 @@ previous:
         if (direction == DIRECTION_DOWN)
                 return 0;
 
-        /* Indicate to go to the previous array later. Note, do not move to the previous array here,
-         * as that may invalidate the current array object in the mmap cache and
-         * journal_file_entry_array_item() below may read invalid address. */
-        i = UINT64_MAX;
+        /* Get the last entry of the previous array. */
+        r = bump_entry_array(f, NULL, a, first, DIRECTION_UP, &a);
+        if (r <= 0)
+                return r;
+
+        r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array);
+        if (r < 0)
+                return r;
+
+        p = journal_file_entry_array_n_items(f, array);
+        if (p == 0 || t < p)
+                return -EBADMSG;
+
+        t -= p;
+        i = p - 1;
 
 found:
         p = journal_file_entry_array_item(f, array, 0);
@@ -3175,27 +3186,6 @@ found:
         /* Let's cache this item for the next invocation */
         chain_cache_put(f->chain_cache, ci, first, a, p, t, i);
 
-        if (i == UINT64_MAX) {
-                uint64_t m;
-
-                /* Get the last entry of the previous array. */
-
-                r = bump_entry_array(f, NULL, a, first, DIRECTION_UP, &a);
-                if (r <= 0)
-                        return r;
-
-                r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &array);
-                if (r < 0)
-                        return r;
-
-                m = journal_file_entry_array_n_items(f, array);
-                if (m == 0 || t < m)
-                        return -EBADMSG;
-
-                t -= m;
-                i = m - 1;
-        }
-
         p = journal_file_entry_array_item(f, array, i);
         if (p == 0)
                 return -EBADMSG;