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:
parent
2f7a0648cd
commit
aa00163d79
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user