[PATCH 06/18] NAN: Validate the NDC carried in an accepted response

Andrei Otcheretianski andrei.otcheretianski at intel.com
Mon Oct 12 08:46:40 PDT 2026


Table 16 in the Wi-Fi Aware Specification v4.0 only lets the responder
select the NDC when the Initial Proposal did not carry one. If the
request proposed an NDC, an accepted response has to carry the very
same one; a responder that wants a different NDC has to counter
instead.

Nothing verified this, so a response that accepted the NDL while
silently replacing the proposed NDC was taken as an agreement on an
NDC the local device never asked for.

No legitimate negotiation can lead to such a response, so drop it the
same way an invalid frame is dropped. A "Continued" one is left alone,
as a counter proposal may select any NDC.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/nan/nan_ndl.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index 69abcd82de..c6ed6aa5c1 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -1057,9 +1057,10 @@ nan_ndl_local_ndc_chan(struct nan_data *nan, const struct nan_ndl *ndl)
 
 
 /*
- * Table 18 in the Wi-Fi Aware Specification v4.0 requires the NDC carried in a
- * Confirm to be the same one that was proposed in the Response, so compare it
- * against the NDC that was last transmitted to the peer.
+ * Table 16 in the Wi-Fi Aware Specification v4.0 only lets the responder pick
+ * the NDC when the request carried none, and Table 18 requires the NDC in a
+ * Confirm to be the one proposed in the Response. Both cases compare against
+ * the NDC that was last transmitted to the peer.
  */
 static bool nan_ndl_ndc_matches_proposed(struct nan_data *nan,
 					 struct nan_peer *peer,
@@ -1182,16 +1183,33 @@ static int nan_ndl_attr_handle_resp(struct nan_data *nan, struct nan_peer *peer,
 	}
 
 	if (os_memcmp(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id)) != 0) {
+		if (params->status == NAN_NDL_STATUS_ACCEPTED &&
+		    ndl->local_ndc.len) {
+			wpa_printf(MSG_DEBUG,
+				   "NAN: NDL: Resp: NDC ID differs from the proposed one");
+			return -1;
+		}
+
 		wpa_printf(MSG_DEBUG, "NAN: NDL: Resp: ndc_id changed");
 		os_memcpy(ndl->ndc_id, params->ndc_id, sizeof(ndl->ndc_id));
 	}
 
+	if (params->status == NAN_NDL_STATUS_ACCEPTED &&
+	    !nan_ndl_ndc_matches_proposed(nan, peer, params->ndc_sched,
+					  params->ndc_sched_len)) {
+		wpa_printf(MSG_DEBUG,
+			   "NAN: NDL: Resp: NDC differs from the proposed one");
+		return -1;
+	}
+
 	ndl->max_idle_period = params->max_idle_period;
 	ndl->peer_qos.min_slots = params->min_slots;
 	ndl->peer_qos.max_latency = params->max_latency;
 
-	/* TODO: validate that in case an ACCEPTED NDL and an NDC, the NDC
-	 * schedule is covered by the local device committed availability.
+	/*
+	 * TODO: When the request carried no NDC the responder selects it, and
+	 * the selection is still not validated against the local committed
+	 * availability.
 	 */
 	if (params->ndc_sched && params->ndc_sched_len) {
 		os_free(ndl->ndc_sched);
-- 
2.53.0




More information about the Hostap mailing list