Skip to content

Commit 4ad952e

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 4ad952e

File tree

3 files changed

+939
-0
lines changed

3 files changed

+939
-0
lines changed

executor/common_bsd.h

Lines changed: 80 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,82 @@ static void sandbox_common()
421422
}
422423
#endif // SYZ_EXECUTOR || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NONE
423424

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

426503
static void loop();
@@ -430,6 +507,9 @@ static int do_sandbox_none(void)
430507
sandbox_common();
431508
#if SYZ_EXECUTOR || SYZ_NET_INJECTION
432509
initialize_tun(procid);
510+
#endif
511+
#if SYZ_EXECUTOR || SYZ_WIFI
512+
initialize_wifi_devices();
433513
#endif
434514
loop();
435515
return 0;

0 commit comments

Comments
 (0)