Giter Site home page Giter Site logo

dosfstools / dosfstools Goto Github PK

View Code? Open in Web Editor NEW
243.0 13.0 112.0 1 MB

dosfstools consists of the programs mkfs.fat, fsck.fat and fatlabel to create, check and label file systems of the FAT family.

License: GNU General Public License v3.0

Shell 2.05% C 79.11% Makefile 3.32% M4 0.84% Roff 14.67%
fat c mkfs fsck filesystem

dosfstools's Introduction

dosfstools consists of the programs mkfs.fat, fsck.fat and fatlabel to create, check and label file systems of the FAT family. The dosfstools are licensed under the GNU GPL version 3 or later. See the file COPYING for details.

Build Requirements

The test suite requires the tool xxd (available as part of the vim distribution).

Installing

dosfstools are built using an autoconf/automake system, so the standard method applies:

./configure
make
make install

You need to have superuser privileges in order to install into the standard system wide locations.

The ./configure script has an option --enable-compat-symlinks that will configure the build to symlink older names of the tools to the current ones on installation. These are dosfsck, fsck.msdos and fsck.vfat for fsck.fat, mkdosfs, mkfs.msdos and mkfs.vfat for mkfs.fat and dosfslabel for fatlabel.

Running the test suite

The test suite can be run with make check after configuring. Note that if xxd isn't available, all tests will be skipped and nothing actually tested.

During the tests temporary files of multiple GB in size will be created, but the actual data content is not more than a few MB. The operating system and the filesystem the tests are executed on should support sparse files, otherwise the tests will be resource intensive.

Building from the VCS repository

If you are working directly from a git clone of the official dosfstools repository, you will find that you can not run ./configure straight away because it, like other autogenerated files for the build system, is not included in the repository.

First, autoconf, automake and gettext have to be installed. Then you can run ./autogen.sh to generate all the required files.

dosfstools's People

Contributors

alkor avatar andreasbombe avatar bjornfor avatar crrodriguez avatar daniel-baumann avatar davidgumberg avatar ferivoz avatar fstirlitz avatar i0ntempest avatar laborer2008 avatar lkundrak avatar michaelforney avatar michal-szczepaniak avatar mvrable avatar mwilck avatar ncommander avatar ncopa avatar noltari avatar olerem avatar pali avatar pgajdos avatar poettering avatar radhermit avatar smagnani avatar stapelberg avatar stoeckmann avatar ulm avatar vapier avatar yann-morin-1998 avatar yarda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dosfstools's Issues

Code page for FAT volume label

FAT volume label specified either for mkfs.fat or for fatlabel is treated as is -- as binary bytes.

But according to specification and also observed from Windows behavior, FAT volume label is interpreted according to current DOS code page. Basically in the same way as fsck.fat handle file names. As linux does not have "current DOS code page", there is no way to get one. fsck.fat has already option -c for specifying it.

I would propose -c option also for fatlabel and mkfs.fat to allow specify how should be FAT label treated when reading it or writing it.

libiconv_open unreferenced make error

the error after intalling libiconv-1.5 while:

charconv.o: In function iconv_init_codepage': /cygdrive/c/Users/x/Documents/mygame/magh4862/dosfstools-4.1/src/charcon v.c:12: undefined reference to libiconv_open'
/cygdrive/c/Users/x/Documents/mygame/magh4862/dosfstools-4.1/src/charcon v.c:12:(.text+0x2f): relocation truncated to fit: R_X86_64_PC32 against undefine d symbol libiconv_open' charconv.o: In function dos_char_to_printable':
/cygdrive/c/Users/x/Documents/mygame/magh4862/dosfstools-4.1/src/charcon v.c:58: undefined reference to libiconv' /cygdrive/c/Users/x/Documents/mygame/magh4862/dosfstools-4.1/src/charcon v.c:58:(.text+0x195): relocation truncated to fit: R_X86_64_PC32 against undefin ed symbol libiconv'

[git master] fsck.vfat: return non-zero exitcode when errors and user quit

fsck.vfat should perhaps return non-zero exit code in this case?

Starting check/repair pass.
FATs differ but appear to be intact.1) Use first FAT
2) Use second FAT
[12?q]? q
No changes have been written to the filesystem yet. If you choose
to quit, it will be left in the same state it was in before you
started this program.
1) Quit now
2) Continue
[12?]? 1

using current git master.

How to drop incorrect file name?

Hi. I try to repair filesystem on my SD card.
I have a .JPG file which recognized as directory with infinity content.

Full paht is: /DCIM/170_1308/i├R6&4v.JPG

Auto-rename don't performed and i can't choose "drop it".
When i start dosfsck with -d option i got an error:

Invalid character in name. Use \ooo for special characters.

But this character have too long code in octal form - 22434, when program expect only 3 nums

I read name by python and translate symbol:

int chr octal
9500 ├ 0o22434

mkfs.fat: changing sec_per_track problematic

I'm not sure if this really is a bug in dosfstools, maybe you can help with that.

The latest release changes the default sectors-per-track value to 63 and master has a commit that seems to make it depend on target size. Can you explain why these need to be done -- isn't this value cosmetic by now?

Yocto generates images with "mkfs.fat" and then uses "mcopy" to copy data to them. mcopy has a sanity check to make sure total sector count is divisible by sectors-per-track. It's becoming very difficult to make the image size correct when the sectors-per-track keeps changing based on version of dosfstools...

Is it possible to give the caller more control over sectors-per-track, or would you say "mcopy" is wrong to do the sanity check it does?

mkfs.vfat refuses to work without -I on loop device

Hi,

I've encountered a strange issue when trying to build a live-build hdd image for the upcoming Debian Stretch release. As one of the last steps, live-build attempts to generate an image file with a FAT partition to boot from. At the beginning we have an empty "binary.img" file. Then, "parted" is used to create a partition table at offset 0. Then, the image file is mounted again using losetup and the -o parameter to specify an offset of one sector. Then, mkfs.vfat is called on the /dev/loop0 device in order to create a new FAT filesystem. However, mkfs.vfat refuses to do this without the -I parameter (error message: Partitions or virtual mappings on device '/dev/loop0', not making filesystem (use -I to override)).

A hexdump on /dev/loop0 reveals that is only contains zeros. However, mkfs.vfat seems to take a glimpse behind the curtains and sees the the original file has a partition table at offset 0!

You can find the relevant live-build code here:
https://github.com/timrchavez/live-build/blob/master/scripts/build/binary_hdd#L202

The error message in mkfs.vfat is generated here:
https://github.com/dosfstools/dosfstools/blob/master/src/mkfs.fat.c#L1670

dosfstools 4.1 compilation failed with glibc 2.27 version.

Hi ,

I am compiling the dosfstools 4.1 version with gcc 4.9.4 and glibc 2.27 and i am getting the below error.

x86_64-linux-gnu-gcc --sysroot=/home/work/x86_64/rootfs/x86_64-linux-gnu -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -g -O2 -L/usr/lib64 -ludev -o testdevinfo testdevinfo-testdevinfo.o testdevinfo-device_info.o blkdev/testdevinfo-blkdev.o blkdev/testdevinfo-linux_version.o
/home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libm.so.6: undefined reference to __strtof128_nan@GLIBC_PRIVATE' /home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libpthread.so.0: undefined reference to _IO_enable_locks@GLIBC_PRIVATE'
/home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libpthread.so.0: undefined reference to __mmap@GLIBC_PRIVATE' /home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libpthread.so.0: undefined reference to __munmap@GLIBC_PRIVATE'
/home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libresolv.so.2: undefined reference to __resolv_context_get@GLIBC_PRIVATE' /home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libresolv.so.2: undefined reference to __resolv_context_get_override@GLIBC_PRIVATE'
/home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libpthread.so.0: undefined reference to __mprotect@GLIBC_PRIVATE' /home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libpthread.so.0: undefined reference to __tunable_get_val@GLIBC_PRIVATE'
/home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libresolv.so.2: undefined reference to __resolv_context_get_preinit@GLIBC_PRIVATE' /home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/librt.so.1: undefined reference to __close_nocancel@GLIBC_PRIVATE'
/home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libpthread.so.0: undefined reference to __sigtimedwait@GLIBC_PRIVATE' /home/work/x86_64/rootfs/x86_64-linux-gnu/lib64/libresolv.so.2: undefined reference to __resolv_context_put@GLIBC_PRIVATE'
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:435: testdevinfo] Error 1
make[4]: *** Waiting for unfinished jobs....
mv -f .deps/mkfs_fat-mkfs.fat.Tpo .deps/mkfs_fat-mkfs.fat.Po
make[3]: *** [Makefile:400: all-recursive] Error 1

The same dosfstools version compilation was successful with the gcc 4.94 and glibc 2.24. Is this any know issue, Please provide your inputs.

Regards,
Rajesh.

dosfstools patches from Nokia

Nokia for Maemo N900 device heavily patched dosfstools package, but IIRC their changes were never send to upstream. Just to not loose their changes forever I'm sending link to patch file, which contains all changes. Patches can be found in debian/patches directory.

http://deriv.debian.net/Maemo/patches/d/dosfstools/dosfstools_3.0.1-1_dosfstools_3.0.1-1maemo6+0m5.patch

Please investigate if something is useful for upstream. E.g. there is:

++/* A simple block allocator to speed up and cut down the huge memory
++ * overhead of dosfsck allocs (with full 8GB file system, cuts 120MB
++ * memory usage to 80MB)

Heap overflow in function read_fat()

The attached file will cause a heap overflow in the function read_fat (it's zip-packed, because github only allows certain file types).
This was found via fuzzing with american fuzzy lop and address sanitizer.

Address Sanitizer error message / stack trace:

==2804==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c00000be78 at pc 0x00000049e22f bp 0x7ffde1e2f3b0 sp 0x7ffde1e2eb60
WRITE of size 21474836600 at 0x60c00000be78 thread T0
    #0 0x49e22e in __asan_memset (/home/hanno/Desktop/dosfstools/src/fsck.fat+0x49e22e)
    #1 0x4f4971 in read_fat /mnt/ram/dosfstools/src/fat.c:160:5
    #2 0x4e018c in main /mnt/ram/dosfstools/src/fsck.fat.c:187:12
    #3 0x7f5e7c77562f in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.22-r4/work/glibc-2.22/csu/libc-start.c:289
    #4 0x4181e8 in _start (/home/hanno/Desktop/dosfstools/src/fsck.fat+0x4181e8)

0x60c00000be78 is located 0 bytes to the right of 120-byte region [0x60c00000be00,0x60c00000be78)
allocated by thread T0 here:
    #0 0x4b3888 in __interceptor_malloc (/home/hanno/Desktop/dosfstools/src/fsck.fat+0x4b3888)
    #1 0x4f332c in alloc /mnt/ram/dosfstools/src/common.c:66:17

SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/hanno/Desktop/dosfstools/src/fsck.fat+0x49e22e) in __asan_memset
Shadow bytes around the buggy address:
  0x0c187fff9770: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff9780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff9790: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff97a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff97b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c187fff97c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[fa]
  0x0c187fff97d0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c187fff97e0: 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa
  0x0c187fff97f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa
  0x0c187fff9800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c187fff9810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
[dosfstools-heapoverflow-read_fat.zip](https://github.com/dosfstools/dosfstools/files/215455/dosfstools-heapoverflow-read_fat.zip)

fsck.fat complains about spaces in file names

fsck.fat complains about short file names with spaces in the middle (with the exception of EA DATA. SF and WP ROOT. SF), even though they are actually sort-of permitted under DOS; the syscall interface (INT 21h) allows using them, and Microsoft tools don't complain about them. The COMMAND.COM from Windows 9x even allows you to do this (outside a Windows session, of course):

C:\TEST>mkdir "1 2 3"

C:\TEST>echo foo > "7 8 9"

C:\TEST>type "7 8 9"
foo

C:\TEST>dir /b
1 2 3
7 8 9

Given that files with such names may be hard to access in DOS programs (which are the main users of short file names), fsck.fat should probably keep an option to treat them as invalid.

-w still prompts for `Perform changes ? (y/n)` but changes were already written

sudo fsck.vfat -v -f -V -w -- /dev/sdb1

This still prompts for Perform changes ? (y/n) and answering n is useless because at least the second FAT(what I tested this on: invalidated 2nd FAT) was already written. A second run of the same command detects nothing wrong, but this time no prompt and thus fs_flush(void) is reached.

I'm on Arch Linux, dosfstools 4.1-1

Replacing '-w' with '-r' still prompts, as expected, and changes(second FAT at least) aren't written, as expected.

mkfs.fat number of reserved sectors has changed.

An explicit -R switch is ignored. 3.0.28 vs. 4.1:

[⋐]$ mkfs.fat -v -F16 -R1 -D0x80 -I -M0xF8 -n RPIBOOT out/target/product/rpi3/rpi_boot.img
mkfs.fat 3.0.28 (2015-05-16)
out/target/product/rpi3/rpi_boot.img has 64 heads and 32 sectors per track,
hidden sectors 0x0000;
logical sector size is 512,
using 0xf8 media descriptor, with 131072 sectors;
drive number 0x80;
filesystem has 2 16-bit FATs and 4 sectors per cluster.
FAT size is 128 sectors, and provides 32695 clusters.
There is 1 reserved sector.
Root directory contains 512 slots and uses 32 sectors.
Volume ID is 01ce154f, volume label RPIBOOT .

[⋐]$ /sbin/mkfs.fat -v -F16 -R1 -D0x80 -I -M0xF8 -n RPIBOOT out/target/product/rpi3/rpi_boot.img
mkfs.fat 4.1 (2017-01-24)
out/target/product/rpi3/rpi_boot.img has 64 heads and 32 sectors per track,
hidden sectors 0x0000;
logical sector size is 512,
using 0xf8 media descriptor, with 131072 sectors;
drive number 0x80;
filesystem has 2 16-bit FATs and 4 sectors per cluster.
FAT size is 128 sectors, and provides 32695 clusters.
There are 4 reserved sectors.
Root directory contains 512 slots and uses 32 sectors.
Volume ID is 0235d0f0, volume label RPIBOOT .

Please clarify licensing of the dummy boot sector

The src/mkfs.fat.c file is currently licensed as GPLv3 or later. So, this also applies to the dummy boot code contained there. Thus, everyone who did the steps below is, technically, guilty of GPLv3 violation. It's likely that it's not what you want. If that's the case, please relicense the dummy boot code more permissively.

The steps are:

  1. Take a USB flash drive.
  2. Format it using mkfs.fat.
  3. Give the flash drive to someone else, without also giving dosfstools source.

GPL license

Hello,

I saw that dosfstools is based on mkdosfs and dosfsck. Mkdosfs in licensed under GPL-2.0 or any later version but from my research, dosfsck is licensed under GPL-2.0 only. Can you please give me more details as GPL-2.0 is incompatible with GPL-3.0? Did the author give you permission to upgrade it to GPL-3.0?

Thank you.

View/Change volume-id

Currently it is possible to specify volume-id (UUID) when formatting via -i mkdosfs option. But it is not possible to view volume-id of some existing file system and also it is not possible to change it.

Please provide some tool for view and change volume-id.

Regular report of status progress fs checking

Your file system checker for FAT32 is used by ReactOS. And in it missing component for reporting of current status of checking. When system is installed or updated, running disk checking, but due missing this component, users can't understand when it will end. Can you implement it, please.

global out of bounds reads in file_stat() / check_dir()

This input file will cause out of bounds reads in fsck.fat:
https://crashes.fuzzing-project.org/dosfstools-date_dos2unix-oob-read-heap

This can be seen with address sanitizer. Now the situation seems a bit tricky, because different combinations of compilers (gcc or clang) and cflags will show different bugs.

This is with CC set to clang (3.7) and CFLAGS="-fsanitize=address -O3":

==20294==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000050dc7c at pc 0x0000004e700e bp 0x7ffdef038790 sp 0x7ffdef038788
READ of size 4 at 0x00000050dc7c thread T0
    #0 0x4e700d in check_dir (/mnt/ram/dosfstools/src/fsck.fat+0x4e700d)
    #1 0x4e41a5 in scan_root (/mnt/ram/dosfstools/src/fsck.fat+0x4e41a5)
    #2 0x4f68c9 in main (/mnt/ram/dosfstools/src/fsck.fat+0x4f68c9)
    #3 0x7f6d37dae7af in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.21-r1/work/glibc-2.21/csu/libc-start.c:289
    #4 0x418058 in _start (/mnt/ram/dosfstools/src/fsck.fat+0x418058)

0x00000050dc7c is located 4 bytes to the left of global variable 'day_n' defined in 'check.c:227:12' (0x50dc80) of size 64
0x00000050dc7c is located 35 bytes to the right of global variable '<string literal>' defined in 'check.c:259:19' (0x50dc40) of size 25
  '<string literal>' is ascii string '  Size %u bytes, date %s'

This is with CC set to gcc (5.2.0) and CFLAGS="-fsanitize=address -O3" (with older gcc 4.9 bug doesn't show up):

==20954==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000041c19c at pc 0x0000004058de bp 0x7ffd2dbed990 sp 0x7ffd2dbed980
READ of size 4 at 0x00000041c19c thread T0
    #0 0x4058dd in file_stat.isra.0 (/mnt/ram/dosfstools/src/fsck.fat+0x4058dd)
    #1 0x40b7df in check_dir (/mnt/ram/dosfstools/src/fsck.fat+0x40b7df)
    #2 0x40e3a6 in scan_root (/mnt/ram/dosfstools/src/fsck.fat+0x40e3a6)
    #3 0x402179 in main (/mnt/ram/dosfstools/src/fsck.fat+0x402179)
    #4 0x7f1bf7ca37af in __libc_start_main (/lib64/libc.so.6+0x207af)
    #5 0x402498 in _start (/mnt/ram/dosfstools/src/fsck.fat+0x402498)

0x00000041c19c is located 36 bytes to the right of global variable '*.LC94' defined in 'check.c' (0x41c160) of size 24
  '*.LC94' is ascii string 'Root directory is full.'
0x00000041c19c is located 4 bytes to the left of global variable 'day_n' defined in 'check.c:227:12' (0x41c1a0) of size 64

This is with clang (3.7) and CFLAGS="-fsanitize=address -g -O3":

==27976==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000050de3c at pc 0x0000004e700e bp 0x7ffd42a7a790 sp 0x7ffd42a7a788
READ of size 4 at 0x00000050de3c thread T0
    #0 0x4e700d in date_dos2unix /mnt/ram/dosfstools/src/check.c:242:29
    #1 0x4e700d in file_stat /mnt/ram/dosfstools/src/check.c:256
    #2 0x4e700d in check_dir /mnt/ram/dosfstools/src/check.c:771
    #3 0x4e41a5 in scan_root /mnt/ram/dosfstools/src/check.c:1081:11
    #4 0x4f6a79 in main /mnt/ram/dosfstools/src/fsck.fat.c:187:27
    #5 0x7fc8c5cf57af in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.21-r1/work/glibc-2.21/csu/libc-start.c:289
    #6 0x418058 in _start (/mnt/ram/dosfstools/src/fsck.fat+0x418058)

0x00000050de3c is located 4 bytes to the left of global variable 'day_n' defined in 'check.c:227:12' (0x50de40) of size 64
0x00000050de3c is located 35 bytes to the right of global variable '<string literal>' defined in 'check.c:259:19' (0x50de00) of size 25
  '<string literal>' is ascii string '  Size %u bytes, date %s'

So it seems depending on optimizations different bugs are triggered.

XFAIL: check-dot_entries

41206  [2017-09-25 14:35:28 +0200 Mon] git clone https://github.com/dosfstools/dosfstools
41207  [2017-09-25 14:35:39 +0200 Mon] cd dosfstools/
41208  [2017-09-25 14:36:58 +0200 Mon] ./configure
41209  [2017-09-25 14:38:16 +0200 Mon] autoreconf -i
41210  [2017-09-25 14:38:31 +0200 Mon] ./configure 
41211  [2017-09-25 14:38:48 +0200 Mon] make
41212  [2017-09-25 14:39:10 +0200 Mon] ./configure --enable-compat-symlinks
41213  [2017-09-25 14:39:15 +0200 Mon] make
41214  [2017-09-25 14:39:19 +0200 Mon] sudo make install
41215  [2017-09-25 14:39:22 +0200 Mon] make
41216  [2017-09-25 14:39:27 +0200 Mon] make check
$ cat test-suite.log 
==============================================
   dosfstools 4.1+git: tests/test-suite.log
==============================================

# TOTAL: 10
# PASS:  9
# SKIP:  0
# XFAIL: 1
# FAIL:  0
# XPASS: 0
# ERROR: 0

.. contents:: :depth: 2

XFAIL: check-dot_entries
========================

Test check-dot_entries
First fsck run to check and fix error...
fsck.fat 4.1+git (2017-01-24)
check-dot_entries.img: 4 files, 3/63931 clusters
*** Error was not detected by fsck.
XFAIL check-dot_entries.fsck (exit status: 100)

$ 

fsck.fat complain about filename ÕÕÕ

File with name ÕÕÕ according to DOS codepage 850 is stored as 0x05 0xE5 0xE5 0x20 .... in directory entry. It is completely valid filename, but fsck.fat complain about it.

$ fsck.fat -c 850 -v fat 
fsck.fat 4.1+git (2017-01-24)
Checking we can access the last sector of the filesystem
Boot sector contents:
System ID "mkdosfs"
Media byte 0xf8 (hard disk)
       512 bytes per logical sector
      2048 bytes per cluster
         4 reserved sectors
First FAT starts at byte 2048 (sector 4)
         2 FATs, 16 bit entries
     30720 bytes per FAT (= 60 sectors)
Root directory starts at byte 63488 (sector 124)
       512 root directory entries
Data area starts at byte 79872 (sector 156)
     15321 data clusters (31377408 bytes)
32 sectors/track, 64 heads
         0 hidden sectors
     61440 sectors total
/ÕÕÕ
  Bad short file name (ÕÕ).
1) Drop file
2) Rename file
3) Auto-rename
4) Keep it
[1234?q]?

Steps to reproduce:

  1. Set terminal to UTF-8
  2. Mount FAT32 filesystem with -t vfat -o codepage=850,iocharset=utf8
  3. Create UTF-8 filename ÕÕÕ
  4. Unmount and run fsck.fat

mkfs.fat -n "" generates file system with invalid label

If argument for -n (volume name) option is empty, then it is handled incorrectly and stores label as " " instead of "NO NAME " (which is correct way how to store empty label).

If -n is not specified then empty label is stored correctly.

-l with no bad blocks

$ touch /tmp/empty
$ sudo src/mkfs.fat -l /tmp/empty /dev/sdh1
mkfs.fat 3.99.0 (2015-05-16)
mkfs.fat: Invalid cluster number in mark_FAT_sector: probably bug!

It should simply ignore -l if the file is empty.

fsck.fat: Both FATs appear to be corrupt. Giving up.

I got a USB disk with a fat32 partition where one file was not readable.
In dmesg this output was shown:
FAT-fs (sdb1): error, fat_bmap_cluster: request beyond EOF (i_pos 3815167)

Otherwise the partition had no other problems so far.

Therefore tried to make a fsck.vfat (debian, 3.0.27-1, 3.0.28-2, 3.99.0~git20160203).
A dirty bit was successfully repaired.
But the message "Both FATs appear to be corrupt. Giving up." was still showing up.

This is how the content looks at the offset where function get_fat tried to read the
first FAT_ENTRY struct:
00004000 00 00 00 00 ff ff ff 0f f8 ff ff 0f 04 00 00 00 |................|

The second area looks the same:
03a38c00 00 00 00 00 ff ff ff 0f f8 ff ff 0f 04 00 00 00 |................|

In my case there was also a difference in first and second copy and therefore I
got into this path.
if (second && memcmp(first, second, eff_size) != 0) {

By putting the expected value to offset 0x4000 fsck.vfat did recognise the first one as valid
and fsck.fat could proceed.
# echo -n -e "\xf8\xff\xff\x0f" | dd of=/dev/sdX1 bs=1 seek=16384 count=4

So I think there are probably two points for improvement:

  • Somehow check this first_ok even when the two copies are equal.
  • Probably try to identify by some other mark (and repair if identified successfully).

I cannot say how these 8 bytes got all zeros. Tried to test with a sparse file and fdisk/mkfs.vfat
but the bytes in question were set. But got not the values followed by these character tables.
Probably caused by some utility running on the smart tv where this disk was attached on.

Following is a hexdump of the partition begin and begin of the second copy:

# hexdump -C /dev/sdb1 -n 100000000 | less
00000000  eb 58 90 6d 6b 66 73 2e  66 61 74 00 02 40 20 00  |.X.mkfs.fat..@ .|
00000010  02 00 00 00 00 f8 00 00  3f 00 ff 00 00 08 00 00  |........?.......|
00000020  00 58 38 3a a6 d1 01 00  00 00 00 00 02 00 00 00  |.X8:............|
00000030  01 00 06 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  80 00 29 cf 04 26 a6 46  65 73 74 70 6c 61 74 74  |..)..&.Festplatt|
00000050  65 20 46 41 54 33 32 20  20 20 0e 1f be 77 7c ac  |e FAT32   ...w|.|
00000060  22 c0 74 0b 56 b4 0e bb  07 00 cd 10 5e eb f0 32  |".t.V.......^..2|
00000070  e4 cd 16 cd 19 eb fe 54  68 69 73 20 69 73 20 6e  |.......This is n|
00000080  6f 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 64 69  |ot a bootable di|
00000090  73 6b 2e 20 20 50 6c 65  61 73 65 20 69 6e 73 65  |sk.  Please inse|
000000a0  72 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 66 6c  |rt a bootable fl|
000000b0  6f 70 70 79 20 61 6e 64  0d 0a 70 72 65 73 73 20  |oppy and..press |
000000c0  61 6e 79 20 6b 65 79 20  74 6f 20 74 72 79 20 61  |any key to try a|
000000d0  67 61 69 6e 20 2e 2e 2e  20 0d 0a 00 00 00 00 00  |gain ... .......|
000000e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200  52 52 61 41 00 00 00 00  00 00 00 00 00 00 00 00  |RRaA............|
00000210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000003e0  00 00 00 00 72 72 41 61  e3 6f d3 00 85 62 15 00  |....rrAa.o...b..|
000003f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000400  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000c00  eb 58 90 6d 6b 66 73 2e  66 61 74 00 02 40 20 00  |.X.mkfs.fat..@ .|
00000c10  02 00 00 00 00 f8 00 00  3f 00 ff 00 00 08 00 00  |........?.......|
00000c20  00 58 38 3a a6 d1 01 00  00 00 00 00 02 00 00 00  |.X8:............|
00000c30  01 00 06 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000c40  80 00 29 cf 04 26 a6 46  65 73 74 70 6c 61 74 74  |..)..&.Festplatt|
00000c50  65 20 46 41 54 33 32 20  20 20 0e 1f be 77 7c ac  |e FAT32   ...w|.|
00000c60  22 c0 74 0b 56 b4 0e bb  07 00 cd 10 5e eb f0 32  |".t.V.......^..2|
00000c70  e4 cd 16 cd 19 eb fe 54  68 69 73 20 69 73 20 6e  |.......This is n|
00000c80  6f 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 64 69  |ot a bootable di|
00000c90  73 6b 2e 20 20 50 6c 65  61 73 65 20 69 6e 73 65  |sk.  Please inse|
00000ca0  72 74 20 61 20 62 6f 6f  74 61 62 6c 65 20 66 6c  |rt a bootable fl|
00000cb0  6f 70 70 79 20 61 6e 64  0d 0a 70 72 65 73 73 20  |oppy and..press |
00000cc0  61 6e 79 20 6b 65 79 20  74 6f 20 74 72 79 20 61  |any key to try a|
00000cd0  67 61 69 6e 20 2e 2e 2e  20 0d 0a 00 00 00 00 00  |gain ... .......|
00000ce0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000df0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000e00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00004000  00 00 00 00 ff ff ff 0f  f8 ff ff 0f 04 00 00 00  |................| --> changed to get it working to 00004000  f8 ff ff 0f ff ff ff 0f  f8 ff ff 0f 04 00 00 00  |................|
00004010  05 00 00 00 06 00 00 00  07 00 00 00 08 00 00 00  |................|
00004020  09 00 00 00 0a 00 00 00  0b 00 00 00 0c 00 00 00  |................|
00004030  0d 00 00 00 0e 00 00 00  0f 00 00 00 10 00 00 00  |................|
00004040  11 00 00 00 12 00 00 00  13 00 00 00 14 00 00 00  |................|
00004050  15 00 00 00 16 00 00 00  17 00 00 00 18 00 00 00  |................|
00004060  19 00 00 00 1a 00 00 00  1b 00 00 00 1c 00 00 00  |................|
00004070  1d 00 00 00 1e 00 00 00  1f 00 00 00 20 00 00 00  |............ ...|
00004080  21 00 00 00 22 00 00 00  23 00 00 00 24 00 00 00  |!..."...#...$...|
00004090  25 00 00 00 26 00 00 00  27 00 00 00 28 00 00 00  |%...&...'...(...|
000040a0  29 00 00 00 2a 00 00 00  2b 00 00 00 2c 00 00 00  |)...*...+...,...|
000040b0  2d 00 00 00 2e 00 00 00  2f 00 00 00 30 00 00 00  |-......./...0...|
000040c0  31 00 00 00 32 00 00 00  33 00 00 00 34 00 00 00  |1...2...3...4...|
000040d0  35 00 00 00 36 00 00 00  37 00 00 00 38 00 00 00  |5...6...7...8...|
000040e0  39 00 00 00 3a 00 00 00  3b 00 00 00 3c 00 00 00  |9...:...;...<...|
000040f0  3d 00 00 00 3e 00 00 00  3f 00 00 00 40 00 00 00  |=...>...?...@...|
00004100  41 00 00 00 42 00 00 00  43 00 00 00 44 00 00 00  |A...B...C...D...|
00004110  45 00 00 00 46 00 00 00  47 00 00 00 48 00 00 00  |E...F...G...H...|
00004120  49 00 00 00 4a 00 00 00  4b 00 00 00 4c 00 00 00  |I...J...K...L...|
00004130  4d 00 00 00 4e 00 00 00  4f 00 00 00 50 00 00 00  |M...N...O...P...|
00004140  51 00 00 00 52 00 00 00  53 00 00 00 54 00 00 00  |Q...R...S...T...|
00004150  55 00 00 00 56 00 00 00  57 00 00 00 58 00 00 00  |U...V...W...X...|
00004160  59 00 00 00 5a 00 00 00  5b 00 00 00 5c 00 00 00  |Y...Z...[...\...|
00004170  5d 00 00 00 5e 00 00 00  5f 00 00 00 60 00 00 00  |]...^..._...`...|

# dd if=/dev/sdb1 bs=1 skip=61049856 count=100 | hexdump -C
00000000  00 00 00 00 ff ff ff 0f  f8 ff ff 0f 04 00 00 00  |................|
00000010  05 00 00 00 06 00 00 00  07 00 00 00 08 00 00 00  |................|
00000020  09 00 00 00 0a 00 00 00  0b 00 00 00 0c 00 00 00  |................|
00000030  0d 00 00 00 0e 00 00 00  0f 00 00 00 10 00 00 00  |................|
00000040  11 00 00 00 12 00 00 00  13 00 00 00 14 00 00 00  |................|
00000050  15 00 00 00 16 00 00 00  17 00 00 00 18 00 00 00  |................|
00000060  19 00 00 00                                       |....|

03a38c00  00 00 00 00 ff ff ff 0f  f8 ff ff 0f 04 00 00 00  |................|
# ./fsck.fat -n -v /dev/sdb1 
fsck.fat 3.99.0 (2015-05-16)
Checking we can access the last sector of the filesystem
Boot sector contents:
System ID "mkfs.fat"
Media byte 0xf8 (hard disk)
       512 bytes per logical sector
     32768 bytes per cluster
        32 reserved sectors
First FAT starts at byte 16384 (sector 32)
         2 FATs, 32 bit entries
  61033472 bytes per FAT (= 119206 sectors)
Root directory start at cluster 2 (arbitrary size)
Data area starts at byte 122083328 (sector 238444)
  15258322 data clusters (499984695296 bytes)
63 sectors/track, 255 heads
      2048 hidden sectors
 976771072 sectors total
Both FATs appear to be corrupt. Giving up.

mkfs.vfat does not erase btrfs magic

The problem can be reproduced with:

dd if=/dev/zero of=disk.img bs=1024 count=18000
losetup /dev/loop0 disk.img
mkfs.btrfs /dev/loop0
mkfs.vfat /dev/loop0

Now mounting the device fails since there are both magic values from btrfs and vfat:

wipefs /dev/loop0 
offset               type
----------------------------------------------------------------
0x10040              btrfs   [filesystem]
                     UUID:  a4236e6f-4a2e-4f69-9599-da99de4f7e66

0x36                 vfat   [filesystem]
                     UUID:  6975-6A29

This can be either fixed by running wipefs -a /path/to/device or by calling corresponding functions from libblkid from util-linux (hint: the mkswap does this in wipe_device() function that iterates over probed magic values and erases them issuing warnings in the process).

memory leaks in fsck.fat

Not sure if it's your goal to eliminate all memory leaks, but I noted them while fuzzing fsck.fat.

When running fsck against a fresh, correct fat12 partition with valgrind I get this (current git code):

==12712== 12 bytes in 1 blocks are definitely lost in loss record 1 of 6
==12712==    at 0x4C2C070: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12712==    by 0x4026E6: read_boot (boot.c:429)
==12712==    by 0x40AF1E: main (fsck.fat.c:181)
==12712== 
==12712== 15 bytes in 1 blocks are definitely lost in loss record 2 of 6
==12712==    at 0x4C29F80: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12712==    by 0x406ABC: alloc (common.c:66)
==12712==    by 0x406E70: read_fat (fat.c:107)
==12712==    by 0x40AF57: main (fsck.fat.c:187)
==12712== 
==12712== 80 bytes in 1 blocks are definitely lost in loss record 3 of 6
==12712==    at 0x4C29F80: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12712==    by 0x406ABC: alloc (common.c:66)
==12712==    by 0x407145: read_fat (fat.c:154)
==12712==    by 0x40AF57: main (fsck.fat.c:187)
==12712== 

dosfsck (3.0.28) failes to repair (remove dirty bit) FAT32 on the JetFlash Transcend flash drive

First time I've seen this issue on sys-fs/dosfstools-3.0.26.

dmesg | tail about connected device:

[33689.104140] scsi 15:0:0:0: Direct-Access JetFlash Transcend 8GB 1100 PQ: 0 ANSI: 4
[33689.104418] sd 15:0:0:0: Attached scsi generic sg7 type 0
[33689.105062] sd 15:0:0:0: [sdg] 15826944 512-byte logical blocks: (8.10 GB/7.54 GiB)
[33689.105804] sd 15:0:0:0: [sdg] Write Protect is off
[33689.105807] sd 15:0:0:0: [sdg] Mode Sense: 43 00 00 00
[33689.106632] sd 15:0:0:0: [sdg] No Caching mode page found
[33689.106638] sd 15:0:0:0: [sdg] Assuming drive cache: write through
[33689.110587] sdg: sdg1
[33689.113712] sd 15:0:0:0: [sdg] Attached SCSI removable disk

Try to execute auto-repair (manual shows the same result):

dosfsck -a /dev/sdg1

fsck.fat 3.0.28 (2015-05-16)
0x41: Dirty bit is set. Fs was not properly unmounted and some data may be corrupt.
Automatically removing dirty bit.
Filesystem has 1973762 clusters but only space for 1973758 FAT entries.

Re-run chech to verify filesystem is OK, but see the same error.

dosfsck -a /dev/sdg1

fsck.fat 3.0.28 (2015-05-16)
0x41: Dirty bit is set. Fs was not properly unmounted and some data may be corrupt.
Automatically removing dirty bit.
Filesystem has 1973762 clusters but only space for 1973758 FAT entries.

Some devices never update second FAT, could fsck.vfat ignore second FAT?

Some devices(car cameras, old cellphones) never update second FAT,
It would be somewhat nice if an arg could be passed to fsck.vfat to ignore second FAT read/write.

Here are both FATs in a SD card of a car camera(viz car(R) camera) after format(fat32) and after recording a file:

00006400  f8 ff ff ff ff ff ff 0f  ff ff ff 0f ff ff ff 0f  |................|
00006410  05 00 00 00 06 00 00 00  07 00 00 00 08 00 00 00  |................|
00006420  09 00 00 00 0a 00 00 00  0b 00 00 00 0c 00 00 00  |................|
00006430  0d 00 00 00 0e 00 00 00  0f 00 00 00 10 00 00 00  |................|
00006440  11 00 00 00 12 00 00 00  13 00 00 00 14 00 00 00  |................|
00006450  15 00 00 00 16 00 00 00  17 00 00 00 18 00 00 00  |................|
...lots more non-zero gibberish...
00006a20  8a 01 00 00 ff ff ff 0f  89 01 00 00 00 00 00 00  |................|
00006a30  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
003a5200  f8 ff ff ff ff ff ff 0f  ff ff ff 0f 00 00 00 00  |................|
003a5210  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00744000  44 43 49 4d 20 20 20 20                           |DCIM    |
00744008

Second FAT(from 003a5200) will never be updated, unless by fsck.vfat of course.

I made a lil thing to detect that, for me, but it would be best if fsck.vfat would not write 2nd FAT at all, in this case.

diff -upr '--exclude=*.Po' dosfstools-4.1/src/fat.c dosfstools-4.1.mod/src/fat.c
--- dosfstools-4.1/src/fat.c	2017-01-22 04:50:09.000000000 +0100
+++ dosfstools-4.1.mod/src/fat.c	2017-05-05 15:30:48.175450189 +0200
@@ -121,6 +121,26 @@ void read_fat(DOS_FS * fs)
 	get_fat(&second_media, second, 0, fs);
 	first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
 	second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
+
+  if (second_ok) {
+    uint8_t *end=second+eff_size;//using <, so no -1
+    //int count=0;
+    uint8_t *cur=second+12;
+    if (end >= cur) {
+      //first 12 chars are these: f8 ff ff 0f ff ff ff 0f  ff ff ff 0f
+      //rest are zeroes if this 2nd FAT (FAT32) is unused/empty in some devices like: VIZ CAR CAMERA - they never update 2nd FAT so it remains as it was when last restored by fsck.vfat
+      for (; cur < end && 0 == *cur; cur++);//{count++;}
+      //printf("count=%d eff_size=%d cur==end?%d\n",count, eff_size, cur == end);
+      if (cur > end) {
+        printf("THIS IS NOT SUPPOSED TO HAPPEN cur=%p > end=%p\n", cur, end);
+      }
+      second_ok = (cur < end);
+      if (!second_ok) {
+        printf("Second FAT is empty/unused - ignoring it.\n");
+      }
+    }
+  }
+
 	if (first_ok && !second_ok) {
 	    printf("FATs differ - using first FAT.\n");
 	    fs_write(fs->fat_start + fs->fat_size, eff_size, first);

make issue

device_info.c:280: undefined reference to `blkid_probe_is_wholedisk'

typo

"such filesystem will not propably mount"

Usage of "Dirty Bit" does not meet FAT specification

It seems that fsck is using byte "0x41" (FAT32) or "0x25" (FAT16) as as the containing byte of this bit.

However, the FAT specification indicates that the first two clusters of a FAT are reserved for information which includes this dirty bit (notably, not within the boot sector). It also mentions that byte 0x41/0x25 is "BS_Reserved1", which "is "Reserved (used by Windows NT). Code that formats FAT volumes should always set this byte to 0."

Apparently, fsck's behavior isn't wrong -- there are other (informal) third party sources that confirm the usage of byte 0x41 / 0x25 as dirty bits. However, I can't find any formal documentation for this "out of spec" dirty bit -- or any reasoning why the documented dirty bit is going unused.

Additionally, there doesn't seem to be any attempt by fsck to set the formally specified "ClnShutBitMask" to "clean" after a verification pass.

fsck.fat: "Bad short file name ()." for root directory on FAT32

Steps to reproduce:

$ truncate -s 1073741824 disk.fat
$ mkfs.fat disk.fat
$ ./fsck.fat disk.fat

Expected behavior:

fsck.fat 3.0.28 (2015-05-16)
disk.fat: 0 files, 1/261629 clusters

Actual behavior:

fsck.fat 4.1+git (2017-01-24)
/
  Bad short file name ().
1) Drop file
2) Rename file
3) Auto-rename
4) Keep it
[1234?q]? 4
disk.fat: 0 files, 1/261629 clusters

Patch for bootcode

Sam Bingner in 2003 wrote patch for mkdosfs which adds support for writing custom boot code to FAT boot sector: https://lists.debian.org/debian-devel/2003/06/msg01316.html

This patch was included into Debian version 2.11-5 of mkdosfs, but reverted in 2.11-6 as it cause problems for syslinux. Daniel Baumann wrote that proper fix would be later. See bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=489292

Apparently Sam Bingner's patch was never fixed and never entered into upstream dosfstools.

It would be nice to have boot code support in mkfs.fat. I suspect that problem reported in above bug is because bs.hidden needs to be set to bs.secs_track only if using external boot code.

heap out of bounds read in get_fat()

An invalid memory read (heap oob) can happen with a malformed filesystem in the function get_fat().

This was found with american fuzzy lop and address sanitizer.

ASAN stack trace:

==17221==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x61400000fdc8 at pc 0x0000004f5289 bp 0x7fff4589e890 sp 0x7fff4589e888
READ of size 4 at 0x61400000fdc8 thread T0
    #0 0x4f5288 in get_fat /mnt/ram/dosfstools/src/fat.c:68:19
    #1 0x4f5288 in read_fat /mnt/ram/dosfstools/src/fat.c:165
    #2 0x4e018c in main /mnt/ram/dosfstools/src/fsck.fat.c:187:12
    #3 0x7f140fa897af in __libc_start_main (/lib64/libc.so.6+0x207af)
    #4 0x4181e8 in _start (/mnt/ram/dosfstools/fsck.fat+0x4181e8)

0x61400000fdc8 is located 0 bytes to the right of 392-byte region [0x61400000fc40,0x61400000fdc8)
allocated by thread T0 here:
    #0 0x4b3888 in __interceptor_malloc (/mnt/ram/dosfstools/fsck.fat+0x4b3888)
    #1 0x4f332c in alloc /mnt/ram/dosfstools/src/common.c:66:17

SUMMARY: AddressSanitizer: heap-buffer-overflow /mnt/ram/dosfstools/src/fat.c:68:19 in get_fat
Shadow bytes around the buggy address:
  0x0c287fff9f60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c287fff9f70: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
  0x0c287fff9f80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c287fff9f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff9fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff9fb0: 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa fa
  0x0c287fff9fc0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c287fff9fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff9fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff9ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa
  0x0c287fffa000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb

dosfstools-get_fat-oob-heap-read.zip

mkfs.fat manpage: Misleading description of the -h option

The current description for the -h option may be interpreted as if the hidden sectors are wasted space on the filesystem, when in fact the value set by the -h option is just the partition offset...
I don't even know why they called this value "hidden sectors" in the first place, but I think the man page should clarify that it is actually the partition offset and that it will be handled automatically by mkfs.fat

mkfs.fat: automatic FAT32 selection

Currently there is a comment in mkfs.fat.c stating: FAT32 is (not yet) choosen automatically.

From https://msdn.microsoft.com/en-us/windows/hardware/gg463080.aspx :

FAT type—one of FAT12, FAT16, or FAT32—is determined by the count of clusters on the volume and nothing else.

And:

This is the one and only way that FAT type is determined. There is no such thing as a FAT12 volume that has more than 4084 clusters. There is no such thing as a FAT16 volume that has less than 4085 clusters or more than 65,524 clusters. There is no such thing as a FAT32 volume that has less than 65,525 clusters. If you try to make a FAT volume that violates this rule, Microsoft operating systems will not handle them correctly because they will think the volume has a different type of FAT than what you think it does.

Pretentious general tone of the text apart (e.g. the world is full of FAT code that is wrong), I believe mkfs.fat has a dangerous default, as the user must manually calculate whether -F 32 is required.
So, this is a request to automatically select FAT32 when size_fat_by_user==0 and the partition has the minimum size required.

In case this isn't reasonable because it breaks backwards compatibility, I suggest as an alternative creating something like --auto-size to calculate the size according to the spec. OTOH this would complicate the code...

mkfs.fat ignores user-set reserved sectors count that is less than cluster size

While I was experimenting with partition data alignment in digital camera's SD card, I ran into an issue when I invoked mkfs.fat with:

  • Manually-specified cluster size (-s), and...
  • Manually-specified reserved sector count (-R) that is less than the size of cluster.

I found that in this condition, mkfs.fat ignored my reserved sector count specification, and used the same value as cluster size.

In my understanding, the varying reserved-area size is done for improving physical alignment; but this behavior has to be documented (see note about manual page at the end of this post). And when user explicitly specify it, user's value should take precedence; or else -R option would became useless for dealing with any nontrivial alignment issues (e.g. Win9x's FDISK-partitioned hard disk with 4 KiB sector).

Exact steps to reproduce:

  • Make an empty image file with the size of 15941632 sectors: dd if=/dev/zero of=test.img bs=512 count=15941632

  • Run mkfs.fat on the image file in verbose mode, with cluster size of 64 sectors, and reserved area size of 32 sectors: mkfs.fat -v -s 64 -R 32 test.img

  • You would see that mkfs.fat gave following output:

      mkfs.fat 4.1 (2017-01-24)
      Auto-selecting FAT32 for large filesystem
      test.img has 255 heads and 63 sectors per track,
      hidden sectors 0x0000;
      logical sector size is 512,
      using 0xf8 media descriptor, with 15941632 sectors;
      drive number 0x80;
      filesystem has 2 32-bit FATs and 64 sectors per cluster.
      FAT size is 1984 sectors, and provides 249025 clusters.
      There are 64 reserved sectors.
      Volume ID is 393de7df, no volume label.
    

    From the output, you would see that mkfs.fat used 64-sector reserved area, despite being explicitly instructed to use 32 sectors via -R option.

  • If one inspected the image with GNU mtools' minfo, they would see following report:

      device information:
      ===================
      filename="/tmp/test.img"
      sectors per track: 63
      heads: 255
      cylinders: 993
      
      mformat command line: mformat -T 15941632 -h 255 -s 63 -H 0 c:
      
      bootsector information
      ======================
      banner:"mkfs.fat"
      sector size: 512 bytes
      cluster size: 64 sectors
      reserved (boot) sectors: 64
      fats: 2
      max available root directory slots: 0
      small size: 0 sectors
      media descriptor byte: 0xf8
      sectors per fat: 0
      sectors per track: 63
      heads: 255
      hidden sectors: 0
      big size: 15941632 sectors
      physical drive id: 0x80
      reserved=0x0
      dos4=0x29
      serial number: 393DE7DF
      disk label="NO NAME    "
      disk type="FAT32   "
      Big fatlen=1984
      Extended flags=0x0000
      FS version=0x0000
      rootCluster=2
      infoSector location=1
      backup boot sector=6
      
      Infosector:
      signature=0x41615252
      free clusters=249024
      last allocated cluster=2
    

    The report confirms that reserved area is 64 sectors-long, instead of the desired 32-sector.

Notes:

  • This problem also apply to situations when cluster size is automatically determined.
  • This problem also affects older releases, like dosfstools 3.0.13.
  • This varying reserved-area size behavior disagrees with manual page: which said it defaulted to 32 without any mention of its dependency on cluster size.
  • Unrelated: mkfs.vfat doesn't seem to allow reserved sectors count that is not a multiple of cluster size. (Specifying one will result in a rounding up to the next larger multiple).

dosfstools: 4.1 (source)
mtools: 4.0.17-1 (debian)
System: Debian GNU/Linux 7.0 Wheezy i386

minimum number of clusters for FAT32

mkfs.fat.c:

#define MIN_CLUST_32    65529

according to Microsoft Extensible Firmware Initiative FAT32 File System Specification

If(CountofClusters < 4085) {
   /* Volume is FAT12 */
} else if(CountofClusters < 65525) {
   /* Volume is FAT16 */
} else {
   /* Volume is FAT32 */
}

maybe we should change MIN_CLUST_32 to 65525 ?

mkdosfs -F 32 accepts a "-r" static Root Directory size parameter but ignores it

$ dd if=/dev/zero of=disk.img count=1024 bs=100000
1024+0 records in
1024+0 records out
102400000 bytes (102 MB, 98 MiB) copied, 0.0900041 s, 1.1 GB/s

$ mkdosfs -F 32 -r 1024 disk.img 
mkfs.fat 4.0 (2016-05-06)

$ dosfsck -vn disk.img 
fsck.fat 4.0 (2016-05-06)
(...)
Root directory start at cluster 2 (arbitrary size)
(...)

I think mkdosfs must warn or fail with a "FAT32 doesn't support an statically allocated Root Directory" message, instead of simply ignoring the "-r 1024" switch and giving the user the impression the static Root Directory was allocated.

fatlabel does not handle empty label correctly

FAT label is stored to two locations:

  1. boot sector
  2. root FAT directory

Empty label for 1) needs to be stored as "NO NAME " and for 2) either not stored or as "\xE5" (deleted flag).

fatlabel does not handle this correctly and stores empty label as " " which is incorrect.

fsck.vfat invalid memory access in get_fat

This file will generate some invalid memory read in fsck.vfat:
https://crashes.fuzzing-project.org/dosfstools-get_fat-invalid-read

Judging from the output of address sanitizer and valgrind it is a bit unusual, it seems to be neither memory on the stack or heap, but it also doesn't crash the app if run without asan or valgrind. Happens both with the latest release and latest git code.

Found with american fuzzy lop.

This is the address sanitizer stack trace:

==17848==ERROR: AddressSanitizer: SEGV on unknown address 0x6020000105d8 (pc 0x0000004f1ace bp 0x7ffcae3ad230 sp 0x7ffcae3ad080 T0)
    #0 0x4f1acd in get_fat /f/dosfstools-3.0.26/src/fat.c:53:26
    #1 0x4ea4e6 in check_file /f/dosfstools-3.0.26/src/check.c:569:2
    #2 0x4ea4e6 in check_files /f/dosfstools-3.0.26/src/check.c:683
    #3 0x4ede42 in scan_dir /f/dosfstools-3.0.26/src/check.c:1029:9
    #4 0x4ede42 in subdirs /f/dosfstools-3.0.26/src/check.c:1053
    #5 0x4e4f90 in scan_root /f/dosfstools-3.0.26/src/check.c:1085:12
    #6 0x4ddaf4 in main /f/dosfstools-3.0.26/src/fsck.fat.c:188:27
    #7 0x7efe5b4eef9f in __libc_start_main /var/tmp/portage/sys-libs/glibc-2.20-r2/work/glibc-2.20/csu/libc-start.c:289
    #8 0x437106 in _start (/mnt/ram/dosfstools/fsck.fat+0x437106)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /f/dosfstools-3.0.26/src/fat.c:53 get_fat

Error when Compiling configure.ac with autoconf

autoconf
Gives me an m4_allocate_allow warning but builds the configure script.

root:/sources/dosfstools# ./configure --prefix=/usr
./configure: line 2090: syntax error near unexpected token `1.11'

./configure: line 2090: `AM_INIT_AUTOMAKE(1.11 foreign subdir-objects parallel-tests)'

This is on a partially built LFS system, however I also tried it on the ubuntu host and received the same configure.ac warnings and configure error.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.