Skip to content

Commit 789c22c

Browse files
Jian-Lin LiJian-Lin Li
Jian-Lin Li
authored and
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 789c22c

File tree

3 files changed

+941
-0
lines changed

3 files changed

+941
-0
lines changed

executor/common_bsd.h

Lines changed: 82 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+
#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+
#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+
const int kWtapFd = 200;
455+
if (dup2(wtapfd, kWtapFd) < 0)
456+
fail("dup2(wtapfd, kWtapFd) failed");
457+
close(wtapfd);
458+
wtapfd = kWtapFd;
459+
460+
uint8_t ssid[] = WIFI_IBSS_SSID;
461+
for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) {
462+
if (ioctl(wtapfd, WTAPIOCTLCRT, &device_id) < 0)
463+
failmsg("wtap: can't create wtap device", "id=%d\n", device_id);
464+
execute_command(0, "ifconfig wlan%d create wlandev wtap%d wlanmode adhoc ssid %s", device_id, device_id, ssid);
465+
}
466+
}
467+
468+
static long syz_80211_inject_frame(volatile long a0, volatile long a1, volatile long a2)
469+
{
470+
char wlan_id = (char)a0;
471+
char* buf = (char*)a1;
472+
int buf_len = (int)a2;
473+
474+
char interface[32] = "/dev/wlan0\0";
475+
int wlanfd = -1;
476+
int ret = -1;
477+
478+
interface[9] += wlan_id;
479+
480+
if (wtapfd < 0)
481+
return -1;
482+
483+
wlanfd = open(interface, O_RDWR);
484+
485+
if ((wlanfd < 0)) {
486+
failmsg("wtap: can't open wlan device", "interface=%s\n", interface);
487+
return -1;
488+
}
489+
490+
ret = write(wlanfd, buf, buf_len);
491+
492+
close(wlanfd);
493+
494+
return ret;
495+
}
496+
497+
#endif // SYZ_EXECUTOR || SYZ_WIFI
498+
499+
#endif // GOOS_freebsd
500+
424501
#if SYZ_EXECUTOR || SYZ_SANDBOX_NONE
425502

426503
static void loop();
@@ -430,6 +507,11 @@ static int do_sandbox_none(void)
430507
sandbox_common();
431508
#if SYZ_EXECUTOR || SYZ_NET_INJECTION
432509
initialize_tun(procid);
510+
#endif
511+
#ifdef GOOS_freebsd
512+
#if SYZ_EXECUTOR || SYZ_WIFI
513+
initialize_wifi_devices();
514+
#endif
433515
#endif
434516
loop();
435517
return 0;

0 commit comments

Comments
 (0)