1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68#ifdef STATIC
69# define UNZSTD_PREBOOT
70# include "xxhash.c"
71# include "zstd/entropy_common.c"
72# include "zstd/fse_decompress.c"
73# include "zstd/huf_decompress.c"
74# include "zstd/zstd_common.c"
75# include "zstd/decompress.c"
76#endif
77
78#include <linux/decompress/mm.h>
79#include <linux/kernel.h>
80#include <linux/zstd.h>
81
82
83#define ZSTD_WINDOWSIZE_MAX (1 << ZSTD_WINDOWLOG_MAX)
84
85
86
87
88
89
90#define ZSTD_IOBUF_SIZE (1 << 17)
91
92static int INIT handle_zstd_error(size_t ret, void (*error)(char *x))
93{
94 const int err = ZSTD_getErrorCode(ret);
95
96 if (!ZSTD_isError(ret))
97 return 0;
98
99 switch (err) {
100 case ZSTD_error_memory_allocation:
101 error("ZSTD decompressor ran out of memory");
102 break;
103 case ZSTD_error_prefix_unknown:
104 error("Input is not in the ZSTD format (wrong magic bytes)");
105 break;
106 case ZSTD_error_dstSize_tooSmall:
107 case ZSTD_error_corruption_detected:
108 case ZSTD_error_checksum_wrong:
109 error("ZSTD-compressed data is corrupt");
110 break;
111 default:
112 error("ZSTD-compressed data is probably corrupt");
113 break;
114 }
115 return -1;
116}
117
118
119
120
121
122
123static int INIT decompress_single(const u8 *in_buf, long in_len, u8 *out_buf,
124 long out_len, long *in_pos,
125 void (*error)(char *x))
126{
127 const size_t wksp_size = ZSTD_DCtxWorkspaceBound();
128 void *wksp = large_malloc(wksp_size);
129 ZSTD_DCtx *dctx = ZSTD_initDCtx(wksp, wksp_size);
130 int err;
131 size_t ret;
132
133 if (dctx == NULL) {
134 error("Out of memory while allocating ZSTD_DCtx");
135 err = -1;
136 goto out;
137 }
138
139
140
141
142 ret = ZSTD_findFrameCompressedSize(in_buf, in_len);
143 err = handle_zstd_error(ret, error);
144 if (err)
145 goto out;
146 in_len = (long)ret;
147
148 ret = ZSTD_decompressDCtx(dctx, out_buf, out_len, in_buf, in_len);
149 err = handle_zstd_error(ret, error);
150 if (err)
151 goto out;
152
153 if (in_pos != NULL)
154 *in_pos = in_len;
155
156 err = 0;
157out:
158 if (wksp != NULL)
159 large_free(wksp);
160 return err;
161}
162
163static int INIT __unzstd(unsigned char *in_buf, long in_len,
164 long (*fill)(void*, unsigned long),
165 long (*flush)(void*, unsigned long),
166 unsigned char *out_buf, long out_len,
167 long *in_pos,
168 void (*error)(char *x))
169{
170 ZSTD_inBuffer in;
171 ZSTD_outBuffer out;
172 ZSTD_frameParams params;
173 void *in_allocated = NULL;
174 void *out_allocated = NULL;
175 void *wksp = NULL;
176 size_t wksp_size;
177 ZSTD_DStream *dstream;
178 int err;
179 size_t ret;
180
181
182
183
184
185
186 if (out_len == 0)
187 out_len = UINTPTR_MAX - (uintptr_t)out_buf;
188
189 if (fill == NULL && flush == NULL)
190
191
192
193
194 return decompress_single(in_buf, in_len, out_buf, out_len,
195 in_pos, error);
196
197
198
199
200
201
202 if (in_buf == NULL) {
203 in_allocated = large_malloc(ZSTD_IOBUF_SIZE);
204 if (in_allocated == NULL) {
205 error("Out of memory while allocating input buffer");
206 err = -1;
207 goto out;
208 }
209 in_buf = in_allocated;
210 in_len = 0;
211 }
212
213 if (fill != NULL)
214 in_len = fill(in_buf, ZSTD_IOBUF_SIZE);
215 if (in_len < 0) {
216 error("ZSTD-compressed data is truncated");
217 err = -1;
218 goto out;
219 }
220
221 in.src = in_buf;
222 in.pos = 0;
223 in.size = in_len;
224
225 if (flush != NULL) {
226 out_allocated = large_malloc(ZSTD_IOBUF_SIZE);
227 if (out_allocated == NULL) {
228 error("Out of memory while allocating output buffer");
229 err = -1;
230 goto out;
231 }
232 out_buf = out_allocated;
233 out_len = ZSTD_IOBUF_SIZE;
234 }
235
236 out.dst = out_buf;
237 out.pos = 0;
238 out.size = out_len;
239
240
241
242
243
244
245
246
247 ret = ZSTD_getFrameParams(¶ms, in.src, in.size);
248 err = handle_zstd_error(ret, error);
249 if (err)
250 goto out;
251 if (ret != 0) {
252 error("ZSTD-compressed data has an incomplete frame header");
253 err = -1;
254 goto out;
255 }
256 if (params.windowSize > ZSTD_WINDOWSIZE_MAX) {
257 error("ZSTD-compressed data has too large a window size");
258 err = -1;
259 goto out;
260 }
261
262
263
264
265
266 wksp_size = ZSTD_DStreamWorkspaceBound(params.windowSize);
267 wksp = large_malloc(wksp_size);
268 dstream = ZSTD_initDStream(params.windowSize, wksp, wksp_size);
269 if (dstream == NULL) {
270 error("Out of memory while allocating ZSTD_DStream");
271 err = -1;
272 goto out;
273 }
274
275
276
277
278
279
280
281 if (in_pos != NULL)
282 *in_pos = 0;
283 do {
284
285
286
287
288 if (in.pos == in.size) {
289 if (in_pos != NULL)
290 *in_pos += in.pos;
291 in_len = fill ? fill(in_buf, ZSTD_IOBUF_SIZE) : -1;
292 if (in_len < 0) {
293 error("ZSTD-compressed data is truncated");
294 err = -1;
295 goto out;
296 }
297 in.pos = 0;
298 in.size = in_len;
299 }
300
301 ret = ZSTD_decompressStream(dstream, &out, &in);
302 err = handle_zstd_error(ret, error);
303 if (err)
304 goto out;
305
306 if (flush != NULL && out.pos > 0) {
307 if (out.pos != flush(out.dst, out.pos)) {
308 error("Failed to flush()");
309 err = -1;
310 goto out;
311 }
312 out.pos = 0;
313 }
314 } while (ret != 0);
315
316 if (in_pos != NULL)
317 *in_pos += in.pos;
318
319 err = 0;
320out:
321 if (in_allocated != NULL)
322 large_free(in_allocated);
323 if (out_allocated != NULL)
324 large_free(out_allocated);
325 if (wksp != NULL)
326 large_free(wksp);
327 return err;
328}
329
330#ifndef UNZSTD_PREBOOT
331STATIC int INIT unzstd(unsigned char *buf, long len,
332 long (*fill)(void*, unsigned long),
333 long (*flush)(void*, unsigned long),
334 unsigned char *out_buf,
335 long *pos,
336 void (*error)(char *x))
337{
338 return __unzstd(buf, len, fill, flush, out_buf, 0, pos, error);
339}
340#else
341STATIC int INIT __decompress(unsigned char *buf, long len,
342 long (*fill)(void*, unsigned long),
343 long (*flush)(void*, unsigned long),
344 unsigned char *out_buf, long out_len,
345 long *pos,
346 void (*error)(char *x))
347{
348 return __unzstd(buf, len, fill, flush, out_buf, out_len, pos, error);
349}
350#endif
351