Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0 2 : : /* 3 : : * decompress.c 4 : : * 5 : : * Detect the decompression method based on magic number 6 : : */ 7 : : 8 : : #include <linux/decompress/generic.h> 9 : : 10 : : #include <linux/decompress/bunzip2.h> 11 : : #include <linux/decompress/unlzma.h> 12 : : #include <linux/decompress/unxz.h> 13 : : #include <linux/decompress/inflate.h> 14 : : #include <linux/decompress/unlzo.h> 15 : : #include <linux/decompress/unlz4.h> 16 : : 17 : : #include <linux/types.h> 18 : : #include <linux/string.h> 19 : : #include <linux/init.h> 20 : : #include <linux/printk.h> 21 : : 22 : : #ifndef CONFIG_DECOMPRESS_GZIP 23 : : # define gunzip NULL 24 : : #endif 25 : : #ifndef CONFIG_DECOMPRESS_BZIP2 26 : : # define bunzip2 NULL 27 : : #endif 28 : : #ifndef CONFIG_DECOMPRESS_LZMA 29 : : # define unlzma NULL 30 : : #endif 31 : : #ifndef CONFIG_DECOMPRESS_XZ 32 : : # define unxz NULL 33 : : #endif 34 : : #ifndef CONFIG_DECOMPRESS_LZO 35 : : # define unlzo NULL 36 : : #endif 37 : : #ifndef CONFIG_DECOMPRESS_LZ4 38 : : # define unlz4 NULL 39 : : #endif 40 : : 41 : : struct compress_format { 42 : : unsigned char magic[2]; 43 : : const char *name; 44 : : decompress_fn decompressor; 45 : : }; 46 : : 47 : : static const struct compress_format compressed_formats[] __initconst = { 48 : : { {0x1f, 0x8b}, "gzip", gunzip }, 49 : : { {0x1f, 0x9e}, "gzip", gunzip }, 50 : : { {0x42, 0x5a}, "bzip2", bunzip2 }, 51 : : { {0x5d, 0x00}, "lzma", unlzma }, 52 : : { {0xfd, 0x37}, "xz", unxz }, 53 : : { {0x89, 0x4c}, "lzo", unlzo }, 54 : : { {0x02, 0x21}, "lz4", unlz4 }, 55 : : { {0, 0}, NULL, NULL } 56 : : }; 57 : : 58 : 0 : decompress_fn __init decompress_method(const unsigned char *inbuf, long len, 59 : : const char **name) 60 : : { 61 : : const struct compress_format *cf; 62 : : 63 : 0 : if (len < 2) { 64 : 0 : if (name) 65 : 0 : *name = NULL; 66 : : return NULL; /* Need at least this much... */ 67 : : } 68 : : 69 : : pr_debug("Compressed data magic: %#.2x %#.2x\n", inbuf[0], inbuf[1]); 70 : : 71 : 0 : for (cf = compressed_formats; cf->name; cf++) { 72 : 0 : if (!memcmp(inbuf, cf->magic, 2)) 73 : : break; 74 : : 75 : : } 76 : 0 : if (name) 77 : 0 : *name = cf->name; 78 : 0 : return cf->decompressor; 79 : : }