J Holsenback - 2011-07-22

I'm having some troubles extracting the files from a squashfs v1.0 filesystem using the latest (v4.2) unsquashfs. This filesystem was lifted from a router firmware image. The filesystem is somewhat of a black box to me, in that I'm not sure what compression was used when it was created, or what files are in the image. Given the version of the filesystem, an educated guess /might/ be that it used gzip compression, but I know that some earlier variants (branches or customizations) used lzma compression.

Here's what I've learned about the filesystem from information gained using v4.2 tools, and some information gained through direct examination (hexdump and a small c program that was cobbled together):

./unsquashfs -s ../../filesystem.bin
unsquashfs: read_bytes: reading from position 0x0, bytes 96
unsquashfs: read_bytes: reading from position 0x0, bytes 119
Found a valid little endian SQUASHFS 1:0 superblock on ../../filesystem.bin.
Creation or last append time Fri Oct 16 23:07:09 2009
Filesystem size 3299.28 Kbytes (3.22 Mbytes)
Block size 32768
Filesystem is not exportable via NFS
Inodes are compressed
Data is compressed
Check data is not present in the filesystem
Duplicates are removed
Number of inodes 1670
Number of uids 2
Number of gids 0 ?
unsquashfs: sBlk.s.inode_table_start 0x3343d3
unsquashfs: sBlk.s.directory_table_start 0x3365b2
unsquashfs: sBlk.uid_start 0x338d1b
unsquashfs: sBlk.guid_start 0x0

I have #define SQUASHFS_TRACE 1 set in squashfs_fs.c to give a little bit more information …

Notice that it properly identified that my filesystem image is version 1.0 compressed data and inode table … however when I try to extract the files from the image I get a fatal error:

./unsquashfs -ll ../../filesystem.bin
unsquashfs: read_bytes: reading from position 0x0, bytes 96
unsquashfs: read_bytes: reading from position 0x0, bytes 119
Parallel unsquashfs: Using 2 processors
unsquashfs: MY: read_uids_guids: no_uids 2, no_guids 0
unsquashfs: read_bytes: reading from position 0x338d1b, bytes 8
unsquashfs: read_fragment_table
unsquashfs: uncompress_inode_table: start 3359699, end 3368370
unsquashfs: uncompress_inode_table: reading block 0x3343d3
unsquashfs: read_bytes: reading from position 0x3343d3, bytes 2
unsquashfs: read_block: block @0x3343d3, 2261 compressed bytes
unsquashfs: read_bytes: reading from position 0x3343d5, bytes 2261
gzip uncompress failed with error code -3
read_block: failed to read block @0x3343d3
FATAL ERROR aborting: uncompress_inode_table: failed to read block

What this seems to be telling me is that gzip is having some difficulties reading the first block of data, but has successfully identified the start and end of the first block.

Something else I noticed (refer to first session transcript): from unsquashfs -s is that the Number of gids reported is "0" and later on … unsquashfs: sBlk.guid_start 0x0. This is also verified through direct examination of the super-block, where at offset 0x000026, it indeed is set to zero!

Could this be the bigger problem. I don't think I've heard of any unix/linux system that would allow a file or directory without having some sort of group affiliation, or could it be that the super-block information is corrupted somehow! At this point I'm thinking what compressor was used when the filesystem was created is the least of my worries.

Insights appreciated!