Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177587911
D49575.1794804237.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None
D49575.1794804237.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,51 @@
*/
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 false if the frame is not a CTL frame (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)
+{
+ const struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+ uint8_t subtype;
+
+ wh = mtod(m0, const struct ieee80211_frame *);
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ /* Verify it's a ctl frame. */
+ KASSERT(IEEE80211_IS_CTL(wh), ("%s: not a CTL frame (fc[0]=0x%04x)",
+ __func__, wh->i_fc[0]));
+ 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 (false);
+ }
+
+ /* Verify the TA if present. */
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_CTS:
+ case IEEE80211_FC0_SUBTYPE_ACK:
+ /* No TA. */
+ break;
+ default:
+ /* TODO: verify TA */
+ break;
+ }
+
+ /* Verify the RA */
+ return (IEEE80211_ADDR_EQ(wh->i_addr1, IF_LLADDR(vap->iv_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
Mon, Nov 16, 4:43 AM (14 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41760611
Default Alt Text
D49575.1794804237.diff (4 KB)
Attached To
Mode
D49575: net80211: validate control frame TA/RA before further processing
Attached
Detach File
Event Timeline