1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-18 17:57:27 +03:00

journal: Fix upwards iteration of entry items in case of corruption

8d801e35cb155faa08235a5af8b4d6ad60715837 didn't take into account
upwards iteration of entry items when we're working on a corrupted
journal file. Instead of moving to the previous entry array, we'd
always move to the next array, regardless of the iteration direction.

To fix this, we introduce bump_entry_array() that moves to the next
or previous entry array depending on the given direction. Since the
entry array chains are singly linked lists, we have to start iterating
from the front to find the previous array. We only reach this logic
if we're working on a corrupted journal file so being slow here shouldn't
matter too much.
This commit is contained in:
Daan De Meyer 2022-02-07 20:15:07 +00:00
parent 2f7a0648cd
commit aa00163d79

View File

@ -2163,6 +2163,41 @@ static int bump_array_index(uint64_t *i, direction_t direction, uint64_t n) {
return 1;
}
static int bump_entry_array(JournalFile *f, Object *o, uint64_t offset, uint64_t first, direction_t direction, uint64_t *ret) {
uint64_t p, q = 0;
int r;
assert(f);
assert(offset);
assert(ret);
if (direction == DIRECTION_DOWN)
return le64toh(o->entry_array.next_entry_array_offset);
/* Entry array chains are a singly linked list, so to find the previous array in the chain, we have
* to start iterating from the top. */
p = first;
while (p > 0 && p != offset) {
r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, p, &o);
if (r < 0)
return r;
q = p;
p = le64toh(o->entry_array.next_entry_array_offset);
}
/* If we can't find the previous entry array in the entry array chain, we're likely dealing with a
* corrupted journal file. */
if (p == 0)
return -EBADMSG;
*ret = q;
return 0;
}
static int generic_array_get(
JournalFile *f,
uint64_t first,
@ -2240,8 +2275,11 @@ static int generic_array_get(
log_debug_errno(r, "Entry item %" PRIu64 " is bad, skipping over it.", i);
} while (bump_array_index(&i, direction, k) > 0);
r = bump_entry_array(f, o, a, first, direction, &a);
if (r < 0)
return r;
t += k;
a = le64toh(o->entry_array.next_entry_array_offset);
i = UINT64_MAX;
}