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