| From 112d963a0542b1280667e2eb2727a8946d9bcf8d Mon Sep 17 00:00:00 2001 |
| From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com> |
| Date: Mon, 13 Mar 2017 08:14:42 +0100 |
| Subject: [PATCH] journal: prevent integer overflow while validating header |
| (#5569) |
| |
| It is possible to overflow uint64_t while validating the header of |
| a journal file. To prevent this, the addition itself is checked to |
| be within the limits of UINT64_MAX first. |
| |
| To keep this readable, I have introduced two stack variables which |
| hold the converted values during validation. |
| (cherry picked from commit 6f94e420e8355421fc31713a0df760d6b20473ac) |
| --- |
| src/journal/journal-file.c | 12 +++++++++--- |
| 1 file changed, 9 insertions(+), 3 deletions(-) |
| |
| diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c |
| index a6ccb67..14cb01a 100644 |
| --- a/src/journal/journal-file.c |
| +++ b/src/journal/journal-file.c |
| @@ -546,6 +546,8 @@ static bool warn_wrong_flags(const JournalFile *f, bool compatible) { |
| } |
| |
| static int journal_file_verify_header(JournalFile *f) { |
| + uint64_t arena_size, header_size; |
| + |
| assert(f); |
| assert(f->header); |
| |
| @@ -564,17 +566,21 @@ static int journal_file_verify_header(JournalFile *f) { |
| if (f->header->state >= _STATE_MAX) |
| return -EBADMSG; |
| |
| + header_size = le64toh(f->header->header_size); |
| + |
| /* The first addition was n_data, so check that we are at least this large */ |
| - if (le64toh(f->header->header_size) < HEADER_SIZE_MIN) |
| + if (header_size < HEADER_SIZE_MIN) |
| return -EBADMSG; |
| |
| if (JOURNAL_HEADER_SEALED(f->header) && !JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays)) |
| return -EBADMSG; |
| |
| - if ((le64toh(f->header->header_size) + le64toh(f->header->arena_size)) > (uint64_t) f->last_stat.st_size) |
| + arena_size = le64toh(f->header->arena_size); |
| + |
| + if (UINT64_MAX - header_size < arena_size || header_size + arena_size > (uint64_t) f->last_stat.st_size) |
| return -ENODATA; |
| |
| - if (le64toh(f->header->tail_object_offset) > (le64toh(f->header->header_size) + le64toh(f->header->arena_size))) |
| + if (le64toh(f->header->tail_object_offset) > header_size + arena_size) |
| return -ENODATA; |
| |
| if (!VALID64(le64toh(f->header->data_hash_table_offset)) || |
| -- |
| 2.9.3 |
| |