[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