e2fsprogs/6005-libe2p-avoid-segfault-when-s_nr_users-is-too-high.patch
2019-09-30 10:37:40 -04:00

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) {