From 50809d7a9c986f78d8b8872098e4880aa8ff2076 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Apr 2016 21:42:15 +0200 Subject: sd-journal: detect earlier if we try to read an object from an invalid offset Specifically, detect early if we try to read from offset 0, i.e. are using uninitialized offset data. --- src/journal/journal-file.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index ac6c30f9f2..c4318636f7 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -709,6 +709,10 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset if (!VALID64(offset)) return -EFAULT; + /* Object may not be located in the file header */ + if (offset < le64toh(f->header->header_size)) + return -EBADMSG; + r = journal_file_move_to(f, type, false, offset, sizeof(ObjectHeader), &t); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From d00f1d57cc326231e7003340056f4fbcf056674c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Apr 2016 21:43:12 +0200 Subject: journal: when dumping journal contents, react nicer to lines we can't read If journal files are not cleanly closed it might happen that intermediaery journal entries cannot be read. Handle this nicely, skip over the unreadable entries, and log a debug message about it; after all we generally follow the logic that we try to make the best of corrupted files. --- src/shared/logs-show.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index cd3d53669c..9351b85eed 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -287,7 +287,10 @@ static int output_short( if (r < 0) return r; } - + if (r == -EBADMSG) { + log_debug_errno(r, "Skipping message we can't read: %m"); + return 0; + } if (r < 0) return log_error_errno(r, "Failed to get journal fields: %m"); -- cgit v1.2.3-54-g00ecf From bd30fdf213c830002aaf48a0d840c011f739ce8f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 11:37:22 +0200 Subject: journal-file: always generate the same error when encountering corrupted files Let's make sure EBADMSG is the one error we throw when we encounter corrupted data, so that we can neatly test for it. --- src/journal/journal-file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index c4318636f7..e13ae05990 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -707,7 +707,7 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset /* Objects may only be located at multiple of 64 bit */ if (!VALID64(offset)) - return -EFAULT; + return -EBADMSG; /* Object may not be located in the file header */ if (offset < le64toh(f->header->header_size)) -- cgit v1.2.3-54-g00ecf From caeab8f626e709569cc492b75eb7e119076059e7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 11:38:39 +0200 Subject: journal-file: when iterating through a partly corruped journal file, treat error like EOF When we linearly iterate through a corrupted journal file, and we encounter a read error, don't consider this fatal, but merely as EOF condition (and log about it). --- src/journal/journal-file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index e13ae05990..c97b3f9882 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -2469,12 +2469,18 @@ int journal_file_next_entry( le64toh(f->header->entry_array_offset), i, ret, &ofs); + if (r == -EBADMSG && direction == DIRECTION_DOWN) { + /* Special case: when we iterate throught the journal file linearly, and hit an entry we can't read, + * consider this the end of the journal file. */ + log_debug_errno(r, "Encountered entry we can't read while iterating through journal file. Considering this the end of the file."); + return 0; + } if (r <= 0) return r; if (p > 0 && (direction == DIRECTION_DOWN ? ofs <= p : ofs >= p)) { - log_debug("%s: entry array corrupted at entry %"PRIu64, f->path, i); + log_debug("%s: entry array corrupted at entry %" PRIu64, f->path, i); return -EBADMSG; } -- cgit v1.2.3-54-g00ecf From bee6a29198e7c8f6636aafece9a42c97435d171e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 11:39:48 +0200 Subject: journal-file: make seeking in corrupted files work Previously, when we used a bisection table for seeking through a corrupted file, and the end of the bisection table was corrupted we'd most likely fail the entire seek operation. Improve the situation: if we encounter invalid entries in a bisection table, linearly go backwards until we find a working entry again. --- src/journal/journal-file.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index c97b3f9882..ff01e5aa94 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -1984,9 +1984,14 @@ static int generic_array_bisect( i = right - 1; lp = p = le64toh(array->entry_array.items[i]); if (p <= 0) - return -EBADMSG; - - r = test_object(f, p, needle); + r = -EBADMSG; + else + r = test_object(f, p, needle); + if (r == -EBADMSG) { + log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (1)"); + n = i; + continue; + } if (r < 0) return r; @@ -2062,9 +2067,14 @@ static int generic_array_bisect( p = le64toh(array->entry_array.items[i]); if (p <= 0) - return -EBADMSG; - - r = test_object(f, p, needle); + r = -EBADMSG; + else + r = test_object(f, p, needle); + if (r == -EBADMSG) { + log_debug_errno(r, "Encountered invalid entry while bisecting, cutting algorithm short. (2)"); + right = n = i; + continue; + } if (r < 0) return r; -- cgit v1.2.3-54-g00ecf