From a1640191b4ca583ca62a4bd3b91edec3532bd41f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 12 Oct 2022 16:08:57 +0900 Subject: [PATCH] sd-journal: re-read object on next try Otherwise, the object may be already altered by another cached entry. --- src/libsystemd/sd-journal/journal-file.c | 3 ++- src/libsystemd/sd-journal/sd-journal.c | 20 ++++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c index ca5f5c9fcc..54bad925b2 100644 --- a/src/libsystemd/sd-journal/journal-file.c +++ b/src/libsystemd/sd-journal/journal-file.c @@ -4000,7 +4000,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6 r = journal_file_data_payload(from, NULL, q, NULL, 0, 0, &data, &l); if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) { log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i); - continue; + goto next; } if (r < 0) return r; @@ -4023,6 +4023,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6 .hash = le64toh(u->data.hash), }; + next: /* The above journal_file_data_payload() may clear or overwrite cached object. Hence, we need * to re-read the object from the cache. */ r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o); diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c index 5a75994d15..53c0b2a01e 100644 --- a/src/libsystemd/sd-journal/sd-journal.c +++ b/src/libsystemd/sd-journal/sd-journal.c @@ -2264,8 +2264,8 @@ static bool field_is_valid(const char *field) { _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) { JournalFile *f; size_t field_length; - int r; Object *o; + int r; assert_return(j, -EINVAL); assert_return(!journal_pid_changed(j), -ECHILD); @@ -2296,10 +2296,10 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** p = journal_file_entry_item_object_offset(f, o, i); r = journal_file_data_payload(f, NULL, p, field, field_length, j->data_threshold, &d, &l); if (r == 0) - continue; + goto next; if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) { log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i); - continue; + goto next; } if (r < 0) return r; @@ -2308,6 +2308,12 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** *size = l; return 0; + + next: + /* journal_file_data_payload() may clear or overwrite cached object. */ + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; } return -ENOENT; @@ -2343,7 +2349,7 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t r = journal_file_data_payload(f, NULL, p, NULL, 0, j->data_threshold, &d, &l); if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) { log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", j->current_field); - continue; + goto next; } if (r < 0) return r; @@ -2355,6 +2361,12 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t j->current_field++; return 1; + + next: + /* journal_file_data_payload() may clear or overwrite cached object. */ + r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o); + if (r < 0) + return r; } return 0;