]> Git Repo - J-u-boot.git/blame - fs/squashfs/sqfs_decompressor.c
fs/squashfs: sqfs_search_dir: fix dangling pointer
[J-u-boot.git] / fs / squashfs / sqfs_decompressor.c
CommitLineData
c5100613
JMC
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2020 Bootlin
4 *
5 * Author: Joao Marcos Costa <[email protected]>
6 */
7
8#include <errno.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
6dfed163
JMC
12
13#if IS_ENABLED(CONFIG_LZO)
14#include <linux/lzo.h>
15#endif
16
3634b350
JMC
17#if IS_ENABLED(CONFIG_ZLIB)
18#include <u-boot/zlib.h>
19#endif
c5100613 20
9c948f53
JMC
21#if IS_ENABLED(CONFIG_ZSTD)
22#include <linux/zstd.h>
23#endif
24
c5100613 25#include "sqfs_decompressor.h"
c5100613
JMC
26#include "sqfs_utils.h"
27
10f7cf5f
JMC
28int sqfs_decompressor_init(struct squashfs_ctxt *ctxt)
29{
30 u16 comp_type = get_unaligned_le16(&ctxt->sblk->compression);
31
32 switch (comp_type) {
6dfed163
JMC
33#if IS_ENABLED(CONFIG_LZO)
34 case SQFS_COMP_LZO:
35 break;
36#endif
10f7cf5f
JMC
37#if IS_ENABLED(CONFIG_ZLIB)
38 case SQFS_COMP_ZLIB:
39 break;
9c948f53
JMC
40#endif
41#if IS_ENABLED(CONFIG_ZSTD)
42 case SQFS_COMP_ZSTD:
43 ctxt->zstd_workspace = malloc(ZSTD_DCtxWorkspaceBound());
44 if (!ctxt->zstd_workspace)
45 return -ENOMEM;
46 break;
10f7cf5f
JMC
47#endif
48 default:
49 printf("Error: unknown compression type.\n");
50 return -EINVAL;
51 }
52
53 return 0;
54}
55
56void sqfs_decompressor_cleanup(struct squashfs_ctxt *ctxt)
57{
58 u16 comp_type = get_unaligned_le16(&ctxt->sblk->compression);
59
60 switch (comp_type) {
6dfed163
JMC
61#if IS_ENABLED(CONFIG_LZO)
62 case SQFS_COMP_LZO:
63 break;
64#endif
10f7cf5f
JMC
65#if IS_ENABLED(CONFIG_ZLIB)
66 case SQFS_COMP_ZLIB:
67 break;
9c948f53
JMC
68#endif
69#if IS_ENABLED(CONFIG_ZSTD)
70 case SQFS_COMP_ZSTD:
71 free(ctxt->zstd_workspace);
72 break;
10f7cf5f
JMC
73#endif
74 }
75}
76
3634b350
JMC
77#if IS_ENABLED(CONFIG_ZLIB)
78static void zlib_decompression_status(int ret)
79{
80 switch (ret) {
81 case Z_BUF_ERROR:
82 printf("Error: 'dest' buffer is not large enough.\n");
83 break;
84 case Z_DATA_ERROR:
85 printf("Error: corrupted compressed data.\n");
86 break;
87 case Z_MEM_ERROR:
88 printf("Error: insufficient memory.\n");
89 break;
90 }
91}
92#endif
93
9c948f53
JMC
94#if IS_ENABLED(CONFIG_ZSTD)
95static int sqfs_zstd_decompress(struct squashfs_ctxt *ctxt, void *dest,
96 unsigned long dest_len, void *source, u32 src_len)
97{
98 ZSTD_DCtx *ctx;
99 size_t wsize;
100 int ret;
101
102 wsize = ZSTD_DCtxWorkspaceBound();
103 ctx = ZSTD_initDCtx(ctxt->zstd_workspace, wsize);
104 ret = ZSTD_decompressDCtx(ctx, dest, dest_len, source, src_len);
105
106 return ZSTD_isError(ret);
107}
108#endif /* CONFIG_ZSTD */
109
cdc11441
JMC
110int sqfs_decompress(struct squashfs_ctxt *ctxt, void *dest,
111 unsigned long *dest_len, void *source, u32 src_len)
c5100613 112{
cdc11441 113 u16 comp_type = get_unaligned_le16(&ctxt->sblk->compression);
c5100613
JMC
114 int ret = 0;
115
116 switch (comp_type) {
6dfed163
JMC
117#if IS_ENABLED(CONFIG_LZO)
118 case SQFS_COMP_LZO: {
119 size_t lzo_dest_len = *dest_len;
120 ret = lzo1x_decompress_safe(source, src_len, dest, &lzo_dest_len);
121 if (ret) {
122 printf("LZO decompression failed. Error code: %d\n", ret);
123 return -EINVAL;
124 }
125
126 break;
127 }
128#endif
3634b350
JMC
129#if IS_ENABLED(CONFIG_ZLIB)
130 case SQFS_COMP_ZLIB:
10f7cf5f 131 ret = uncompress(dest, dest_len, source, src_len);
3634b350
JMC
132 if (ret) {
133 zlib_decompression_status(ret);
134 return -EINVAL;
135 }
136
137 break;
138#endif
9c948f53
JMC
139#if IS_ENABLED(CONFIG_ZSTD)
140 case SQFS_COMP_ZSTD:
141 ret = sqfs_zstd_decompress(ctxt, dest, *dest_len, source, src_len);
142 if (ret) {
143 printf("ZSTD Error code: %d\n", ZSTD_getErrorCode(ret));
144 return -EINVAL;
145 }
146
147 break;
148#endif
c5100613
JMC
149 default:
150 printf("Error: unknown compression type.\n");
151 return -EINVAL;
152 }
153
154 return ret;
155}
This page took 0.048774 seconds and 4 git commands to generate.