Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157268925
D49575.id152857.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D49575.id152857.diff
View Options
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -2732,3 +2732,40 @@
*/
return (!ieee80211_is_key_global(vap, key));
}
+
+/**
+ * Determine whether the given control frame is from a known node
+ * and destined to us.
+ *
+ * In some instances a control frame won't have a TA (eg ACKs), so
+ * we should only verify the RA for those.
+ *
+ * @param ni ieee80211_node representing the sender, or BSS node
+ * @param m0 mbuf representing the 802.11 frame.
+ * @returns true if the frame is not a CTL frame (but with a warning
+ * logged);
+ * true if the frame is from a known sender / valid recipient,
+ * false otherwise.
+ */
+bool
+ieee80211_is_ctl_frame_for_vap(struct ieee80211_node *ni, const struct mbuf *m0)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ifnet *ifp = vap->iv_ifp;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m0, const struct ieee80211_frame *);
+
+ /* Verify it's a ctl frame. */
+ if (!IEEE80211_IS_CTL(wh)) {
+ if_printf(vap->iv_ifp,
+ "%s: not a control frame (fc[0]=0x%04x)\n",
+ __func__, (wh)->i_fc[0]);
+ return (true);
+ }
+
+ /* TODO: verify the TA if the frame format has a TA */
+
+ /* Verify the RA */
+ return (IEEE80211_ADDR_EQ(wh->i_addr1, IF_LLADDR(ifp)));
+}
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -1047,6 +1047,16 @@
static void
adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BAR:
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -2418,6 +2418,17 @@
static void
hostap_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_PS_POLL:
ni->ni_vap->iv_recv_pspoll(ni, m);
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -2089,6 +2089,17 @@
static void
mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BAR:
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -2054,6 +2054,17 @@
static void
sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BAR:
ieee80211_recv_bar(ni, m);
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -842,6 +842,9 @@
bool ieee80211_is_key_unicast(const struct ieee80211vap *vap,
const struct ieee80211_key *key);
+bool ieee80211_is_ctl_frame_for_vap(struct ieee80211_node *,
+ const struct mbuf *);
+
void ieee80211_radiotap_attach(struct ieee80211com *,
struct ieee80211_radiotap_header *th, int tlen,
uint32_t tx_radiotap,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, May 20, 9:42 PM (11 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33358008
Default Alt Text
D49575.id152857.diff (4 KB)
Attached To
Mode
D49575: net80211: validate control frame TA/RA before further processing
Attached
Detach File
Event Timeline
Log In to Comment