From 6e3930c40f3379b7123e505a71ba4cd6db6c372f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 26 Apr 2016 14:38:45 +0200 Subject: smaller journal fixes (#3124) * 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. * 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. * 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. * 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). * 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. * man: elaborate on the automatic systemd-journald.socket service dependencies Fixes: #1603 --- man/systemd.exec.xml | 13 ++++++++----- src/journal/journal-file.c | 36 ++++++++++++++++++++++++++++-------- src/shared/logs-show.c | 5 ++++- 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 4ed62dbada..fea42ebd31 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -94,11 +94,10 @@ required to access /tmp and /var/tmp. - Units whose output standard output or error output is - connected to any other sink but , - and automatically - acquire dependencies of type After= on - journald.socket. + Units whose output standard output or error output is connected to , + or (or their combinations with console output, see below) + automatically acquire dependencies of type After= on + systemd-journald.socket. @@ -470,6 +469,10 @@ similar to the same option of StandardInput=. + If the standard output (or error output, see below) of a unit is connected with the journal, syslog or + the kernel log buffer the unit will implicitly gain a dependency of type After= on + systemd-journald.socket (also see the automatic dependencies section above). + This setting defaults to the value set with in systemd-system.conf5, diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index ac6c30f9f2..ff01e5aa94 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -707,7 +707,11 @@ 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)) + return -EBADMSG; r = journal_file_move_to(f, type, false, offset, sizeof(ObjectHeader), &t); if (r < 0) @@ -1980,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; @@ -2058,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; @@ -2465,12 +2479,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; } 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