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;
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;
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;
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);
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);
- s = le64toh(o.object.size);
+ 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);
"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,
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);