[NAN] Add (T)LV validation testing
Test for validity of a (T)LV. Used in construction of publish and
subscribe configuration (both Tx and Rx filters).
Bug: 30007730
Change-Id: Ibf2179121d45c582bb054c06ec2a765ed0927040
(cherry picked from commit c13b9f6b7d132e06e09b8604b095bdf59ec42307)
diff --git a/wifi/java/android/net/wifi/nan/PublishConfig.java b/wifi/java/android/net/wifi/nan/PublishConfig.java
index 96d257c..a4969bd 100644
--- a/wifi/java/android/net/wifi/nan/PublishConfig.java
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.java
@@ -300,10 +300,18 @@
throw new IllegalArgumentException(
"Non-matching combination of txFilter and txFilterLength");
}
+ if (!TlvBufferUtils.isValid(mTxFilter, mTxFilterLength, 0, 1)) {
+ throw new IllegalArgumentException(
+ "Invalid txFilter configuration - LV fields do not match up to length");
+ }
if (mRxFilterLength != 0 && (mRxFilter == null || mRxFilter.length < mRxFilterLength)) {
throw new IllegalArgumentException(
"Non-matching combination of rxFilter and rxFilterLength");
}
+ if (!TlvBufferUtils.isValid(mRxFilter, mRxFilterLength, 0, 1)) {
+ throw new IllegalArgumentException(
+ "Invalid rxFilter configuration - LV fields do not match up to length");
+ }
if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) {
throw new IllegalArgumentException("Invalid publishType - " + mPublishType);
}
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.java b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
index 3133d3e..0d3ea01 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
@@ -327,10 +327,18 @@
throw new IllegalArgumentException(
"Non-matching combination of txFilter and txFilterLength");
}
+ if (!TlvBufferUtils.isValid(mTxFilter, mTxFilterLength, 0, 1)) {
+ throw new IllegalArgumentException(
+ "Invalid txFilter configuration - LV fields do not match up to length");
+ }
if (mRxFilterLength != 0 && (mRxFilter == null || mRxFilter.length < mRxFilterLength)) {
throw new IllegalArgumentException(
"Non-matching combination of rxFilter and rxFilterLength");
}
+ if (!TlvBufferUtils.isValid(mRxFilter, mRxFilterLength, 0, 1)) {
+ throw new IllegalArgumentException(
+ "Invalid rxFilter configuration - LV fields do not match up to length");
+ }
if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) {
throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType);
}
diff --git a/wifi/java/android/net/wifi/nan/TlvBufferUtils.java b/wifi/java/android/net/wifi/nan/TlvBufferUtils.java
index fa1dcf1..da7ecd8 100644
--- a/wifi/java/android/net/wifi/nan/TlvBufferUtils.java
+++ b/wifi/java/android/net/wifi/nan/TlvBufferUtils.java
@@ -488,4 +488,43 @@
};
}
}
+
+ /**
+ * Validates that a (T)LV array is constructed correctly. I.e. that its specified Length
+ * fields correctly fill the specified length (and do not overshoot).
+ *
+ * @param array The (T)LV array to verify.
+ * @param length The number of bytes in the array to consider (starting at offset 0).
+ * @param typeSize The size (in bytes) of the type field. Valid values are 0, 1, or 2.
+ * @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
+ * @return A boolean indicating whether the array is valid (true) or invalid (false).
+ */
+ public static boolean isValid(byte[] array, int length, int typeSize, int lengthSize) {
+ if (typeSize < 0 || typeSize > 2) {
+ throw new IllegalArgumentException(
+ "Invalid arguments - typeSize must be 0, 1, or 2: typeSize=" + typeSize);
+ }
+ if (lengthSize <= 0 || lengthSize > 2) {
+ throw new IllegalArgumentException(
+ "Invalid arguments - lengthSize must be 1 or 2: lengthSize=" + lengthSize);
+ }
+ if (length < 0 || length > array.length) {
+ throw new IllegalArgumentException(
+ "Invalid arguments - length must be non-negative and <= array.length: length="
+ + length + ", array.length=" + array.length);
+ }
+
+ int nextTlvIndex = 0;
+ while (nextTlvIndex + typeSize + lengthSize <= length) {
+ nextTlvIndex += typeSize;
+ if (lengthSize == 1) {
+ nextTlvIndex += lengthSize + array[nextTlvIndex];
+ } else {
+ nextTlvIndex += lengthSize + Memory.peekShort(array, nextTlvIndex,
+ ByteOrder.BIG_ENDIAN);
+ }
+ }
+
+ return nextTlvIndex == length;
+ }
}