Re: [Squashfs-devel] PROBLEM: mount empty SquashFS

From: Geert Uytterhoeven
Date: Tue Sep 04 2012 - 14:52:38 EST


Hi Phillip,

On Wed, Aug 1, 2012 at 6:25 AM, Phillip Lougher
<phillip@xxxxxxxxxxxxxxxxxxx> wrote:
> Cyril Strejc wrote:
>> I have problem when mounting empty SquashFS. Mount syscall ends with EINVAL.
>>
>> Kernel vesions: mainline
>> SquashFS tools version: 4.2
>>
>> Steps to reproduce:
>> 1. create empty directory (mkdir empty)
>> 2. create SquashFS image (my mksquashfs output below)
>> 3. mount image using block or loop device (strace output below)
>>
>> I've add some printk to
>> super.c: squashfs_fill_super()
>>
>> /* code starts here */
>> ...
>> handle_fragments:
>> fragments = le32_to_cpu(sblk->fragments);
>> printk("fragments = %u\n", fragments);
>> ...
>> check_directory_table:
>> /* Sanity check directory_table */
>> if (msblk->directory_table >= next_table) {
>> printk("directory_table = %llu, next_table = %llu\n",
>> msblk->directory_table, next_table);
>> err = -EINVAL;
>> printk("mount error: 16\n");
>> goto failed_mount;
>> }
>> ...
>>
>> dmesg after mount:
>> fragments = 0
>> directory_table = 125, next_table = 125
>> mount error: 16
>>
>>
>> I hardly understand these details. Please, do You have any idea?
>>
>
> Hi Cyril,
>
> This is a Squashfs kernel bug introduced by some extra superblock
> sanity checks added in kernel 3.0. These extra sanity checks were
> necessary to harden Squashfs against corrupted Squashfs filesystems
> generated by the latest version of fsfuzzer (a tool used to randomly
> corrupt filesystems with the aim of making the filesystem code
> behave badly).
>
> I discovered the sanity checks mistakenly flagged empty filesystems
> as invalid in January, and added a fix to the mainline kernel, FYI
> the commit is here:
>
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=cc37f75a9ffbbfcb1c3297534f293c8284e3c5a6
>
> This bug has been fixed in kernel versions 3.3 and newer, but, kernel
> versions 3.0, 3.1 and 3.2 unfortunately have this bug.
>
> There's really only three solutions to this problem:
>
> - upgrade to a later kernel, 3.3 or newer,
> - apply the above commit to your kernel, or
> - avoid generating empty filesystems and trying to mount them
>
> The one obvious question that arises here is why are you generating
> completely empty filesystems and then trying to mount them? An
> empty Squashfs filesystem doesn't seem to serve any useful purpose?

I can easily imagine a system that has an optional filesystem mounted,
which may be empty. For such a system, it's a regression.

So I think this warrants application to the stable 3.0, 3.1, and 3.2 branches.
Commit cc37f75a9ffbbfcb1c3297534f293c8284e3c5a6 ("Squashfs: fix
mount time sanity check for corrupted superblock") seems to cherry-pick just
fine on v3.0.42, v3.1.10, and v3.2.28.

>> mksquashfs command output:
>> --------------------------
>> localhost:~ # mksquashfs emptydir test.bin
>> Parallel mksquashfs: Using 1 processor
>> Creating 4.0 filesystem on test.bin, block size 131072.
>>
>> Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
>> compressed data, compressed metadata, compressed fragments, no
>> xattrs
>> duplicates are removed
>> Filesystem size 0.15 Kbytes (0.00 Mbytes)
>> 99.37% of uncompressed filesystem size (0.15 Kbytes)
>> Inode table size 29 bytes (0.03 Kbytes)
>> 85.29% of uncompressed inode table size (34 bytes)
>> Directory table size 0 bytes (0.00 Kbytes)
>> nan% of uncompressed directory table size (0 bytes)
>> Number of duplicate files found 0
>> Number of inodes 1
>> Number of files 0
>> Number of fragments 0
>> Number of symbolic links 0
>> Number of device nodes 0
>> Number of fifo nodes 0
>> Number of socket nodes 0
>> Number of directories 1
>> Number of ids (unique uids + gids) 1
>> Number of uids 1
>> root (0)
>> Number of gids 1
>> root (0)
>> --------------------------------------------------------------------
>>
>> mount command output (strace):
>> -----------------------------
>> mount("/dev/loop0", "/mnt", "squashfs", MS_MGC_VAL, NULL) = -1 EINVAL
>> (Invalid argument)
>>
>> anouther mount version (empty image on MTD device):
>> ---------------------------------------------------
>> mount("/dev/mtdblock4", "/mnt", "squashfs", MS_RDONLY|MS_SILENT, NULL) =
>> -1 EINVAL (Invalid argument)

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/