lkml.org 
[lkml]   [2020]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 4/5] staging: exfat: add boot region verification
Date
Add Boot-Regions verification specified in exFAT specification.

Reviewed-by: Takahiro Mori <Mori.Takahiro@ab.MitsubishiElectric.co.jp>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.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
\
 
 \ /
  Last update: 2020-03-11 11:54    [W:4.941 / U:1.756 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site