/src/nghttp2/fuzz/fuzz_frames.cc
Line | Count | Source |
1 | | #include <string> |
2 | | #include <fuzzer/FuzzedDataProvider.h> |
3 | | |
4 | | extern "C" { |
5 | | #include <string.h> |
6 | | #include "nghttp2_hd.h" |
7 | | #include "nghttp2_frame.h" |
8 | | |
9 | | #include "nghttp2_test_helper.h" |
10 | | |
11 | 87.6k | #define HEADERS_LENGTH 7 |
12 | | |
13 | 34.1k | static nghttp2_nv fuzz_make_nv(std::string s1, std::string s2) { |
14 | 34.1k | nghttp2_nv nv; |
15 | 34.1k | uint8_t *n = (uint8_t *)malloc(s1.size()); |
16 | 34.1k | memcpy(n, s1.c_str(), s1.size()); |
17 | | |
18 | 34.1k | uint8_t *v = (uint8_t *)malloc(s2.size()); |
19 | 34.1k | memcpy(v, s2.c_str(), s2.size()); |
20 | | |
21 | 34.1k | nv.name = n; |
22 | 34.1k | nv.value = v; |
23 | 34.1k | nv.namelen = s1.size(); |
24 | 34.1k | nv.valuelen = s2.size(); |
25 | 34.1k | nv.flags = NGHTTP2_NV_FLAG_NONE; |
26 | | |
27 | 34.1k | return nv; |
28 | 34.1k | } |
29 | | |
30 | 34.1k | static void fuzz_free_nv(nghttp2_nv *nv) { |
31 | 34.1k | free(nv->name); |
32 | 34.1k | free(nv->value); |
33 | 34.1k | } |
34 | | |
35 | 2.43k | void check_frame_pack_headers(FuzzedDataProvider *data_provider) { |
36 | 2.43k | nghttp2_hd_deflater deflater; |
37 | 2.43k | nghttp2_hd_inflater inflater; |
38 | 2.43k | nghttp2_headers frame, oframe; |
39 | 2.43k | nghttp2_bufs bufs; |
40 | 2.43k | nghttp2_nv *nva; |
41 | 2.43k | nghttp2_priority_spec pri_spec; |
42 | 2.43k | size_t nvlen; |
43 | 2.43k | nva_out out; |
44 | 2.43k | size_t hdblocklen; |
45 | 2.43k | int rv; |
46 | 2.43k | nghttp2_mem *mem; |
47 | | |
48 | 2.43k | mem = nghttp2_mem_default(); |
49 | 2.43k | frame_pack_bufs_init(&bufs); |
50 | | |
51 | 2.43k | nva_out_init(&out); |
52 | 2.43k | nghttp2_hd_deflate_init(&deflater, mem); |
53 | 2.43k | nghttp2_hd_inflate_init(&inflater, mem); |
54 | | |
55 | | /* Create a set of headers seeded with data from the fuzzer */ |
56 | 2.43k | nva = (nghttp2_nv *)mem->malloc(sizeof(nghttp2_nv) * HEADERS_LENGTH, NULL); |
57 | 19.4k | for (int i = 0; i < HEADERS_LENGTH; i++) { |
58 | 17.0k | nva[i] = fuzz_make_nv(data_provider->ConsumeRandomLengthString(30), |
59 | 17.0k | data_provider->ConsumeRandomLengthString(300)); |
60 | 17.0k | } |
61 | | |
62 | 2.43k | nvlen = HEADERS_LENGTH; |
63 | 2.43k | nghttp2_priority_spec_default_init(&pri_spec); |
64 | 2.43k | nghttp2_frame_headers_init( |
65 | 2.43k | &frame, NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS, 1000000007, |
66 | 2.43k | NGHTTP2_HCAT_REQUEST, &pri_spec, nva, nvlen); |
67 | | |
68 | | /* Perform a set of operations with the fuzz data */ |
69 | 2.43k | rv = nghttp2_frame_pack_headers(&bufs, &frame, &deflater); |
70 | 2.43k | if (rv == 0) { |
71 | 2.43k | unpack_framebuf((nghttp2_frame *)&oframe, &bufs); |
72 | | |
73 | 2.43k | inflate_hd(&inflater, &out, &bufs, NGHTTP2_FRAME_HDLEN, mem); |
74 | 2.43k | nva_out_reset(&out, mem); |
75 | 2.43k | nghttp2_bufs_reset(&bufs); |
76 | 2.43k | } |
77 | | |
78 | 2.43k | nghttp2_nv *nva2 = NULL; |
79 | 2.43k | rv = nghttp2_nv_array_copy(&nva2, nva, nvlen, mem); |
80 | 2.43k | if (rv == 0) { |
81 | 2.43k | nghttp2_nv_array_del(nva2, mem); |
82 | 2.43k | } |
83 | | |
84 | | /* Cleanup */ |
85 | 19.4k | for (int i = 0; i < HEADERS_LENGTH; i++) { |
86 | 17.0k | fuzz_free_nv(&nva[i]); |
87 | 17.0k | } |
88 | | |
89 | 2.43k | nghttp2_bufs_free(&bufs); |
90 | 2.43k | nghttp2_frame_headers_free(&frame, mem); |
91 | 2.43k | nghttp2_hd_inflate_free(&inflater); |
92 | 2.43k | nghttp2_hd_deflate_free(&deflater); |
93 | 2.43k | } |
94 | | |
95 | 2.43k | void check_frame_push_promise(FuzzedDataProvider *data_provider) { |
96 | 2.43k | nghttp2_hd_deflater deflater; |
97 | 2.43k | nghttp2_hd_inflater inflater; |
98 | 2.43k | nghttp2_push_promise frame, oframe; |
99 | 2.43k | nghttp2_bufs bufs; |
100 | 2.43k | nghttp2_nv *nva; |
101 | 2.43k | nghttp2_priority_spec pri_spec; |
102 | 2.43k | size_t nvlen; |
103 | 2.43k | nva_out out; |
104 | 2.43k | size_t hdblocklen; |
105 | 2.43k | int rv; |
106 | 2.43k | nghttp2_mem *mem; |
107 | | |
108 | 2.43k | mem = nghttp2_mem_default(); |
109 | 2.43k | frame_pack_bufs_init(&bufs); |
110 | | |
111 | 2.43k | nva_out_init(&out); |
112 | 2.43k | nghttp2_hd_deflate_init(&deflater, mem); |
113 | 2.43k | nghttp2_hd_inflate_init(&inflater, mem); |
114 | | |
115 | | /* Create a set of headers seeded with data from the fuzzer */ |
116 | 2.43k | nva = (nghttp2_nv *)mem->malloc(sizeof(nghttp2_nv) * HEADERS_LENGTH, NULL); |
117 | 19.4k | for (int i = 0; i < HEADERS_LENGTH; i++) { |
118 | 17.0k | nva[i] = fuzz_make_nv(data_provider->ConsumeRandomLengthString(30), |
119 | 17.0k | data_provider->ConsumeRandomLengthString(300)); |
120 | 17.0k | } |
121 | 2.43k | nvlen = HEADERS_LENGTH; |
122 | 2.43k | nghttp2_priority_spec_default_init(&pri_spec); |
123 | | |
124 | | /* Perform a set of operations with the fuzz data */ |
125 | 2.43k | nghttp2_frame_push_promise_init(&frame, NGHTTP2_FLAG_END_HEADERS, 1000000007, |
126 | 2.43k | (1U << 31) - 1, nva, nvlen); |
127 | | |
128 | 2.43k | rv = nghttp2_frame_pack_push_promise(&bufs, &frame, &deflater); |
129 | 2.43k | if (rv == 0) { |
130 | 2.43k | unpack_framebuf((nghttp2_frame *)&oframe, &bufs); |
131 | 2.43k | } |
132 | | |
133 | 2.43k | nghttp2_nv *nva2 = NULL; |
134 | 2.43k | rv = nghttp2_nv_array_copy(&nva2, nva, nvlen, mem); |
135 | 2.43k | if (rv == 0) { |
136 | 2.43k | nghttp2_nv_array_del(nva2, mem); |
137 | 2.43k | } |
138 | | |
139 | | /* Cleanup */ |
140 | 19.4k | for (int i = 0; i < HEADERS_LENGTH; i++) { |
141 | 17.0k | fuzz_free_nv(&nva[i]); |
142 | 17.0k | } |
143 | | |
144 | 2.43k | nghttp2_bufs_reset(&bufs); |
145 | 2.43k | nghttp2_bufs_free(&bufs); |
146 | | |
147 | 2.43k | nghttp2_frame_push_promise_free(&frame, mem); |
148 | 2.43k | nghttp2_hd_inflate_free(&inflater); |
149 | 2.43k | nghttp2_hd_deflate_free(&deflater); |
150 | 2.43k | } |
151 | | |
152 | 13.7k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
153 | 13.7k | FuzzedDataProvider data_provider(data, size); |
154 | | |
155 | 13.7k | check_frame_pack_headers(&data_provider); |
156 | 13.7k | check_frame_push_promise(&data_provider); |
157 | 13.7k | return 0; |
158 | 13.7k | } |
159 | | |
160 | | } // extern C |