[PATCH] Tried making changes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Respected Maintainers, 

I have tried to solve the bug - UBSAN: shift-out-of-bounds in exfat_fill_super, reported by Syzbot [link - https://syzkaller.appspot.com/bug?extid=d33808a177641a02213e]

Since it didn't have a reproducer, I wasn't able to test the patch
before sending to the maintainers.

The issue is in line 503 of fs/exfat/super.c - by analyzing the code, I
understood that the it is checking if the calculated size of the exFAT
File Allocation Table is very small as compared to the expected
size,based on the number of clusters. If the condition is met, then an
error will be logged. But here inside the if statement, I believe that
the value of number of bits in sbi->num_FAT_sectors ,at some point is
coming more than the value of p_boot->sect_size_bits. As a result, a
shift-out-of-bounds error is being generated. 

I tried using the hweight_long() to find the number of bits in
sbi->num_FAT_sectors in advance and then perform the left shift
operation only if it's total number of bits is greater than or equal to
the value of p_boot->sect_size_bits. 

I think that a new else statement should also be included with that and
I will do that once I get some help from the maintainers and get to know if I
am thinking in the right direction. 
Requesting the maintainers to go through the code once and kindly help me in understanding whether I am 
I am doing it wrong or if I need to add some more things. 

Thank you
Attreyee Mukherjee

Signed-off-by: Attreyee Mukherjee <tintinm2017@xxxxxxxxx>
---
 fs/exfat/super.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/exfat/super.c b/fs/exfat/super.c
index d9d4fa91010b..0d526d9f3e5e 100644
--- a/fs/exfat/super.c
+++ b/fs/exfat/super.c
@@ -18,6 +18,7 @@
 #include <linux/nls.h>
 #include <linux/buffer_head.h>
 #include <linux/magic.h>
+#include <linux/bitops.h>
 
 #include "exfat_raw.h"
 #include "exfat_fs.h"
@@ -500,11 +501,18 @@ static int exfat_read_boot_sector(struct super_block *sb)
 	sbi->used_clusters = EXFAT_CLUSTERS_UNTRACKED;
 
 	/* check consistencies */
-	if ((u64)sbi->num_FAT_sectors << p_boot->sect_size_bits <
+	u64 num_fat_sectors_u64 = (u64)sbi->num_FAT_sectors;
+	unsigned long num_bits = hweight_long(num_fat_sectors_u64);
+
+	if(num_bits>=p_boot->sect_size_bits){
+
+		if ((u64)sbi->num_FAT_sectors << p_boot->sect_size_bits <
 	    (u64)sbi->num_clusters * 4) {
 		exfat_err(sb, "bogus fat length");
 		return -EINVAL;
+		}
 	}
+	
 
 	if (sbi->data_start_sector <
 	    (u64)sbi->FAT1_start_sector +
-- 
2.34.1





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux