From patchwork Fri Jul 1 13:06:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vegard Nossum X-Patchwork-Id: 9209867 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D122A60752 for ; Fri, 1 Jul 2016 13:09:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C0462286AC for ; Fri, 1 Jul 2016 13:09:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B37E6286AE; Fri, 1 Jul 2016 13:09:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_TVD_MIME_EPI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DFE2286AC for ; Fri, 1 Jul 2016 13:09:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751869AbcGANJI (ORCPT ); Fri, 1 Jul 2016 09:09:08 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:23166 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750702AbcGANJH (ORCPT ); Fri, 1 Jul 2016 09:09:07 -0400 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u61D6k26001790 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 1 Jul 2016 13:06:47 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id u61D6kaN011842 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 1 Jul 2016 13:06:46 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id u61D6hdc027696; Fri, 1 Jul 2016 13:06:45 GMT Received: from [10.175.253.84] (/10.175.253.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 01 Jul 2016 06:06:43 -0700 From: Vegard Nossum Subject: [RFC PATCH] ext4: validate number of meta clusters in group To: "Theodore Ts'o" Cc: Ext4 Developers List , linux-fsdevel@vger.kernel.org Message-ID: <57766AE1.1040508@oracle.com> Date: Fri, 1 Jul 2016 15:06:41 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 MIME-Version: 1.0 X-Source-IP: userv0021.oracle.com [156.151.31.71] Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi, I've found that sbi->s_es->s_reserved_gdt_blocks is not validated before being used, so e.g. a value of 25600 will overflow the buffer head and corrupt random kernel memory (I've observed 20+ different stack traces due to this bug! many of them long after the code has finished). The following patch fixes it for me: However, I think there are potentially more bugs later in this function where offsets are not validated so it needs to be reviewed carefully. Another question is whether we should do the validation earlier, e.g. in ext4_fill_super(). I'm not too familiar with the code, but maybe something like the attached patch would be better? It does seem to fix the issue as well. Vegard From efcee80eb78816a4d495224ffc624adf04217044 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 1 Jul 2016 15:03:39 +0200 Subject: [PATCH] ext4: validate number of base meta clusters in group --- fs/ext4/balloc.c | 4 +--- fs/ext4/ext4.h | 2 ++ fs/ext4/super.c | 10 ++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 3020fd7..ec03f01 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -22,8 +22,6 @@ #include -static unsigned ext4_num_base_meta_clusters(struct super_block *sb, - ext4_group_t block_group); /* * balloc.c contains the blocks allocation and deallocation routines */ @@ -817,7 +815,7 @@ unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group) * This function returns the number of file system metadata clusters at * the beginning of a block group, including the reserved gdt blocks. */ -static unsigned ext4_num_base_meta_clusters(struct super_block *sb, +unsigned ext4_num_base_meta_clusters(struct super_block *sb, ext4_group_t block_group) { struct ext4_sb_info *sbi = EXT4_SB(sb); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index b84aa1ca..e492b0b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2270,6 +2270,8 @@ extern ext4_grpblk_t ext4_block_group_offset(struct super_block *sb, extern int ext4_bg_has_super(struct super_block *sb, ext4_group_t group); extern unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group); +extern unsigned ext4_num_base_meta_clusters(struct super_block *sb, + ext4_group_t block_group); extern ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned int flags, diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 563555e..b5a9d28 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3641,6 +3641,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount; } sbi->s_groups_count = blocks_count; + + for (i = 0; i < sbi->s_groups_count; ++i) { + int bit_max = ext4_num_base_meta_clusters(sb, i); + if ((bit_max >> 3) >= sb->s_blocksize) { + ext4_msg(sb, KERN_WARNING, "meta cluster base for " + "group %u exceeds block size", i); + goto failed_mount; + } + } + sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / -- 1.9.1