From 7e88b2569b5cb228925652fe95b15e498cc683df Mon Sep 17 00:00:00 2001
From: Anjan Chanda <anjan.chanda@iopsys.eu>
Date: Mon, 3 Feb 2025 21:21:26 +0100
Subject: [PATCH] easymesh: cmduchecker: validate vendor specific cmdu

---
 src/extensions/map/cmduchecker.c | 14 ++++++++++++++
 src/extensions/map/r1.c          |  7 ++++++-
 src/extensions/map/r2.c          |  7 ++++++-
 src/extensions/map/r3.c          |  7 ++++++-
 src/extensions/map/r4.c          |  7 ++++++-
 src/extensions/map/r6.c          |  7 ++++++-
 src/extensions/map/tlv_checker.c |  9 +++++++++
 src/extensions/map/tlv_checker.h |  1 +
 8 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/src/extensions/map/cmduchecker.c b/src/extensions/map/cmduchecker.c
index 51cc819a..841095d2 100644
--- a/src/extensions/map/cmduchecker.c
+++ b/src/extensions/map/cmduchecker.c
@@ -224,6 +224,19 @@ bool DEFINE_FUNC(CMDU_TYPE_TOPOLOGY_RESPONSE)(struct cmdu_buff *cmdu,
 	return true;
 }
 
+bool DEFINE_FUNC(CMDU_TYPE_VENDOR_SPECIFIC)(struct cmdu_buff *cmdu,
+					    struct tlv *tv[][TLV_MAXNUM],
+					    size_t num_tv,
+					    uint8_t profile)
+{
+	trace("SA = " MACFMT ", profile = %d\n", MAC2STR(cmdu->origin), profile);
+
+	if (tlv_validate(TLV_TYPE_VENDOR_SPECIFIC, tv[0][0]))
+		return false;
+
+	return true;
+}
+
 enum CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH_ATTRS {
 	AP_CONFIG_SEARCH_ATTR_1905_AL_MACADDR,
 	AP_CONFIG_SEARCH_ATTR_SEARCHED_ROLE,
@@ -683,6 +696,7 @@ bool DEFINE_FUNC(CMDU_EARLY_AP_CAPABILITY_REPORT)(struct cmdu_buff *cmdu,
 struct map_cmdu_validator map_cmdu_validate[] = {
 	FUNC(CMDU_TYPE_TOPOLOGY_NOTIFICATION),
 	FUNC(CMDU_TYPE_TOPOLOGY_RESPONSE),
+	FUNC(CMDU_TYPE_VENDOR_SPECIFIC),
 	FUNC(CMDU_TYPE_AP_AUTOCONFIGURATION_SEARCH),
 	FUNC(CMDU_TYPE_AP_AUTOCONFIGURATION_RESPONSE),
 	FUNC(CMDU_TYPE_AP_AUTOCONFIGURATION_WSC),
diff --git a/src/extensions/map/r1.c b/src/extensions/map/r1.c
index 8cc688ad..29f89b79 100644
--- a/src/extensions/map/r1.c
+++ b/src/extensions/map/r1.c
@@ -76,7 +76,12 @@ DEFINE_POLICY(CMDU_TYPE_TOPOLOGY_RESPONSE) = {
 };
 
 DEFINE_POLICY(CMDU_TYPE_VENDOR_SPECIFIC) = {
-	/* user defined */
+	[0] = {
+		.type = TLV_TYPE_VENDOR_SPECIFIC,
+		.present = TLV_PRESENT_ONE,
+		.minlen = 3,
+	},
+	/* any number and/or type of tlvs may follow */
 };
 
 DEFINE_POLICY(CMDU_TYPE_LINK_METRIC_QUERY) = {
diff --git a/src/extensions/map/r2.c b/src/extensions/map/r2.c
index 3b4a1951..a0cc962f 100644
--- a/src/extensions/map/r2.c
+++ b/src/extensions/map/r2.c
@@ -85,7 +85,12 @@ DEFINE_POLICY(CMDU_TYPE_TOPOLOGY_RESPONSE) = {
 };
 
 DEFINE_POLICY(CMDU_TYPE_VENDOR_SPECIFIC) = {
-	/* user defined */
+	[0] = {
+		.type = TLV_TYPE_VENDOR_SPECIFIC,
+		.present = TLV_PRESENT_ONE,
+		.minlen = 3,
+	},
+	/* any number and/or type of tlvs may follow */
 };
 
 DEFINE_POLICY(CMDU_TYPE_LINK_METRIC_QUERY) = {
diff --git a/src/extensions/map/r3.c b/src/extensions/map/r3.c
index 9f4b90d1..a5d52595 100644
--- a/src/extensions/map/r3.c
+++ b/src/extensions/map/r3.c
@@ -85,7 +85,12 @@ DEFINE_POLICY(CMDU_TYPE_TOPOLOGY_RESPONSE) = {
 };
 
 DEFINE_POLICY(CMDU_TYPE_VENDOR_SPECIFIC) = {
-	/* user defined */
+	[0] = {
+		.type = TLV_TYPE_VENDOR_SPECIFIC,
+		.present = TLV_PRESENT_ONE,
+		.minlen = 3,
+	},
+	/* any number and/or type of tlvs may follow */
 };
 
 DEFINE_POLICY(CMDU_TYPE_LINK_METRIC_QUERY) = {
diff --git a/src/extensions/map/r4.c b/src/extensions/map/r4.c
index 77b3f4f5..2c0cf8d6 100644
--- a/src/extensions/map/r4.c
+++ b/src/extensions/map/r4.c
@@ -85,7 +85,12 @@ DEFINE_POLICY(CMDU_TYPE_TOPOLOGY_RESPONSE) = {
 };
 
 DEFINE_POLICY(CMDU_TYPE_VENDOR_SPECIFIC) = {
-	/* user defined */
+	[0] = {
+		.type = TLV_TYPE_VENDOR_SPECIFIC,
+		.present = TLV_PRESENT_ONE,
+		.minlen = 3,
+	},
+	/* any number and/or type of tlvs may follow */
 };
 
 DEFINE_POLICY(CMDU_TYPE_LINK_METRIC_QUERY) = {
diff --git a/src/extensions/map/r6.c b/src/extensions/map/r6.c
index 5448bbc5..41973409 100644
--- a/src/extensions/map/r6.c
+++ b/src/extensions/map/r6.c
@@ -100,7 +100,12 @@ DEFINE_POLICY(CMDU_TYPE_TOPOLOGY_RESPONSE) = {
 };
 
 DEFINE_POLICY(CMDU_TYPE_VENDOR_SPECIFIC) = {
-	/* user defined */
+	[0] = {
+		.type = TLV_TYPE_VENDOR_SPECIFIC,
+		.present = TLV_PRESENT_ONE,
+		.minlen = 3,
+	},
+	/* any number and/or type of tlvs may follow */
 };
 
 DEFINE_POLICY(CMDU_TYPE_LINK_METRIC_QUERY) = {
diff --git a/src/extensions/map/tlv_checker.c b/src/extensions/map/tlv_checker.c
index 88011ea1..6dd20234 100644
--- a/src/extensions/map/tlv_checker.c
+++ b/src/extensions/map/tlv_checker.c
@@ -74,6 +74,14 @@ int FUNC(TLV_TYPE_WSC)(const uint8_t *data, size_t datalen)
 	return ret;
 }
 
+int FUNC(TLV_TYPE_VENDOR_SPECIFIC)(const uint8_t *data, size_t datalen)
+{
+	if (datalen < 3)	/* atleast oui size */
+		return -1;
+
+	return 0;
+}
+
 int FUNC(MAP_TLV_SUPPORTED_SERVICE)(const uint8_t *data, size_t datalen)
 {
 	uint8_t num_services;
@@ -1909,6 +1917,7 @@ int FUNC(MAP_TLV_EHT_OPERATIONS)(const uint8_t *data, size_t datalen)
 /* List of TLV validators */
 struct tlv_validator tlv_validators[] = {
 	DEFINE_VALIDATOR(TLV_TYPE_WSC),
+	DEFINE_VALIDATOR(TLV_TYPE_VENDOR_SPECIFIC),
 	DEFINE_VALIDATOR(MAP_TLV_SUPPORTED_SERVICE),
 	DEFINE_VALIDATOR(MAP_TLV_SEARCHED_SERVICE),
 	DEFINE_VALIDATOR(MAP_TLV_AP_RADIO_IDENTIFIER),
diff --git a/src/extensions/map/tlv_checker.h b/src/extensions/map/tlv_checker.h
index 784cff8b..4c6335bc 100644
--- a/src/extensions/map/tlv_checker.h
+++ b/src/extensions/map/tlv_checker.h
@@ -16,6 +16,7 @@
 #define DECL(t)	int validate_ ## t(const uint8_t *data, size_t datalen)
 
 DECL(TLV_TYPE_WSC);
+DECL(TLV_TYPE_VENDOR_SPECIFIC);
 
 DECL(MAP_TLV_SUPPORTED_SERVICE);
 DECL(MAP_TLV_SEARCHED_SERVICE);
-- 
GitLab