I was writing a long write-up on how I was troubleshooting the issue on the OOB but I found out something else was the problem. I downloaded the newest version available for squashfs-tools (
https://github.com/plougher/squashfs-tools), compiled it with the tracing function enabled and fiddled around with the two squashfs files I dumped: the one from the RouterOS firmware npk file and the one I extracted from the device using nanddump, after flashing it.
I checked if the information about the files could be read
# ./unsquashfs -s ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs
squashfs: read_bytes: reading from position 0x0, bytes 96
Found a valid SQUASHFS 4:0 superblock on ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs.
Creation or last append time Thu Jan 30 08:26:56 2025
Filesystem size 5743084 bytes (5608.48 Kbytes / 5.48 Mbytes)
Compression xz
Block size 262144
Filesystem is exportable via NFS
Inodes are compressed
Data is compressed
Uids/Gids (Id table) are compressed
Fragments are compressed
Tailends are not packed into fragments
Xattrs are not stored
Duplicates are removed
Number of fragments 51
Number of inodes 593
Number of ids 1
squashfs: sBlk.s.inode_table_start 0x57706c
squashfs: sBlk.s.directory_table_start 0x57848e
squashfs: sBlk.s.fragment_table_start 0x579dac
squashfs: sBlk.s.lookup_table_start 0x57a1d6
squashfs: sBlk.s.id_table_start 0x57a1e4
squashfs: sBlk.s.xattr_id_table_start 0xffffffffffffffff
# ./unsquashfs -s ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs
squashfs: read_bytes: reading from position 0x0, bytes 96
Found a valid SQUASHFS 4:0 superblock on ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs.
Creation or last append time Thu Jan 30 08:26:56 2025
Filesystem size 5743084 bytes (5608.48 Kbytes / 5.48 Mbytes)
Compression xz
Block size 262144
Filesystem is exportable via NFS
Inodes are compressed
Data is compressed
Uids/Gids (Id table) are compressed
Fragments are compressed
Tailends are not packed into fragments
Xattrs are not stored
Duplicates are removed
Number of fragments 51
Number of inodes 593
Number of ids 1
squashfs: sBlk.s.inode_table_start 0x57706c
squashfs: sBlk.s.directory_table_start 0x57848e
squashfs: sBlk.s.fragment_table_start 0x579dac
squashfs: sBlk.s.lookup_table_start 0x57a1d6
squashfs: sBlk.s.id_table_start 0x57a1e4
squashfs: sBlk.s.xattr_id_table_start 0xffffffffffffffff
The only difference was the filename
# diff <(./unsquashfs -s ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs) <(./unsquashfs -s ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs)
2c2
< Found a valid SQUASHFS 4:0 superblock on ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs.
---
> Found a valid SQUASHFS 4:0 superblock on ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs.
This is the initial output from the npk file listing:
# ./unsquashfs -l ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs | head
squashfs: read_bytes: reading from position 0x0, bytes 96
squashfs: read_id_table: no_ids 1
squashfs: read_bytes: reading from position 0x57a1e4, bytes 8
squashfs: read_bytes: reading from position 0x57a1de, bytes 2
squashfs: read_block: block @0x57a1de, 4 uncompressed bytes
squashfs: read_bytes: reading from position 0x57a1e0, bytes 4
squashfs: read_bytes: reading from position 0x57a1d6, bytes 8
squashfs: read_fragment_table: 51 fragments, reading 1 fragment indexes from 0x579dac
squashfs: read_bytes: reading from position 0x579dac, bytes 8
squashfs: read_bytes: reading from position 0x579c1a, bytes 2
[...]
This is the full output for the mtd5 dumped file:
# ./unsquashfs -l ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs
squashfs: read_bytes: reading from position 0x0, bytes 96
squashfs: read_id_table: no_ids 1
squashfs: read_bytes: reading from position 0x57a1e4, bytes 8
squashfs: read_bytes: reading from position 0xffffffffffffffff, bytes 2
Lseek failed because Invalid argument
read_block: failed to read block @0xffffffffffffffff
read_id_table: failed to read id table block
FATAL ERROR: File system corruption detected
I manually checked the superblock section (96 bytes) and found out that the value 0xffffffffffffffff is in the "Xattr table" field, which the documentation (
https://dr-emann.github.io/squashfs/squashfs.html) says
"The Xattr table, fragment table and export table are optional. If they are omitted from the archive, the respective fields indicating their position must be set to 0xFFFFFFFFFFFFFFFF (i.e. all bits set)."
Now let's compare both files' headers
# xxd -l 96 ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs
00000000: 6873 7173 5102 0000 0062 9b67 0000 0400 hsqsQ....b.g....
00000010: 3300 0000 0400 1200 c002 0100 0400 0000 3...............
00000020: 5c0b d810 0000 0000 eca1 5700 0000 0000 \.........W.....
00000030: e4a1 5700 0000 0000 ffff ffff ffff ffff ..W.............
00000040: 6c70 5700 0000 0000 8e84 5700 0000 0000 lpW.......W.....
00000050: ac9d 5700 0000 0000 d6a1 5700 0000 0000 ..W.......W.....
# diff <(xxd -l 96 ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs) <(xxd -l 96 ../../_routeros-7.17.1-smips.npk.extracted/1000.squashfs)
#
They are the same, right? When I try to unsquash the firmware's file, it runs without problems, but the absolutely same header, even with the -no-xattrs option, can't be read from the extracted file. I event checked the "flags" field and the bit for the option "Xattrs are stored uncompressed" was disabled and the bit for "There are no Xattrs in the archive was enabled"
# ./unsquashfs -l -no-xattrs ../../_mtd5.nanddump.bin.extracted/7534D0.squashfs
squashfs: read_bytes: reading from position 0x0, bytes 96
squashfs: read_id_table: no_ids 1
squashfs: read_bytes: reading from position 0x57a1e4, bytes 8
squashfs: read_bytes: reading from position 0xffffffffffffffff, bytes 2
Lseek failed because Invalid argument
read_block: failed to read block @0xffffffffffffffff
read_id_table: failed to read id table block
FATAL ERROR: File system corruption detected
Is this a unsquashfs command bug or what?