Some vendor firmwares use a different super block magic to indicate LZMA
compression. This patches adds support for detecting this and enable
extraction for those firmware's root filesystems.
Signed-off-by: Jonas Gorski <jonas.gorski+open...@gmail.com>
---
I chose to only add this to unsquashfs to make inspecting vendor
firmwares easier, so creating them isn't support (but would be easy to
implement)


 tools/squashfs4/patches/160-lzma_magic.patch |   87 ++++++++++++++++++++++++++
 1 files changed, 87 insertions(+), 0 deletions(-)
 create mode 100644 tools/squashfs4/patches/160-lzma_magic.patch

diff --git a/tools/squashfs4/patches/160-lzma_magic.patch 
b/tools/squashfs4/patches/160-lzma_magic.patch
new file mode 100644
index 0000000..40fad9e
--- /dev/null
+++ b/tools/squashfs4/patches/160-lzma_magic.patch
@@ -0,0 +1,87 @@
+--- a/squashfs-tools/squashfs_fs.h
++++ b/squashfs-tools/squashfs_fs.h
+@@ -30,6 +30,13 @@
+ #define SQUASHFS_MAGIC_SWAP           0x68737173
+ #define SQUASHFS_START                        0
+ 
++/*
++ * Squashfs + LZMA
++ */
++
++#define SQUASHFS_MAGIC_LZMA           0x71736873
++#define SQUASHFS_MAGIC_LZMA_SWAP      0x73687371
++
+ /* size of metadata (inode and directory) blocks */
+ #define SQUASHFS_METADATA_SIZE                8192
+ #define SQUASHFS_METADATA_LOG         13
+--- a/squashfs-tools/unsquashfs.c
++++ b/squashfs-tools/unsquashfs.c
+@@ -1437,11 +1437,13 @@ int read_super(char *source)
+        */
+       read_bytes(SQUASHFS_START, sizeof(squashfs_super_block),
+               (char *) &sBlk_4);
+-      swap = sBlk_4.s_magic != SQUASHFS_MAGIC;
++      swap = (sBlk_4.s_magic != SQUASHFS_MAGIC && 
++              sBlk_4.s_magic != SQUASHFS_MAGIC_LZMA);
+       SQUASHFS_INSWAP_SUPER_BLOCK(&sBlk_4);
+ 
+-      if(sBlk_4.s_magic == SQUASHFS_MAGIC && sBlk_4.s_major == 4 &&
+-                      sBlk_4.s_minor == 0) {
++      if((sBlk_4.s_magic == SQUASHFS_MAGIC || 
++                      sBlk_4.s_magic == SQUASHFS_MAGIC_LZMA) && 
++                      sBlk_4.s_major == 4 && sBlk_4.s_minor == 0) {
+               s_ops.squashfs_opendir = squashfs_opendir_4;
+               s_ops.read_fragment = read_fragment_4;
+               s_ops.read_fragment_table = read_fragment_table_4;
+@@ -1453,7 +1455,11 @@ int read_super(char *source)
+               /*
+                * Check the compression type
+                */
+-              comp = lookup_compressor_id(sBlk.compression);
++              if (sBlk_4.s_magic == SQUASHFS_MAGIC_LZMA)
++                      comp = lookup_compressor("lzma");
++              else
++                      comp = lookup_compressor_id(sBlk.compression);
++
+               if(!comp->supported) {
+                       ERROR("Filesystem uses %s compression, this is "
+                               "unsupported by this version\n", comp->name);
+@@ -1475,8 +1481,10 @@ int read_super(char *source)
+        * Check it is a SQUASHFS superblock
+        */
+       swap = 0;
+-      if(sBlk_3.s_magic != SQUASHFS_MAGIC) {
+-              if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP) {
++      if(sBlk_3.s_magic != SQUASHFS_MAGIC && 
++                      sBlk_3.s_magic != SQUASHFS_MAGIC_LZMA) {
++              if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP || 
++                              sBlk_3.s_magic == SQUASHFS_MAGIC_LZMA_SWAP) {
+                       squashfs_super_block_3 sblk;
+                       ERROR("Reading a different endian SQUASHFS filesystem "
+                               "on %s\n", source);
+@@ -1550,11 +1558,20 @@ int read_super(char *source)
+               goto failed_mount;
+       }
+ 
+-      /*
+-       * 1.x, 2.x and 3.x filesystems use gzip compression.  Gzip is always
+-       * suppported.
+-       */
+-      comp = lookup_compressor("gzip");
++      if (sBlk.s_magic == SQUASHFS_MAGIC_LZMA) {
++              /* Check for availability */
++              comp = lookup_compressor("lzma");
++              if(!comp->supported) {
++                      ERROR("Filesystem uses lzma compression, this is "
++                              "unsupported by this version\n");
++                      ERROR("Decompressors available:\n");
++                      display_compressors("", "");
++                      goto failed_mount;
++              }
++      } else {
++              /* Gzip is always supported */
++              comp = lookup_compressor("gzip");
++      }
+       return TRUE;
+ 
+ failed_mount:
-- 
1.5.6.5

_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to