Compare commits
10 Commits
aef394895d
...
c2ad0006eb
Author | SHA1 | Date |
---|---|---|
James Prestwood | c2ad0006eb | |
James Prestwood | 5fcfb430b2 | |
James Prestwood | 3a17c8e3c5 | |
James Prestwood | 6febe5bed1 | |
James Prestwood | 338577bb3a | |
James Prestwood | 83c032a583 | |
James Prestwood | d34b4e16e0 | |
James Prestwood | 52a47c9fd4 | |
James Prestwood | 816d258cab | |
James Prestwood | 5067654a6d |
|
@ -0,0 +1,72 @@
|
|||
import unittest
|
||||
import sys
|
||||
import sys
|
||||
import os
|
||||
from scapy.layers.dot11 import *
|
||||
from scapy.arch import str2mac, get_if_raw_hwaddr
|
||||
from time import time, sleep
|
||||
from threading import Thread
|
||||
|
||||
def if_hwaddr(iff):
|
||||
return str2mac(get_if_raw_hwaddr(iff)[1])
|
||||
|
||||
def config_mon(iface, channel):
|
||||
"""set the interface in monitor mode and then change channel using iw"""
|
||||
os.system("ip link set dev %s down" % iface)
|
||||
os.system("iw dev %s set type monitor" % iface)
|
||||
os.system("ip link set dev %s up" % iface)
|
||||
os.system("iw dev %s set channel %d" % (iface, channel))
|
||||
|
||||
class AP:
|
||||
def __init__(self, ssid, psk, mac=None, mode="stdio", iface="wlan0", channel=1):
|
||||
self.channel = channel
|
||||
self.iface = iface
|
||||
self.mode = mode
|
||||
if self.mode == "iface":
|
||||
if not mac:
|
||||
mac = if_hwaddr(iface)
|
||||
config_mon(iface, channel)
|
||||
if not mac:
|
||||
raise Exception("Need a mac")
|
||||
else:
|
||||
self.mac = mac
|
||||
self.boottime = time()
|
||||
|
||||
def get_radiotap_header(self):
|
||||
return RadioTap()
|
||||
|
||||
def dot11_beacon(self, contents):
|
||||
evil_packet = (
|
||||
self.get_radiotap_header()
|
||||
/ Dot11(
|
||||
subtype=8, addr1="ff:ff:ff:ff:ff:ff", addr2=self.mac, addr3=self.mac
|
||||
)
|
||||
/ Dot11Beacon(cap=0x3101)
|
||||
/ contents
|
||||
)
|
||||
self.sendp(evil_packet)
|
||||
|
||||
def run(self, contents):
|
||||
interval = 0.05
|
||||
num_beacons = 100
|
||||
|
||||
while num_beacons:
|
||||
self.dot11_beacon(contents)
|
||||
sleep(interval)
|
||||
num_beacons -= 1
|
||||
|
||||
def start(self, contents):
|
||||
self.thread = Thread(target=self.run, args=(contents,))
|
||||
self.thread.start()
|
||||
|
||||
def stop(self):
|
||||
self.thread.join()
|
||||
|
||||
def sendp(self, packet, verbose=False):
|
||||
if self.mode == "stdio":
|
||||
x = packet.build()
|
||||
sys.stdout.buffer.write(struct.pack("<L", len(x)) + x)
|
||||
sys.stdout.buffer.flush()
|
||||
return
|
||||
assert self.mode == "iface"
|
||||
sendp(packet, iface=self.iface, verbose=False)
|
|
@ -0,0 +1,7 @@
|
|||
[SETUP]
|
||||
num_radios=2
|
||||
start_iwd=0
|
||||
hwsim_medium=yes
|
||||
|
||||
[rad1]
|
||||
reserve=true
|
|
@ -0,0 +1,37 @@
|
|||
#! /usr/bin/python3
|
||||
|
||||
import unittest
|
||||
import sys
|
||||
import sys
|
||||
import os
|
||||
from fake_ap import AP
|
||||
|
||||
sys.path.append('../util')
|
||||
from iwd import IWD
|
||||
|
||||
# Probe frame that causes IWD to crash
|
||||
beacon=b'\xdd\nPo\x9a\t\x0e\x00\x00\x19\x10\x00\xdd/Po\x9a\t\x0c\x02\x00\x00\xdd\x05\x03\x03\x03Po\x9a\x10\x00\x0b\x05\x0e\x00\x00\x00\x00\x0b\x05\x00\x00\x00\xdd\x05\x00\x03\x03\x03\x03\x00\x00\x00\xdd\x05\x03\x03\x03\x03\x03'
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_beacon_crash(self):
|
||||
wd = IWD(True)
|
||||
|
||||
devs = wd.list_devices()
|
||||
|
||||
self.assertEqual(len(devs), 1)
|
||||
|
||||
devs[0].autoconnect = True
|
||||
|
||||
os.system("iw phy rad1 interface add wlan1 type managed")
|
||||
|
||||
ap = AP("evilAP", "password1234", mode="iface", iface="wlan1", channel=4)
|
||||
ap.start(beacon)
|
||||
|
||||
condition = "obj.scanning == True"
|
||||
wd.wait_for_object_condition(devs[0], condition)
|
||||
|
||||
condition = "obj.scanning == False"
|
||||
wd.wait_for_object_condition(devs[0], condition)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=True)
|
13
src/ap.c
13
src/ap.c
|
@ -455,7 +455,8 @@ static void ap_del_station(struct sta_state *sta, uint16_t reason,
|
|||
sta->ip_alloc_lease = NULL;
|
||||
l_dhcp_server_expire_by_mac(ap->netconfig_dhcp, sta->addr);
|
||||
|
||||
ap_event_done(ap, prev);
|
||||
if (ap_event_done(ap, prev))
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1247,8 +1248,10 @@ static size_t ap_build_country_ie(struct ap_state *ap, uint8_t *out_buf,
|
|||
}
|
||||
|
||||
/* finish final group */
|
||||
if (last) {
|
||||
*pos++ = nchans;
|
||||
*pos++ = last->tx_power;
|
||||
}
|
||||
|
||||
len = pos - out_buf - 2;
|
||||
|
||||
|
@ -1482,7 +1485,7 @@ static void ap_handshake_event(struct handshake_state *hs,
|
|||
}
|
||||
case HANDSHAKE_EVENT_REKEY_COMPLETE:
|
||||
ap_set_sta_rekey_timer(ap, sta);
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2961,7 +2964,7 @@ static void ap_handle_new_station(struct ap_state *ap, struct l_genl_msg *msg)
|
|||
uint16_t type;
|
||||
uint16_t len;
|
||||
const void *data;
|
||||
uint8_t mac[6];
|
||||
const uint8_t *mac = NULL;
|
||||
uint8_t *assoc_rsne = NULL;
|
||||
|
||||
if (!l_genl_attr_init(&attr, msg))
|
||||
|
@ -2981,12 +2984,12 @@ static void ap_handle_new_station(struct ap_state *ap, struct l_genl_msg *msg)
|
|||
if (len != 6)
|
||||
goto cleanup;
|
||||
|
||||
memcpy(mac, data, 6);
|
||||
mac = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!assoc_rsne)
|
||||
if (!assoc_rsne || !mac)
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
|
|
|
@ -136,9 +136,7 @@ static bool extract_nested(const void *data, uint16_t len, void *o)
|
|||
const struct l_genl_attr *outer = data;
|
||||
struct l_genl_attr *nested = o;
|
||||
|
||||
l_genl_attr_recurse(outer, nested);
|
||||
|
||||
return true;
|
||||
return l_genl_attr_recurse(outer, nested);
|
||||
}
|
||||
|
||||
static bool extract_u8(const void *data, uint16_t len, void *o)
|
||||
|
|
|
@ -376,6 +376,9 @@ static bool extract_p2p_group_info(const uint8_t *attr, size_t len,
|
|||
desc = l_new(struct p2p_client_info_descriptor, 1);
|
||||
l_queue_push_tail(*out, desc);
|
||||
|
||||
if (desc_len < 24)
|
||||
goto error;
|
||||
|
||||
memcpy(desc->device_addr, attr + 0, 6);
|
||||
memcpy(desc->interface_addr, attr + 6, 6);
|
||||
desc->device_caps = attr[12];
|
||||
|
@ -541,7 +544,8 @@ static void p2p_clear_advertised_service_descriptor(void *data)
|
|||
static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len,
|
||||
void *data)
|
||||
{
|
||||
struct l_queue **out = data;
|
||||
struct l_queue **q = data;
|
||||
struct l_queue *out = NULL;
|
||||
|
||||
while (len) {
|
||||
struct p2p_advertised_service_descriptor *desc;
|
||||
|
@ -557,11 +561,11 @@ static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len,
|
|||
if (!l_utf8_validate((const char *) attr + 7, name_len, NULL))
|
||||
goto error;
|
||||
|
||||
if (!*out)
|
||||
*out = l_queue_new();
|
||||
if (!out)
|
||||
out = l_queue_new();
|
||||
|
||||
desc = l_new(struct p2p_advertised_service_descriptor, 1);
|
||||
l_queue_push_tail(*out, desc);
|
||||
l_queue_push_tail(out, desc);
|
||||
|
||||
desc->advertisement_id = l_get_le32(attr + 0);
|
||||
desc->wsc_config_methods = l_get_be16(attr + 4);
|
||||
|
@ -572,10 +576,12 @@ static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len,
|
|||
len -= 7 + name_len;
|
||||
}
|
||||
|
||||
*q = out;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
l_queue_destroy(*out, p2p_clear_advertised_service_descriptor);
|
||||
l_queue_destroy(out, p2p_clear_advertised_service_descriptor);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -773,7 +779,7 @@ done:
|
|||
/* Section 4.2.1 */
|
||||
int p2p_parse_beacon(const uint8_t *pdu, size_t len, struct p2p_beacon *out)
|
||||
{
|
||||
struct p2p_beacon d = {};
|
||||
struct p2p_beacon d = {0};
|
||||
int r;
|
||||
|
||||
r = p2p_parse_attrs(pdu, len,
|
||||
|
@ -794,7 +800,7 @@ int p2p_parse_beacon(const uint8_t *pdu, size_t len, struct p2p_beacon *out)
|
|||
int p2p_parse_probe_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_probe_req *out)
|
||||
{
|
||||
struct p2p_probe_req d = {};
|
||||
struct p2p_probe_req d = {0};
|
||||
int r;
|
||||
|
||||
r = p2p_parse_attrs(pdu, len,
|
||||
|
@ -825,7 +831,7 @@ int p2p_parse_probe_req(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_probe_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_probe_resp *out)
|
||||
{
|
||||
struct p2p_probe_resp d = {};
|
||||
struct p2p_probe_resp d = {0};
|
||||
int r;
|
||||
|
||||
r = p2p_parse_attrs(pdu, len,
|
||||
|
@ -850,7 +856,7 @@ int p2p_parse_probe_resp(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_association_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_association_req *out)
|
||||
{
|
||||
struct p2p_association_req d = {};
|
||||
struct p2p_association_req d = {0};
|
||||
int r;
|
||||
|
||||
r = p2p_parse_attrs(pdu, len,
|
||||
|
@ -873,7 +879,7 @@ int p2p_parse_association_req(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_association_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_association_resp *out)
|
||||
{
|
||||
struct p2p_association_resp d = {};
|
||||
struct p2p_association_resp d = {0};
|
||||
int r;
|
||||
|
||||
r = p2p_parse_attrs(pdu, len,
|
||||
|
@ -936,7 +942,7 @@ int p2p_parse_disassociation(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_go_negotiation_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_go_negotiation_req *out)
|
||||
{
|
||||
struct p2p_go_negotiation_req d = {};
|
||||
struct p2p_go_negotiation_req d = {0};
|
||||
int r;
|
||||
struct p2p_go_intent_attr go_intent;
|
||||
uint8_t *wsc_data;
|
||||
|
@ -998,7 +1004,7 @@ error:
|
|||
int p2p_parse_go_negotiation_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_go_negotiation_resp *out)
|
||||
{
|
||||
struct p2p_go_negotiation_resp d = {};
|
||||
struct p2p_go_negotiation_resp d = {0};
|
||||
int r;
|
||||
struct p2p_go_intent_attr go_intent;
|
||||
uint8_t *wsc_data;
|
||||
|
@ -1059,7 +1065,7 @@ error:
|
|||
int p2p_parse_go_negotiation_confirmation(const uint8_t *pdu, size_t len,
|
||||
struct p2p_go_negotiation_confirmation *out)
|
||||
{
|
||||
struct p2p_go_negotiation_confirmation d = {};
|
||||
struct p2p_go_negotiation_confirmation d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1093,7 +1099,7 @@ error:
|
|||
int p2p_parse_invitation_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_invitation_req *out)
|
||||
{
|
||||
struct p2p_invitation_req d = {};
|
||||
struct p2p_invitation_req d = {0};
|
||||
int r;
|
||||
uint8_t *wsc_data;
|
||||
ssize_t wsc_len;
|
||||
|
@ -1148,7 +1154,7 @@ error:
|
|||
int p2p_parse_invitation_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_invitation_resp *out)
|
||||
{
|
||||
struct p2p_invitation_resp d = {};
|
||||
struct p2p_invitation_resp d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1182,7 +1188,7 @@ error:
|
|||
int p2p_parse_device_disc_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_device_discoverability_req *out)
|
||||
{
|
||||
struct p2p_device_discoverability_req d = {};
|
||||
struct p2p_device_discoverability_req d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1207,7 +1213,7 @@ int p2p_parse_device_disc_req(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_device_disc_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_device_discoverability_resp *out)
|
||||
{
|
||||
struct p2p_device_discoverability_resp d = {};
|
||||
struct p2p_device_discoverability_resp d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1231,7 +1237,7 @@ int p2p_parse_device_disc_resp(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_provision_disc_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_provision_discovery_req *out)
|
||||
{
|
||||
struct p2p_provision_discovery_req d = {};
|
||||
struct p2p_provision_discovery_req d = {0};
|
||||
int r;
|
||||
uint8_t *wsc_data;
|
||||
ssize_t wsc_len;
|
||||
|
@ -1306,7 +1312,7 @@ error:
|
|||
int p2p_parse_provision_disc_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_provision_discovery_resp *out)
|
||||
{
|
||||
struct p2p_provision_discovery_resp d = {};
|
||||
struct p2p_provision_discovery_resp d = {0};
|
||||
int r;
|
||||
uint8_t *wsc_data;
|
||||
ssize_t wsc_len;
|
||||
|
@ -1386,7 +1392,7 @@ error:
|
|||
int p2p_parse_notice_of_absence(const uint8_t *pdu, size_t len,
|
||||
struct p2p_notice_of_absence *out)
|
||||
{
|
||||
struct p2p_notice_of_absence d = {};
|
||||
struct p2p_notice_of_absence d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1408,7 +1414,7 @@ int p2p_parse_notice_of_absence(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_presence_req(const uint8_t *pdu, size_t len,
|
||||
struct p2p_presence_req *out)
|
||||
{
|
||||
struct p2p_presence_req d = {};
|
||||
struct p2p_presence_req d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
@ -1434,7 +1440,7 @@ int p2p_parse_presence_req(const uint8_t *pdu, size_t len,
|
|||
int p2p_parse_presence_resp(const uint8_t *pdu, size_t len,
|
||||
struct p2p_presence_resp *out)
|
||||
{
|
||||
struct p2p_presence_resp d = {};
|
||||
struct p2p_presence_resp d = {0};
|
||||
int r;
|
||||
|
||||
if (len < 1)
|
||||
|
|
|
@ -175,23 +175,27 @@ class Process(subprocess.Popen):
|
|||
def process_io(self, source, condition):
|
||||
if condition & GLib.IO_HUP:
|
||||
self.hup = True
|
||||
self.wait()
|
||||
bt = self.out.partition("++++++++ backtrace ++++++++")
|
||||
if bt[1]:
|
||||
raise Exception(f"Process {self.args[0]} crashed!\n{bt[1] + bt[2]}")
|
||||
|
||||
data = source.read()
|
||||
|
||||
if not data:
|
||||
return True
|
||||
return not self.hup
|
||||
|
||||
try:
|
||||
data = data.decode('utf-8')
|
||||
except:
|
||||
return True
|
||||
return not self.hup
|
||||
|
||||
# Save data away in case the caller needs it (e.g. list_sta)
|
||||
self.out += data
|
||||
|
||||
self._write_io(self, data)
|
||||
|
||||
return True
|
||||
return not self.hup
|
||||
|
||||
def _append_outfile(self, file, append=True):
|
||||
gid = int(os.environ.get('SUDO_GID', os.getgid()))
|
||||
|
|
Loading…
Reference in New Issue