[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200311105245.125564-4-Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
Date: Wed, 11 Mar 2020 19:52:44 +0900
From: Tetsuhiro Kohada <Kohada.Tetsuhiro@...MitsubishiElectric.co.jp>
To: Kohada.Tetsuhiro@...MitsubishiElectric.co.jp
Cc: Mori.Takahiro@...MitsubishiElectric.co.jp,
motai.hirotaka@...mitsubishielectric.co.jp,
Valdis Kletnieks <valdis.kletnieks@...edu>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
linux-fsdevel@...r.kernel.org, devel@...verdev.osuosl.org,
linux-kernel@...r.kernel.org
Subject: [PATCH 4/5] staging: exfat: add boot region verification
Add Boot-Regions verification specified in exFAT specification.
Reviewed-by: Takahiro Mori <Mori.Takahiro@...MitsubishiElectric.co.jp>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@...MitsubishiElectric.co.jp>
---
drivers/staging/exfat/exfat_core.c | 69 ++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index 3faa7f35c77c..07c876bb1759 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -2017,7 +2017,20 @@ u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type)
chksum = (((chksum & 1) << 15) |
((chksum & 0xFFFE) >> 1)) + (u16)*c;
}
+ return chksum;
+}
+u32 calc_checksum32(void *data, int len, u32 chksum, int type)
+{
+ int i;
+ u8 *c = (u8 *)data;
+
+ for (i = 0; i < len; i++, c++) {
+ if (unlikely(type == CS_BOOT_SECTOR &&
+ (i == 106 || i == 107 || i == 112)))
+ continue;
+ chksum = ((chksum & 1) << 31 | chksum >> 1) + (u32)*c;
+ }
return chksum;
}
@@ -2053,6 +2066,58 @@ s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
return 0;
}
+static int verify_boot_region(struct super_block *sb)
+{
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+ struct buffer_head *tmp_bh = NULL;
+ u32 chksum = 0, *p_signatue, *p_chksum;
+ int sn = 0, i, ret;
+
+ /* read boot sector sub-regions */
+ ret = sector_read(sb, sn++, &tmp_bh, 1);
+ if (ret)
+ goto out;
+
+ chksum = calc_checksum32(tmp_bh->b_data, p_bd->sector_size,
+ chksum, CS_BOOT_SECTOR);
+
+ while (sn < 11) {
+ ret = sector_read(sb, sn++, &tmp_bh, 1);
+ if (ret)
+ goto out;
+
+ chksum = calc_checksum32(tmp_bh->b_data, p_bd->sector_size,
+ chksum, CS_DEFAULT);
+
+ /* skip OEM Parameters & Reserved sub-regions */
+ if (sn >= 9)
+ continue;
+
+ /* extended boot sector sub-regions */
+ p_signatue = (u32 *)(tmp_bh->b_data + p_bd->sector_size - 4);
+ if (le32_to_cpu(*p_signatue) != EXBOOT_SIGNATURE) {
+ ret = -EFSCORRUPTED;
+ goto out;
+ }
+ }
+
+ /* boot checksum sub-regions */
+ ret = sector_read(sb, sn++, &tmp_bh, 1);
+ if (ret)
+ goto out;
+
+ p_chksum = (u32 *)tmp_bh->b_data;
+ for (i = 0; i < p_bd->sector_size / 4; i++) {
+ if (le32_to_cpu(*p_chksum) != chksum) {
+ ret = -EFSCORRUPTED;
+ goto out;
+ }
+ }
+out:
+ brelse(tmp_bh);
+ return ret;
+}
+
static int read_boot_sector(struct super_block *sb)
{
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
@@ -2129,6 +2194,10 @@ s32 exfat_mount(struct super_block *sb)
if (ret)
goto err_out;
+ ret = verify_boot_region(sb);
+ if (ret)
+ goto err_out;
+
ret = load_alloc_bitmap(sb);
if (ret)
goto err_out;
--
2.25.1
Powered by blists - more mailing lists