[PATCH BlueZ v2 03/10] unit/test-eir: Add tests for the longest local names

Luiz Augusto von Dentz <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth
Message-ID <[email protected]>
From: Luiz Augusto von Dentz <[email protected]>

Nothing covered a name anywhere near the size of the buffer it is copied
into, which is why the missing clamp went unnoticed.

Add two tests. The first uses a name of HCI_MAX_NAME_LENGTH bytes, the
longest one that fits, to pin the boundary down.

The second uses a name of 253 bytes, as large as eir_parse() can be
handed given the EIR length is a single byte, and which does not fit.
Run against the code before the previous patch, it dies with

  *** buffer overflow detected ***: terminated

Assisted-by: Claude:claude-opus-5
---
 unit/test-eir.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/unit/test-eir.c b/unit/test-eir.c
index 62164ca993f6..326bc899e251 100644
--- a/unit/test-eir.c
+++ b/unit/test-eir.c
@@ -440,6 +440,64 @@ static const struct test_data iso_2022_jp_name_test = {
 	.tx_power = 127,
 };
 
+/*
+ * A complete local name of HCI_MAX_NAME_LENGTH bytes, the longest one that
+ * fits the buffer eir_parse() copies the name into.
+ */
+static unsigned char max_name_data[HCI_MAX_NAME_LENGTH + 2];
+static char max_name[HCI_MAX_NAME_LENGTH + 1];
+
+static const struct test_data max_name_test = {
+	.eir_data = max_name_data,
+	.eir_size = sizeof(max_name_data),
+	.name = max_name,
+	.name_complete = true,
+	.tx_power = 127,
+};
+
+static void max_name_setup(const void *data)
+{
+	max_name_data[0] = sizeof(max_name_data) - 1;
+	max_name_data[1] = EIR_NAME_COMPLETE;
+	memset(max_name_data + 2, 'A', HCI_MAX_NAME_LENGTH);
+
+	memset(max_name, 'A', HCI_MAX_NAME_LENGTH);
+	max_name[HCI_MAX_NAME_LENGTH] = '\0';
+
+	tester_setup_complete();
+}
+
+/*
+ * The longest complete local name eir_parse() can be handed at all, which is
+ * bounded by the EIR length being a single byte. That is 253 bytes, more than
+ * the buffer it is copied into, so this used to overflow it.
+ */
+static unsigned char long_name_data[255];
+static char long_name[sizeof(long_name_data) - 2 + 1];
+
+/* The name does not fit, so it comes back clamped to HCI_MAX_NAME_LENGTH */
+#define LONG_NAME_LEN	HCI_MAX_NAME_LENGTH
+
+static const struct test_data long_name_test = {
+	.eir_data = long_name_data,
+	.eir_size = sizeof(long_name_data),
+	.name = long_name,
+	.name_complete = true,
+	.tx_power = 127,
+};
+
+static void long_name_setup(const void *data)
+{
+	long_name_data[0] = sizeof(long_name_data) - 1;
+	long_name_data[1] = EIR_NAME_COMPLETE;
+	memset(long_name_data + 2, 'B', sizeof(long_name_data) - 2);
+
+	memset(long_name, 'B', LONG_NAME_LEN);
+	long_name[LONG_NAME_LEN] = '\0';
+
+	tester_setup_complete();
+}
+
 static const unsigned char bluesc_data[] = {
 		0x02, 0x01, 0x06, 0x03, 0x02, 0x16, 0x18, 0x12,
 		0x09, 0x57, 0x61, 0x68, 0x6f, 0x6f, 0x20, 0x42,
@@ -756,6 +814,10 @@ int main(int argc, char *argv[])
 									NULL);
 	tester_add("/eir/iso-2022-jp-name", &iso_2022_jp_name_test, NULL,
 							test_parsing, NULL);
+	tester_add("/eir/max-name", &max_name_test, max_name_setup,
+							test_parsing, NULL);
+	tester_add("/eir/long-name", &long_name_test, long_name_setup,
+							test_parsing, NULL);
 	tester_add("/ad/bluesc", &bluesc_test, NULL, test_parsing, NULL);
 	tester_add("/ad/wahooscale", &wahoo_scale_test, NULL, test_parsing,
 									NULL);
-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.