Coverage Report

Created: 2026-06-09 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hostap/tests/fuzzing/eapol-supp/eapol-supp.c
Line
Count
Source
1
/*
2
 * wpa_supplicant - EAPOL 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 "eapol_supp/eapol_supp_sm.h"
14
#include "rsn_supp/wpa.h"
15
#include "rsn_supp/wpa_i.h"
16
#include "../fuzzer-common.h"
17
18
19
struct arg_ctx {
20
  const u8 *data;
21
  size_t data_len;
22
  struct wpa_sm *wpa;
23
  struct eapol_sm *eapol;
24
};
25
26
27
static void test_send_eapol(void *eloop_data, void *user_ctx)
28
2.11k
{
29
2.11k
  struct arg_ctx *ctx = eloop_data;
30
2.11k
  u8 src[ETH_ALEN] = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x01 };
31
2.11k
  u8 wpa_ie[200];
32
2.11k
  size_t wpa_ie_len;
33
34
2.11k
  wpa_hexdump(MSG_MSGDUMP, "fuzzer - EAPOL", ctx->data, ctx->data_len);
35
36
2.11k
  eapol_sm_notify_portEnabled(ctx->eapol, true);
37
38
2.11k
  wpa_sm_set_param(ctx->wpa, WPA_PARAM_PROTO, WPA_PROTO_RSN);
39
2.11k
  wpa_sm_set_param(ctx->wpa, WPA_PARAM_RSN_ENABLED, 1);
40
2.11k
  wpa_sm_set_param(ctx->wpa, WPA_PARAM_KEY_MGMT, WPA_KEY_MGMT_PSK);
41
2.11k
  wpa_sm_set_param(ctx->wpa, WPA_PARAM_PAIRWISE, WPA_CIPHER_CCMP);
42
2.11k
  wpa_sm_set_param(ctx->wpa, WPA_PARAM_GROUP, WPA_CIPHER_CCMP);
43
44
2.11k
  wpa_ie_len = sizeof(wpa_ie);
45
2.11k
  wpa_sm_set_assoc_wpa_ie_default(ctx->wpa, wpa_ie, &wpa_ie_len);
46
47
2.11k
  if (eapol_sm_rx_eapol(ctx->eapol, src, ctx->data, ctx->data_len,
48
2.11k
            FRAME_ENCRYPTION_UNKNOWN) <= 0)
49
1.85k
    wpa_sm_rx_eapol(ctx->wpa, src, ctx->data, ctx->data_len,
50
1.85k
        FRAME_ENCRYPTION_UNKNOWN);
51
52
2.11k
  eloop_terminate();
53
2.11k
}
54
55
56
static void * get_network_ctx(void *arg)
57
1.68k
{
58
1.68k
  return (void *) 1;
59
1.68k
}
60
61
62
static void set_state(void *arg, enum wpa_states state)
63
1.29k
{
64
1.29k
}
65
66
67
static void deauthenticate(void *arg, u16 reason_code)
68
0
{
69
0
}
70
71
72
static u8 * alloc_eapol(void *arg, u8 type,
73
      const void *data, u16 data_len,
74
      size_t *msg_len, void **data_pos)
75
1.29k
{
76
1.29k
  struct ieee802_1x_hdr *hdr;
77
78
1.29k
  *msg_len = sizeof(*hdr) + data_len;
79
1.29k
  hdr = os_malloc(*msg_len);
80
1.29k
  if (hdr == NULL)
81
0
    return NULL;
82
83
1.29k
  hdr->version = 2;
84
1.29k
  hdr->type = type;
85
1.29k
  hdr->length = host_to_be16(data_len);
86
87
1.29k
  if (data)
88
0
    os_memcpy(hdr + 1, data, data_len);
89
1.29k
  else
90
1.29k
    os_memset(hdr + 1, 0, data_len);
91
92
1.29k
  if (data_pos)
93
1.29k
    *data_pos = hdr + 1;
94
95
1.29k
  return (u8 *) hdr;
96
1.29k
}
97
98
99
static int ether_send(void *arg, const u8 *dest, u16 proto,
100
          const u8 *buf, size_t len)
101
1.29k
{
102
1.29k
  return 0;
103
1.29k
}
104
105
106
static int get_bssid(void *ctx, u8 *bssid)
107
1.29k
{
108
1.29k
  return -1;
109
1.29k
}
110
111
112
static int eapol_send(void *ctx, int type, const u8 *buf, size_t len)
113
84
{
114
84
  return 0;
115
84
}
116
117
118
static int init_wpa(struct arg_ctx *arg)
119
2.11k
{
120
2.11k
  struct wpa_sm_ctx *ctx;
121
122
2.11k
  ctx = os_zalloc(sizeof(*ctx));
123
2.11k
  if (ctx == NULL) {
124
0
    wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
125
0
    return -1;
126
0
  }
127
128
2.11k
  ctx->ctx = arg;
129
2.11k
  ctx->msg_ctx = arg;
130
2.11k
  ctx->get_network_ctx = get_network_ctx;
131
2.11k
  ctx->set_state = set_state;
132
2.11k
  ctx->deauthenticate = deauthenticate;
133
2.11k
  ctx->alloc_eapol = alloc_eapol;
134
2.11k
  ctx->ether_send = ether_send;
135
2.11k
  ctx->get_bssid = get_bssid;
136
137
2.11k
  arg->wpa = wpa_sm_init(ctx);
138
2.11k
  if (!arg->wpa)
139
0
    return -1;
140
2.11k
  arg->wpa->pmk_len = PMK_LEN;
141
2.11k
  return 0;
142
2.11k
}
143
144
145
static int init_eapol(struct arg_ctx *arg)
146
2.11k
{
147
2.11k
  struct eapol_ctx *ctx;
148
149
2.11k
  ctx = os_zalloc(sizeof(*ctx));
150
2.11k
  if (ctx == NULL) {
151
0
    wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
152
0
    return -1;
153
0
  }
154
155
2.11k
  ctx->ctx = arg;
156
2.11k
  ctx->msg_ctx = arg;
157
2.11k
  ctx->eapol_send = eapol_send;
158
159
2.11k
  arg->eapol = eapol_sm_init(ctx);
160
2.11k
  return arg->eapol ? 0 : -1;
161
2.11k
}
162
163
164
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
165
2.11k
{
166
2.11k
  struct arg_ctx ctx;
167
168
2.11k
  wpa_fuzzer_set_debug_level();
169
170
2.11k
  if (os_program_init())
171
0
    return 0;
172
173
2.11k
  if (eloop_init()) {
174
0
    wpa_printf(MSG_ERROR, "Failed to initialize event loop");
175
0
    return 0;
176
0
  }
177
178
2.11k
  os_memset(&ctx, 0, sizeof(ctx));
179
2.11k
  ctx.data = data;
180
2.11k
  ctx.data_len = size;
181
2.11k
  if (init_wpa(&ctx) || init_eapol(&ctx))
182
0
    goto fail;
183
184
2.11k
  eloop_register_timeout(0, 0, test_send_eapol, &ctx, NULL);
185
186
2.11k
  wpa_printf(MSG_DEBUG, "Starting eloop");
187
2.11k
  eloop_run();
188
2.11k
  wpa_printf(MSG_DEBUG, "eloop done");
189
190
2.11k
fail:
191
2.11k
  if (ctx.wpa)
192
2.11k
    wpa_sm_deinit(ctx.wpa);
193
2.11k
  if (ctx.eapol)
194
2.11k
    eapol_sm_deinit(ctx.eapol);
195
196
2.11k
  eloop_destroy();
197
2.11k
  os_program_deinit();
198
199
2.11k
  return 0;
200
2.11k
}