With a corrupted file, we can get in a situation where two entries in the entry array point to the same object. Then journal_file_next_entry will find the first one using generic_arrray_bisect, and try to move to the second one, but since the address is the same, generic_array_get will return the first one. journal_file_next_entry ends up in an infinite loop.
https://bugzilla.redhat.com/show_bug.cgi?id=1047039 --- Thoughts? Those two patches seem to work for me. Zbyszek src/journal/journal-file.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 5876733..d037e2a 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -1359,7 +1359,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st } typedef struct ChainCacheItem { - uint64_t first; /* the array at the begin of the chain */ + uint64_t first; /* the array at the beginning of the chain */ uint64_t array; /* the cached array */ uint64_t begin; /* the first item in the cached array */ uint64_t total; /* the total number of items in all arrays before this one in the chain */ @@ -1986,10 +1986,21 @@ int journal_file_next_entry( } /* And jump to it */ - return generic_array_get(f, - le64toh(f->header->entry_array_offset), - i, - ret, offset); + r = generic_array_get(f, + le64toh(f->header->entry_array_offset), + i, + ret, offset); + if (r <= 0) + return r; + + if (p > 0 && + (direction == DIRECTION_DOWN ? *offset <= p : *offset >= p)) { + log_debug("%s: entry array corrupted at entry %"PRIu64, + f->path, i); + return -EBADMSG; + } + + return 1; } int journal_file_skip_entry( -- 1.8.5.3 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel