Received: by 2002:a17:90a:8504:0:0:0:0 with SMTP id l4csp398946pjn; Wed, 23 Oct 2019 01:18:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqxRXWOUkdSvlVYLbbceIVdMoL3m/cEOkCd7tQgxWCUPaPgS2vkxUGM3zBGbKdo/sj9RIL0t X-Received: by 2002:a17:906:5c0a:: with SMTP id e10mr31512700ejq.285.1571818713955; Wed, 23 Oct 2019 01:18:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571818713; cv=none; d=google.com; s=arc-20160816; b=BTYRkK51OYrdDbOhEuhum1TmjjEimt4t2XwZv409T2XnUXnF23L3lnv4EKnVWCbGHe yYg25HMDtIhOfsirPe9whMMQvbW1sAriUPSPtIX0BfWve/yD7xDDv9ZmB4Q58FBqYmvi DeHOT37nZVGyc9cflNE2txXLR+cOypHwyBaxooQwpU7i+d9YsqUMR2v1Et/SQS7sNtkc W/WJjTZRtDgBETX1xDKgwHJTgYOQNm0KJyVRpOc085JaldkqacVoPSe7+tVqvjC6RK4o +WxdZ2EkwdrCFOoEo6YXUtPFsR05/SThtCn2nzSxcyCUKFD8PWfp1Y2QBnLE9TUI9X4V vGhA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=LTw760UPNTleTn3oBB2EXBItpD1VbHY8JZcWZPygFEQ=; b=FypsTg3HB8xwvOf2Wg4/0Uc5wnkXjX7Jl6ppN/Gt5fGFR3mCNcmEU5TVzyXL4uq5Af FkOIodOSoEix8S+4iG1GXjf8vXbfJ4/xyOoGfYjSoViREVeZ0iEYlkDHxGt0xvZTVywM hErFqdcoBPGcsYKdA0vGmAkTwXKwR9wOEsOOh8KqQ+M1qbfmB8WEbyzd5DO3/afC+MYC yFToZQ08HXLW/MivGfe03KCkvmNqtNw3raw5jcaO+vFlyFnsYqEOk/EG4zOolD4qcEgJ bl53xEdjgI9t1vzz5ahL6DeV7OKKt0QT+084/jp5PFgLzfghe9Q9Xmap7PpOxje8JFRX s6UA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id gv25si8099733ejb.209.2019.10.23.01.18.10; Wed, 23 Oct 2019 01:18:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390201AbfJWIRC (ORCPT + 99 others); Wed, 23 Oct 2019 04:17:02 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:40078 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2389987AbfJWIRC (ORCPT ); Wed, 23 Oct 2019 04:17:02 -0400 Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 00703BF957FC376344C8; Wed, 23 Oct 2019 16:16:59 +0800 (CST) Received: from [10.134.22.195] (10.134.22.195) by smtp.huawei.com (10.3.19.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Wed, 23 Oct 2019 16:15:30 +0800 Subject: Re: [PATCH v4] erofs: support superblock checksum To: Gao Xiang , Chao Yu , CC: Gao Xiang , References: <20191022180620.19638-1-pratikshinde320@gmail.com> <20191023040557.230886-1-gaoxiang25@huawei.com> From: Chao Yu Message-ID: Date: Wed, 23 Oct 2019 16:15:29 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 In-Reply-To: <20191023040557.230886-1-gaoxiang25@huawei.com> Content-Type: text/plain; charset="windows-1252" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.134.22.195] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Xiang, Pratik, On 2019/10/23 12:05, Gao Xiang wrote: > From: Pratik Shinde > > Introduce superblock checksum feature in order to check > a number of given blocks at mounting time. > > Signed-off-by: Pratik Shinde > Signed-off-by: Gao Xiang > --- > changes from v3: > (based on Pratik's v3 patch) > - add LIBCRC32C dependency; > - use kmap() in order to avoid sleeping in atomic context; > - skip the first 1024 byte for x86 boot sector, > co-tested with userspace utils, > https://lore.kernel.org/r/20191023034957.184711-1-gaoxiang25@huawei.com > > fs/erofs/Kconfig | 1 + > fs/erofs/erofs_fs.h | 6 +++-- > fs/erofs/internal.h | 2 ++ > fs/erofs/super.c | 53 +++++++++++++++++++++++++++++++++++++++++++-- > 4 files changed, 58 insertions(+), 4 deletions(-) > > diff --git a/fs/erofs/Kconfig b/fs/erofs/Kconfig > index 9d634d3a1845..74b0aaa7114c 100644 > --- a/fs/erofs/Kconfig > +++ b/fs/erofs/Kconfig > @@ -3,6 +3,7 @@ > config EROFS_FS > tristate "EROFS filesystem support" > depends on BLOCK > + select LIBCRC32C > help > EROFS (Enhanced Read-Only File System) is a lightweight > read-only file system with modern designs (eg. page-sized > diff --git a/fs/erofs/erofs_fs.h b/fs/erofs/erofs_fs.h > index b1ee5654750d..461913be1d1c 100644 > --- a/fs/erofs/erofs_fs.h > +++ b/fs/erofs/erofs_fs.h > @@ -11,6 +11,8 @@ > > #define EROFS_SUPER_OFFSET 1024 > > +#define EROFS_FEATURE_COMPAT_SB_CHKSUM 0x00000001 > + > /* > * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should > * be incompatible with this kernel version. > @@ -37,8 +39,8 @@ struct erofs_super_block { > __u8 uuid[16]; /* 128-bit uuid for volume */ > __u8 volume_name[16]; /* volume name */ > __le32 feature_incompat; > - > - __u8 reserved2[44]; > + __le32 chksum_blocks; /* number of blocks used for checksum */ > + __u8 reserved2[40]; > }; > > /* > diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h > index 544a453f3076..a3778f597bf6 100644 > --- a/fs/erofs/internal.h > +++ b/fs/erofs/internal.h > @@ -85,6 +85,7 @@ struct erofs_sb_info { > > u8 uuid[16]; /* 128-bit uuid for volume */ > u8 volume_name[16]; /* volume name */ > + u32 feature_compat; > u32 feature_incompat; > > unsigned int mount_opt; > @@ -426,6 +427,7 @@ static inline void z_erofs_exit_zip_subsystem(void) {} > #endif /* !CONFIG_EROFS_FS_ZIP */ > > #define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ > +#define EFSBADCRC EBADMSG /* Bad CRC detected */ > > #endif /* __EROFS_INTERNAL_H */ > > diff --git a/fs/erofs/super.c b/fs/erofs/super.c > index 0e369494f2f2..18d1ec18a671 100644 > --- a/fs/erofs/super.c > +++ b/fs/erofs/super.c > @@ -9,6 +9,7 @@ > #include > #include > #include > +#include > #include "xattr.h" > > #define CREATE_TRACE_POINTS > @@ -46,6 +47,47 @@ void _erofs_info(struct super_block *sb, const char *function, > va_end(args); > } > > +static int erofs_superblock_csum_verify(struct super_block *sb, void *sbdata) > +{ > + struct erofs_super_block *dsb; > + u32 expected_crc, nblocks, crc; > + void *kaddr; > + struct page *page; > + int i; > + > + dsb = kmemdup(sbdata + EROFS_SUPER_OFFSET, > + EROFS_BLKSIZ - EROFS_SUPER_OFFSET, GFP_KERNEL); > + if (!dsb) > + return -ENOMEM; > + > + expected_crc = le32_to_cpu(dsb->checksum); > + nblocks = le32_to_cpu(dsb->chksum_blocks); Now, we try to use nblocks's value before checking its validation, I guess fuzz test can easily make the value extreme larger, result in checking latter blocks unnecessarily. IMO, we'd better 1. check validation of superblock to make sure all fields in sb are valid 2. use .nblocks to count and check payload blocks following sb Thanks, > + dsb->checksum = 0; > + /* to allow for x86 boot sectors and other oddities. */ > + crc = crc32c(~0, dsb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET); > + kfree(dsb); > + > + for (i = 1; i < nblocks; i++) { > + page = erofs_get_meta_page(sb, i); > + if (IS_ERR(page)) > + return PTR_ERR(page); > + > + kaddr = kmap_atomic(page); > + crc = crc32c(crc, kaddr, EROFS_BLKSIZ); > + kunmap_atomic(kaddr); > + > + unlock_page(page); > + put_page(page); > + } > + > + if (crc != expected_crc) { > + erofs_err(sb, "invalid checksum 0x%08x, 0x%08x expected", > + crc, expected_crc); > + return -EFSBADCRC; > + } > + return 0; > +} > + > static void erofs_inode_init_once(void *ptr) > { > struct erofs_inode *vi = ptr; > @@ -112,7 +154,7 @@ static int erofs_read_superblock(struct super_block *sb) > > sbi = EROFS_SB(sb); > > - data = kmap_atomic(page); > + data = kmap(page); > dsb = (struct erofs_super_block *)(data + EROFS_SUPER_OFFSET); > > ret = -EINVAL; > @@ -121,6 +163,13 @@ static int erofs_read_superblock(struct super_block *sb) > goto out; > } > > + sbi->feature_compat = le32_to_cpu(dsb->feature_compat); > + if (sbi->feature_compat & EROFS_FEATURE_COMPAT_SB_CHKSUM) { > + ret = erofs_superblock_csum_verify(sb, data); > + if (ret) > + goto out; > + } > + > blkszbits = dsb->blkszbits; > /* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */ > if (blkszbits != LOG_BLOCK_SIZE) { > @@ -155,7 +204,7 @@ static int erofs_read_superblock(struct super_block *sb) > } > ret = 0; > out: > - kunmap_atomic(data); > + kunmap(data); > put_page(page); > return ret; > } >