85 lines
3.2 KiB
Diff
85 lines
3.2 KiB
Diff
From b0ec76d623f737a32abc5ab8bb7198bf1d9939a4 Mon Sep 17 00:00:00 2001
|
|
From: Lukas Czerner <lczerner@redhat.com>
|
|
Date: Tue, 14 Aug 2018 16:37:53 +0200
|
|
Subject: [PATCH 070/131] libe2p: avoid segfault when s_nr_users is too high
|
|
|
|
Currently in e2fsprogs tools it's possible to access out of bounds
|
|
memory when reading list of ids sharing a journal log
|
|
(journal_superblock_t->s_users[]) in case where s_nr_users is too high.
|
|
|
|
This is because we never check whether the s_nr_users fits into the
|
|
restriction of JFS_USERS_MAX. Fix it by checking that nr_users is not
|
|
bigger than JFS_USERS_MAX and error out when possiblem.
|
|
|
|
Also add test for dumpe2fs. The rest would require involving external
|
|
journal which is not possible to test with e2fsprogs test suite at the
|
|
moment.
|
|
|
|
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
|
|
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
|
|
---
|
|
lib/e2p/ljs.c | 4 +-
|
|
lib/ext2fs/mkjournal.c | 2 +
|
|
misc/tune2fs.c | 11 ++++
|
|
|
|
diff --git a/lib/e2p/ljs.c b/lib/e2p/ljs.c
|
|
index 0b1bead..c99126b 100644
|
|
--- a/lib/e2p/ljs.c
|
|
+++ b/lib/e2p/ljs.c
|
|
@@ -101,10 +101,10 @@ void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
|
|
e2p_be32(jsb->s_checksum));
|
|
if ((nr_users > 1) ||
|
|
!e2p_is_null_uuid(&jsb->s_users[0])) {
|
|
- for (i=0; i < nr_users; i++) {
|
|
+ for (i=0; i < nr_users && i < JFS_USERS_MAX; i++) {
|
|
printf(i ? " %s\n"
|
|
: "Journal users: %s\n",
|
|
- e2p_uuid2str(&jsb->s_users[i*16]));
|
|
+ e2p_uuid2str(&jsb->s_users[i * UUID_SIZE]));
|
|
}
|
|
}
|
|
if (jsb->s_errno != 0)
|
|
diff --git a/lib/ext2fs/mkjournal.c b/lib/ext2fs/mkjournal.c
|
|
index 7f78291..a90e80e 100644
|
|
--- a/lib/ext2fs/mkjournal.c
|
|
+++ b/lib/ext2fs/mkjournal.c
|
|
@@ -401,6 +401,8 @@ errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
|
|
|
|
/* Check and see if this filesystem has already been added */
|
|
nr_users = ntohl(jsb->s_nr_users);
|
|
+ if (nr_users > JFS_USERS_MAX)
|
|
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
|
|
for (i=0; i < nr_users; i++) {
|
|
if (memcmp(fs->super->s_uuid,
|
|
&jsb->s_users[i*16], 16) == 0)
|
|
diff --git a/misc/tune2fs.c b/misc/tune2fs.c
|
|
index b8cddfa..ec977b8 100644
|
|
--- a/misc/tune2fs.c
|
|
+++ b/misc/tune2fs.c
|
|
@@ -292,6 +292,12 @@ static int remove_journal_device(ext2_filsys fs)
|
|
jsb = (journal_superblock_t *) buf;
|
|
/* Find the filesystem UUID */
|
|
nr_users = ntohl(jsb->s_nr_users);
|
|
+ if (nr_users > JFS_USERS_MAX) {
|
|
+ fprintf(stderr, _("Journal superblock is corrupted, nr_users\n"
|
|
+ "is too high (%d).\n"), nr_users);
|
|
+ commit_remove_journal = 1;
|
|
+ goto no_valid_journal;
|
|
+ }
|
|
|
|
if (!journal_user(fs->super->s_uuid, jsb->s_users, nr_users)) {
|
|
fputs(_("Filesystem's UUID not found on journal device.\n"),
|
|
@@ -2850,6 +2856,11 @@ fs_update_journal_user(struct ext2_super_block *sb, __u8 old_uuid[UUID_SIZE])
|
|
jsb = (journal_superblock_t *) buf;
|
|
/* Find the filesystem UUID */
|
|
nr_users = ntohl(jsb->s_nr_users);
|
|
+ if (nr_users > JFS_USERS_MAX) {
|
|
+ fprintf(stderr, _("Journal superblock is corrupted, nr_users\n"
|
|
+ "is too high (%d).\n"), nr_users);
|
|
+ return EXT2_ET_CORRUPT_JOURNAL_SB;
|
|
+ }
|
|
|
|
j_uuid = journal_user(old_uuid, jsb->s_users, nr_users);
|
|
if (j_uuid == NULL) {
|
|
|