arter97 / exfat-linux

EOL exFAT filesystem module for Linux kernel. Everyone should be using https://github.com/namjaejeon/linux-exfat-oot instead.
Other
262 stars 59 forks source link

Unsupported mount options make exfat kernel module crash #26

Open changyp6 opened 4 years ago

changyp6 commented 4 years ago

If unsupported mount options are provided when mounting exfat file system, this kernel module will crash.

For example, if "flush" is provided in mount -o parameters

arter97 commented 4 years ago

Hmm, I've tested this to make sure my patch works well.

Please tell me the kernel version and the system you're running, and preferably panic stacktrace.

changyp6 commented 4 years ago

@arter97 Kernel version is 4.14.183, running on Cortex-A53 This kernel is a customized kernel, but no modifications on filesystem. mount command is from busybox

Following are the trace

[   27.827260] exFAT: file-system version 5.8-2arter97
[   27.833525] ------------[ cut here ]------------
[   27.915068] task: ffffffc009acd800 task.stack: ffffff8024458000
[   27.920985] pc : __alloc_pages_nodemask+0xf8/0x96c
[   27.925753] lr : kmalloc_order+0x1c/0x40
[   27.929650] sp : ffffff802445ba50 pstate : 20000145
[   27.934503] x29: ffffff802445ba50 x28: ffffffc009acd800 
[   27.939791] x27: 0000000010008000 x26: ffffff8008708eb0 
[   27.945079] x25: ffffffc008a91098 x24: 0000000000000001 
[   27.950366] x23: ffffff802445bc5c x22: 00000000014040c0 
[   27.955653] x21: ffffffbffd2a0df8 x20: ffffff802445bcc0 
[   27.960940] x19: ffffffc008a90017 x18: 00000000fffffffe 
[   27.966227] x17: 0000007f8d917af0 x16: 0000000000000000 
[   27.971515] x15: 174e011307111d0c x14: ffff000000000000 
[   27.976802] x13: 0000000000000000 x12: 0000000000000007 
[   27.982089] x11: 0000000000000007 x10: 0101010101010101 
[   27.987376] x9 : 0000000000000007 x8 : 0000000000000001 
[   27.992664] x7 : 0000000000000008 x6 : 000000000000002c 
[   27.997951] x5 : 0000000000000066 x4 : 0000000000000001 
[   28.003237] x3 : 0000000000000000 x2 : 0000000000000000 
[   28.008524] x1 : 0000000000000034 x0 : 0000000000000000 
[   28.013811] Call trace:
[   28.016242]  __alloc_pages_nodemask+0xf8/0x96c
[   28.020661]  kmalloc_order+0x1c/0x40
[   28.024215]  __kmalloc+0x164/0x1e0
[   28.027597]  match_number+0x38/0xbc
[   28.031062]  match_int+0x10/0x20
[   28.034289]  __exfat_parse_option+0xd0/0x250 [exfat]
[   28.039243]  exfat_parse_options+0x78/0x1a0 [exfat]
[   28.044111]  exfat_fill_super+0x7c/0x2c0 [exfat]
[   28.048706]  mount_bdev+0x208/0x250
[   28.052186]  exfat_fs_mount+0x10/0x20 [exfat]
[   28.056519]  mount_fs+0x1c/0xb0
[   28.059641]  vfs_kern_mount.part.0+0x4c/0x16c
[   28.063974]  do_mount+0x158/0x4c0
[   28.067267]  SyS_mount+0x8c/0xf0
[   28.070475]  el0_svc_naked+0x34/0x38
[   28.074026] ---[ end trace 002c67656291c8d3 ]---
[   28.079364] exFAT-fs (sda1): failed to parse options

I did some experiments.

If I manually run command mount -t exfat -o "errors=remount-ro,relatime,noatime,nodiratime,user,utf8,flush,gid=100,dmask=000" /dev/sda1 /storage/sda1

command just fails with error [ 1646.195784] exFAT-fs (sda1): failed to parse options

However, if the mount operation is triggerred by udev, kernel dump will occur.

The invalid option is flush, if I put flush at the first position, driver reports exFAT-fs (sda1): failed to parse options, if I put flush at the last position, exFAT mounts successfully. if I put flush in the middle of other options, driver crash.

It is indeed related to option parser.

changyp6 commented 4 years ago

@arter97 I have found the bug.

According to the definition of match_token function, match_table_t data structure should be terminated with a NULL structure.

Following patch will fix this bug

diff --git a/exfat-linux/src/super.c b/exfat-linux/src/super.c
index 804bc4e9a..b7d24b378 100644
--- a/exfat-linux/src/super.c
+++ b/exfat-linux/src/super.c
@@ -236,6 +236,7 @@ enum {
        Opt_debug,
        Opt_namecase,
        Opt_codepage,
+       Opt_err,
 };

 static const match_table_t exfat_tokens = {
@@ -258,6 +259,7 @@ static const match_table_t exfat_tokens = {
        {Opt_debug, "debug"},
        {Opt_namecase, "namecase=%u"},
        {Opt_codepage, "codepage=%u"},
+       {Opt_err, NULL},
 };
Alexander-Shukaev commented 2 years ago

Is this merged?