1 /*
2 * hostapd - Management frame fuzzer
3 * Copyright (c) 2015-2019, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "ap/hostapd.h"
14 #include "ap/hw_features.h"
15 #include "ap/ieee802_11.h"
16 #include "ap/sta_info.h"
17 #include "ap/ap_list.h"
18 #include "../fuzzer-common.h"
19
20
21 const struct wpa_driver_ops *const wpa_drivers[] =
22 {
23 NULL
24 };
25
26
27 struct arg_ctx {
28 const u8 *data;
29 size_t data_len;
30 struct hostapd_iface iface;
31 struct hostapd_data hapd;
32 struct wpa_driver_ops driver;
33 struct hostapd_config iconf;
34 struct hostapd_bss_config conf;
35 };
36
37
test_send_mgmt(void * eloop_data,void * user_ctx)38 static void test_send_mgmt(void *eloop_data, void *user_ctx)
39 {
40 struct arg_ctx *ctx = eloop_data;
41 struct hostapd_frame_info fi;
42 const u8 *pos, *end;
43
44 os_memset(&fi, 0, sizeof(fi));
45
46 pos = ctx->data;
47 end = pos + ctx->data_len;
48
49 while (end - pos > 2) {
50 u16 flen;
51
52 flen = WPA_GET_BE16(pos);
53 pos += 2;
54 if (end - pos < flen)
55 break;
56 wpa_hexdump(MSG_MSGDUMP, "fuzzer - frame", pos, flen);
57 ieee802_11_mgmt(&ctx->hapd, pos, flen, &fi);
58 pos += flen;
59 }
60
61 eloop_terminate();
62 }
63
64
gen_modes(void)65 static struct hostapd_hw_modes * gen_modes(void)
66 {
67 struct hostapd_hw_modes *mode;
68 struct hostapd_channel_data *chan;
69
70 mode = os_zalloc(sizeof(struct hostapd_hw_modes));
71 if (!mode)
72 return NULL;
73
74 mode->mode = HOSTAPD_MODE_IEEE80211G;
75 chan = os_zalloc(sizeof(struct hostapd_channel_data));
76 if (!chan) {
77 os_free(mode);
78 return NULL;
79 }
80 chan->chan = 1;
81 chan->freq = 2412;
82 mode->channels = chan;
83 mode->num_channels = 1;
84
85 mode->rates = os_zalloc(sizeof(int));
86 if (!mode->rates) {
87 os_free(chan);
88 os_free(mode);
89 return NULL;
90 }
91 mode->rates[0] = 10;
92 mode->num_rates = 1;
93
94 return mode;
95 }
96
97
init_hapd(struct arg_ctx * ctx)98 static int init_hapd(struct arg_ctx *ctx)
99 {
100 struct hostapd_data *hapd = &ctx->hapd;
101 struct sta_info *sta;
102 struct hostapd_bss_config *bss;
103
104 hapd->driver = &ctx->driver;
105 os_memcpy(hapd->own_addr, "\x02\x00\x00\x00\x03\x00", ETH_ALEN);
106 hapd->iface = &ctx->iface;
107 hapd->iface->conf = hostapd_config_defaults();
108 if (!hapd->iface->conf)
109 return -1;
110 hapd->iface->hw_features = gen_modes();
111 hapd->iface->num_hw_features = 1;
112 hapd->iface->current_mode = hapd->iface->hw_features;
113 hapd->iconf = hapd->iface->conf;
114 hapd->iconf->hw_mode = HOSTAPD_MODE_IEEE80211G;
115 hapd->iconf->channel = 1;
116 bss = hapd->conf = hapd->iconf->bss[0];
117 hostapd_config_defaults_bss(hapd->conf);
118 os_memcpy(bss->ssid.ssid, "test", 4);
119 bss->ssid.ssid_len = 4;
120 bss->ssid.ssid_set = 1;
121
122 sta = ap_sta_add(hapd, (u8 *) "\x02\x00\x00\x00\x00\x00");
123 if (sta)
124 sta->flags |= WLAN_STA_ASSOC | WLAN_STA_WMM;
125
126 return 0;
127 }
128
129
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)130 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
131 {
132 struct arg_ctx ctx;
133
134 wpa_fuzzer_set_debug_level();
135
136 if (os_program_init())
137 return 0;
138
139 if (eloop_init()) {
140 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
141 return 0;
142 }
143
144 os_memset(&ctx, 0, sizeof(ctx));
145 ctx.data = data;
146 ctx.data_len = size;
147
148 if (init_hapd(&ctx))
149 goto fail;
150
151 eloop_register_timeout(0, 0, test_send_mgmt, &ctx, NULL);
152
153 wpa_printf(MSG_DEBUG, "Starting eloop");
154 eloop_run();
155 wpa_printf(MSG_DEBUG, "eloop done");
156 hostapd_free_stas(&ctx.hapd);
157 hostapd_free_hw_features(ctx.hapd.iface->hw_features,
158 ctx.hapd.iface->num_hw_features);
159
160 fail:
161 hostapd_config_free(ctx.hapd.iconf);
162 ap_list_deinit(&ctx.iface);
163 eloop_destroy();
164 os_program_deinit();
165
166 return 0;
167 }
168