dorimanx / exfat-nofuse

Android ARM Linux non-fuse read/write kernel driver for exFat and VFat Android file systems
GNU General Public License v2.0
707 stars 326 forks source link

readdir issue,missing files/directories with sandisk ,kernel 2.6.36 #108

Open scholarchen opened 7 years ago

scholarchen commented 7 years ago

Greetings, I found a similar bug with #87 Problem replication: In the windows format the disk to exFAT, and then copy multiple files, stop in the middle (copy some files), it will cause all files cannot be viewed in the Linux by ls command but can be viewed directly in Windows。 problem analysis: I try to view the ls implementation process and found that the call to the getdents64 function will make a mistake by strace command, but I write a test program called getdents can view the file list Tracking kernel code finds that every times __put_user fails,code path :getdents64->vfs_readdir->exfat_readdir->filldir64->__put_user

I printk the struct dirent pointer below,I don't know whether the dirent pointer is out of bounds dirent = buf->current_dir; pr_debug("%s %d %p %p %p\n",__func__,__LINE__,&dirent->d_ino,&dirent->d_off,&dirent->d_reclen); if (__put_user(ino, &dirent->d_ino)) goto efault; getdents pointer is like this

filldir 177 40284058 4028405c 40284060

getdents64 pointer is like this

filldir64 264 bcb90c08 bcb90c10 bcb90c18

other infomations: fsck : fsck.exfat /dev/sda1 exfatfsck 1.2.3 Checking file system on /dev/sda1. File system version 1.0 Sector size 512 bytes Cluster size 32 MB Volume size 29 GB Used space 4911 MB Available space 24 GB Totally 37 directories and 109 files. File system checking finished. No errors found.

strace ls _:ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B115200 opost isig icanon echo ...}) = 0 getuid32() = 0 gettimeofday({1491792068, 179241}, NULL) = 0 ioctl(0, TIOCGWINSZ, {ws_row=0, ws_col=0, ws_xpixel=0, ws_ypixel=0}) = 0 ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B115200 opost isig icanon echo ...}) = 0 ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B115200 opost isig icanon echo ...}) = 0 brk(0) = 0x74000 brk(0x75000) = 0x75000 stat64("/mnt/share/sda1", {st_mode=S_IFDIR|0777, st_size=33554432, ...}) = 0 open("/mnt/share/sda1", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 fstat64(3, {st_mode=S_IFDIR|0777, st_size=33554432, ...}) = 0 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 mmap2(NULL, 33558528, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0) = 0x401f8000 getdents64(3, 0xbcadac08, 33554432) = -1 EFAULT (Bad address) munmap(0x401f8000, 33558528) = 0 close(3) = 0 exitgroup(0) = ? +++ exited with 0 +++