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