Skip to content

Commit 9a8d225

Browse files
author
Jian-Lin Li
committed
executor: support wifi subsystem fuzzing on FreeBSD
Use a wtap device to inject raw frames into 802.11 stack
1 parent aeb6ec6 commit 9a8d225

File tree

3 files changed

+940
-0
lines changed

3 files changed

+940
-0
lines changed

executor/common_bsd.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <stdarg.h>
1010
#include <stdbool.h>
1111
#include <string.h>
12+
#include <sys/ioctl.h>
1213
#include <sys/syscall.h>
1314

1415
#if GOOS_netbsd
@@ -421,6 +422,83 @@ static void sandbox_common()
421422
}
422423
#endif // SYZ_EXECUTOR || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NONE
423424

425+
#ifdef GOOS_freebsd
426+
427+
#if SYZ_EXECUTOR || SYZ_WIFI
428+
429+
#define WIFI_INITIAL_DEVICE_COUNT 2
430+
#define WIFI_IBSS_SSID \
431+
{ \
432+
+0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00 \
433+
}
434+
435+
#define WTAPIOCTLCRT _IOW('W', 1, int)
436+
#define WTAPIOCTLDEL _IOW('W', 2, int)
437+
438+
static int wtapfd = -1;
439+
440+
static void initialize_wifi_devices(void)
441+
{
442+
if (!flag_wifi)
443+
return;
444+
445+
wtapfd = open("/dev/wtapctl", O_RDONLY);
446+
447+
if ((wtapfd < 0) && (errno == ENOENT)) {
448+
execute_command(0, "kldload -q wtap");
449+
wtapfd = open("/dev/wtapctl", O_RDONLY);
450+
}
451+
452+
if (wtapfd == -1)
453+
fail("wtap: can't open /dev/wtapctl");
454+
455+
const int kWtapFd = 200;
456+
if (dup2(wtapfd, kWtapFd) < 0)
457+
fail("dup2(wtapfd, kWtapFd) failed");
458+
close(wtapfd);
459+
wtapfd = kWtapFd;
460+
461+
uint8_t ssid[] = WIFI_IBSS_SSID;
462+
for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) {
463+
if (ioctl(wtapfd, WTAPIOCTLCRT, &device_id) < 0)
464+
failmsg("wtap: can't create wtap device", "id=%d\n", device_id);
465+
execute_command(0, "ifconfig wlan%d create wlandev wtap%d wlanmode adhoc ssid %s", device_id, device_id, ssid);
466+
}
467+
}
468+
469+
static long syz_80211_inject_frame(volatile long a0, volatile long a1, volatile long a2)
470+
{
471+
char wlan_id = (char)a0;
472+
char* buf = (char*)a1;
473+
int buf_len = (int)a2;
474+
475+
char interface[32] = "/dev/wlan0\0";
476+
int wlanfd = -1;
477+
int ret = -1;
478+
479+
interface[9] += wlan_id;
480+
481+
if (wtapfd < 0)
482+
return -1;
483+
484+
wlanfd = open(interface, O_RDWR);
485+
486+
if ((wlanfd < 0)) {
487+
failmsg("wtap: can't open wlan device", "interface=%s\n", interface);
488+
return -1;
489+
}
490+
491+
ret = write(wlanfd, buf, buf_len);
492+
493+
close(wlanfd);
494+
495+
return ret;
496+
}
497+
498+
#endif // SYZ_EXECUTOR || SYZ_WIFI
499+
500+
#endif // GOOS_freebsd
501+
424502
#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
425503

426504
static void loop();
@@ -430,6 +508,9 @@ static int do_sandbox_none(void)
430508
sandbox_common();
431509
#if SYZ_EXECUTOR || SYZ_NET_INJECTION
432510
initialize_tun(procid);
511+
#endif
512+
#if SYZ_EXECUTOR || SYZ_WIFI
513+
initialize_wifi_devices();
433514
#endif
434515
loop();
435516
return 0;

0 commit comments

Comments
 (0)