bfs: fix sanity checks for empty files
authorRakesh Pandit <rakesh@tuxera.com>
Wed, 12 Jul 2017 21:34:07 +0000 (14:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Jul 2017 23:26:00 +0000 (16:26 -0700)
Mount fails if file system image has empty files because of sanity check
while reading superblock.  For empty files disk offset to end of file
(i_eoffset) is cpu_to_le32(-1).  Sanity check comparison, which compares
disk offset with file system size isn't valid for this value and hence
is ignored with this patch.

Steps to reproduce:

  $  dd if=/dev/zero of=bfs-image count=204800
  $  mkfs.bfs bfs-image
  $  mkdir bfs-mount-point
  $  sudo mount -t bfs -o loop bfs-image bfs-mount-point/
  $  cd bfs-mount-point/
  $  sudo touch a
  $  cd ..
  $  sudo umount bfs-mount-point/
  $  sudo mount -t bfs -o loop bfs-image bfs-mount-point/
  mount: /dev/loop0: can't read superblock

  $  dmesg
  [25526.689580] BFS-fs: bfs_fill_super(): Inode 0x00000003 corrupted

Tigran said:
 "If you had created the filesystem with the proper mkfs under SCO
  UnixWare 7 you (probably) wouldn't encounter this issue. But since
  commercial Unix-es are now part of history and the only proper way is
  the Linux mkfs.bfs utility, your patch is fine"

Link: http://lkml.kernel.org/r/20170505201625.GA3097@hercules.tuxera.com
Signed-off-by: Rakesh Pandit <rakesh@tuxera.com>
Acked-by: Tigran Aivazian <aivazian.tigran@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/bfs/inode.c

index 25e312cb60716caef70a66f12eb391f8aa234005..9a69392f1fb375c4c16b07332248edf7da57c9b6 100644 (file)
@@ -419,7 +419,7 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
                if (i_sblock > info->si_blocks ||
                        i_eblock > info->si_blocks ||
                        i_sblock > i_eblock ||
-                       i_eoff > s_size ||
+                       (i_eoff != le32_to_cpu(-1) && i_eoff > s_size) ||
                        i_sblock * BFS_BSIZE > i_eoff) {
 
                        printf("Inode 0x%08x corrupted\n", i);