public inbox for iwd@lists.linux.dev
 help / color / mirror / Atom feed
From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>,
	Alex Radocea <alex@supernetworks.org>
Subject: [PATCH 2/5] auto-t: Add frame fuzzing test
Date: Thu, 29 Feb 2024 09:07:31 -0800	[thread overview]
Message-ID: <20240229170734.1498918-2-prestwoj@gmail.com> (raw)
In-Reply-To: <20240229170734.1498918-1-prestwoj@gmail.com>

Add a test to validate a crash found by Alex Radocea when sending
a fuzzed beacon frame.

Co-authored-by: Alex Radocea <alex@supernetworks.org>
---
 autotests/testFrameFuzzing/fake_ap.py         | 72 +++++++++++++++++++
 autotests/testFrameFuzzing/hw.conf            |  7 ++
 .../testFrameFuzzing/test_frame_fuzzing.py    | 37 ++++++++++
 3 files changed, 116 insertions(+)
 create mode 100644 autotests/testFrameFuzzing/fake_ap.py
 create mode 100644 autotests/testFrameFuzzing/hw.conf
 create mode 100644 autotests/testFrameFuzzing/test_frame_fuzzing.py

diff --git a/autotests/testFrameFuzzing/fake_ap.py b/autotests/testFrameFuzzing/fake_ap.py
new file mode 100644
index 00000000..8ee369de
--- /dev/null
+++ b/autotests/testFrameFuzzing/fake_ap.py
@@ -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)
diff --git a/autotests/testFrameFuzzing/hw.conf b/autotests/testFrameFuzzing/hw.conf
new file mode 100644
index 00000000..0500b51d
--- /dev/null
+++ b/autotests/testFrameFuzzing/hw.conf
@@ -0,0 +1,7 @@
+[SETUP]
+num_radios=2
+start_iwd=0
+hwsim_medium=yes
+
+[rad1]
+reserve=true
diff --git a/autotests/testFrameFuzzing/test_frame_fuzzing.py b/autotests/testFrameFuzzing/test_frame_fuzzing.py
new file mode 100644
index 00000000..9def7684
--- /dev/null
+++ b/autotests/testFrameFuzzing/test_frame_fuzzing.py
@@ -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)
-- 
2.34.1


  reply	other threads:[~2024-02-29 17:07 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-29 17:07 [PATCH 1/5] auto-t: end process_io on HUP signal, detect process crash James Prestwood
2024-02-29 17:07 ` James Prestwood [this message]
2024-02-29 17:07 ` [PATCH 3/5] p2putil: fix crash/remove side effect parsing adv service info James Prestwood
2024-02-29 17:07 ` [PATCH 4/5] p2putil: initialize all parsing structures to zero James Prestwood
2024-02-29 17:07 ` [PATCH 5/5] p2putil: check length of client info description James Prestwood
2024-02-29 20:36 ` [PATCH 1/5] auto-t: end process_io on HUP signal, detect process crash Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240229170734.1498918-2-prestwoj@gmail.com \
    --to=prestwoj@gmail.com \
    --cc=alex@supernetworks.org \
    --cc=iwd@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox