Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : :
3 : : #include <errno.h>
4 : :
5 : : #include "alloc-util.h"
6 : : #include "compress.h"
7 : : #include "fuzz.h"
8 : :
9 : 0 : static int compress(int alg,
10 : : const void *src, uint64_t src_size,
11 : : void *dst, size_t dst_alloc_size, size_t *dst_size) {
12 : :
13 [ # # ]: 0 : if (alg == OBJECT_COMPRESSED_LZ4)
14 : 0 : return compress_blob_lz4(src, src_size, dst, dst_alloc_size, dst_size);
15 [ # # ]: 0 : if (alg == OBJECT_COMPRESSED_XZ)
16 : 0 : return compress_blob_xz(src, src_size, dst, dst_alloc_size, dst_size);
17 : 0 : return -EOPNOTSUPP;
18 : : }
19 : :
20 : : typedef struct header {
21 : : uint32_t alg:2; /* We have only two compression algorithms so far, but we might add
22 : : * more in the future. Let's make this a bit wider so our fuzzer
23 : : * cases remain stable in the future. */
24 : : uint32_t sw_len;
25 : : uint32_t sw_alloc;
26 : : uint32_t reserved[3]; /* Extra space to keep fuzz cases stable in case we need to
27 : : * add stuff in the future. */
28 : : uint8_t data[];
29 : : } header;
30 : :
31 : 0 : int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
32 : 0 : _cleanup_free_ void *buf = NULL, *buf2 = NULL;
33 : : int r;
34 : :
35 [ # # ]: 0 : if (size < offsetof(header, data) + 1)
36 : 0 : return 0;
37 : :
38 : 0 : const header *h = (struct header*) data;
39 : 0 : const size_t data_len = size - offsetof(header, data);
40 : :
41 : 0 : int alg = h->alg;
42 : :
43 : : /* We don't want to fill the logs with messages about parse errors.
44 : : * Disable most logging if not running standalone */
45 [ # # ]: 0 : if (!getenv("SYSTEMD_LOG_LEVEL"))
46 : 0 : log_set_max_level(LOG_CRIT);
47 : :
48 [ # # # # ]: 0 : log_info("Using compression %s, data size=%zu",
49 : : object_compressed_to_string(alg) ?: "(none)",
50 : : data_len);
51 : :
52 : 0 : buf = malloc(MAX(size, 128u)); /* Make the buffer a bit larger for very small data */
53 [ # # ]: 0 : if (!buf) {
54 : 0 : log_oom();
55 : 0 : return 0;
56 : : }
57 : :
58 : : size_t csize;
59 : 0 : r = compress(alg, h->data, data_len, buf, size, &csize);
60 [ # # ]: 0 : if (r < 0) {
61 [ # # ]: 0 : log_error_errno(r, "Compression failed: %m");
62 : 0 : return 0;
63 : : }
64 : :
65 [ # # ]: 0 : log_debug("Compressed %zu bytes to → %zu bytes", data_len, csize);
66 : :
67 : 0 : size_t sw_alloc = MAX(h->sw_alloc, 1u);
68 : 0 : buf2 = malloc(sw_alloc);
69 [ # # ]: 0 : if (!buf) {
70 : 0 : log_oom();
71 : 0 : return 0;
72 : : }
73 : :
74 : 0 : size_t sw_len = MIN(data_len - 1, h->sw_len);
75 : :
76 : 0 : r = decompress_startswith(alg, buf, csize, &buf2, &sw_alloc, h->data, sw_len, h->data[sw_len]);
77 [ # # ]: 0 : assert_se(r > 0);
78 : :
79 : 0 : return 0;
80 : : }
|