mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-08 21:17:47 +03:00
journal: various fixes to journal_file_read_object()
This fixes a bunch of issues:
pread() returns ssize_t, and returns errors in 'errno', handle that
correctly.
More importantly: it might incompletely read data in case we hit
EOF. Check for that, and handle it.
Finally, rename the function to journal_file_read_object_header(), since
it really doesn't read full objects, but only their headers.
Follow-up for: 117e21121e
This commit is contained in:
parent
bb7031bcaa
commit
e5d8473335
@ -45,7 +45,7 @@ static int journald_file_entry_array_punch_hole(JournalFile *f, uint64_t p, uint
|
||||
return 0;
|
||||
|
||||
for (uint64_t q = p; q != 0; q = le64toh(o.entry_array.next_entry_array_offset)) {
|
||||
r = journal_file_read_object(f, OBJECT_ENTRY_ARRAY, q, &o);
|
||||
r = journal_file_read_object_header(f, OBJECT_ENTRY_ARRAY, q, &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -119,7 +119,7 @@ static int journald_file_punch_holes(JournalFile *f) {
|
||||
for (uint64_t q = le64toh(items[j].head_hash_offset); q != 0;
|
||||
q = le64toh(o.data.next_hash_offset)) {
|
||||
|
||||
r = journal_file_read_object(f, OBJECT_DATA, q, &o);
|
||||
r = journal_file_read_object_header(f, OBJECT_DATA, q, &o);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Invalid data object: %m, ignoring");
|
||||
break;
|
||||
|
@ -106,7 +106,7 @@ int journal_file_tail_end(JournalFile *f, uint64_t *ret_offset) {
|
||||
else {
|
||||
uint64_t sz;
|
||||
|
||||
r = journal_file_read_object(f, OBJECT_UNUSED, p, &tail);
|
||||
r = journal_file_read_object_header(f, OBJECT_UNUSED, p, &tail);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -818,10 +818,11 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset
|
||||
return 0;
|
||||
}
|
||||
|
||||
int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, Object *ret) {
|
||||
int r;
|
||||
Object o;
|
||||
int journal_file_read_object_header(JournalFile *f, ObjectType type, uint64_t offset, Object *ret) {
|
||||
uint64_t s;
|
||||
ssize_t n;
|
||||
Object o;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
|
||||
@ -838,17 +839,22 @@ int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, O
|
||||
offset);
|
||||
|
||||
/* This will likely read too much data but it avoids having to call pread() twice. */
|
||||
r = pread(f->fd, &o, sizeof(Object), offset);
|
||||
if (r < 0)
|
||||
return r;
|
||||
n = pread(f->fd, &o, sizeof(o), offset);
|
||||
if (n < 0)
|
||||
return log_debug_errno(errno, "Failed to read journal file at offset: %" PRIu64,
|
||||
offset);
|
||||
|
||||
if ((size_t) n < sizeof(o.object))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Failed to read short object at offset: %" PRIu64,
|
||||
offset);
|
||||
|
||||
s = le64toh(o.object.size);
|
||||
|
||||
if (s == 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||
"Attempt to read uninitialized object: %" PRIu64,
|
||||
offset);
|
||||
if (s < sizeof(ObjectHeader))
|
||||
if (s < sizeof(o.object))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||
"Attempt to read overly short object: %" PRIu64,
|
||||
offset);
|
||||
@ -863,6 +869,11 @@ int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, O
|
||||
"Attempt to read truncated object: %" PRIu64,
|
||||
offset);
|
||||
|
||||
if ((size_t) n < minimum_header_size(&o))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Short read while reading object: %" PRIu64,
|
||||
offset);
|
||||
|
||||
if (type > OBJECT_UNUSED && o.object.type != type)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||
"Attempt to read object of unexpected type: %" PRIu64,
|
||||
|
@ -185,7 +185,7 @@ static inline bool VALID_EPOCH(uint64_t u) {
|
||||
FLAGS_SET(le32toh((h)->incompatible_flags), HEADER_INCOMPATIBLE_KEYED_HASH)
|
||||
|
||||
int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset, Object **ret);
|
||||
int journal_file_read_object(JournalFile *f, ObjectType type, uint64_t offset, Object *ret);
|
||||
int journal_file_read_object_header(JournalFile *f, ObjectType type, uint64_t offset, Object *ret);
|
||||
|
||||
int journal_file_tail_end(JournalFile *f, uint64_t *ret_offset);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user