-
Notifications
You must be signed in to change notification settings - Fork 15
Open
Description
libwifi_remove_tag implementation is incorrect and causes various corruption or bug.
Here is a proof of concept that shows the various issues:
test_libwifi_remove_tag.c.txt
-
deleting the last tag, gives an error:
$ ./test_libwifi_remove_tag remove_last removing Vendor tag; tags length: 168, expected new tag length: 142 mremap_chunk(): invalid pointer Abandon (core dumped) -
deleting the ssid tag, gives a corruption:
$ ./test_libwifi_remove_tag remove_ssid removing ssid tag; tags length: 168, expected new tag length: 154 new probe_resp.tags.length: 165 -
delting and adding back the same tag does not give a consitent tags length over all:
$ ./test_libwifi_remove_tag removing HT_OPERATION tag; tags length: 168, expected new tag length: 144 new probe_resp.tags.length: 2 adding back the same HT_OPERATION tag; tags length: 2, expected new tag length: 26 probe_resp.tags.length: 26
I think, there are 3 issues in the code of libwifi_remove_tag:
- line 70, memcpy is copying the remaining data over the first half of the tag data, corrupting them in the process.
The data should be copied not totags->parameterspointer aka the start of all the data tags, but toit.tag_data - sizeof(struct libwifi_tag_header)aka the start of the current tag. - still using the
itpointer after memcpy returns data that are not the ones expected. hence, new_len should be defined before the memcpy instruction. - copy_len is too big (which gives the error when removing the last tag). it should not contain
sizeof(struct libwifi_tag_header)
So I think that the following patch should be used to fix that:
--- src/libwifi/core/frame/tag.c 2024-11-11 19:22:36.381371022 +0100
+++ src/libwifi/core/frame/tag.c.new 2024-11-11 19:22:19.324833442 +0100
@@ -66,9 +66,9 @@
// how many bytes to shrink the tagged parameter list by
size_t copy_len = tags->length -
(it.tag_data - tags->parameters) -
- (it.tag_header->tag_len + sizeof(struct libwifi_tag_header));
+ it.tag_header->tag_len;
- memcpy(tags->parameters, it.tag_data + it.tag_header->tag_len, copy_len);
size_t new_len = tags->length - it.tag_header->tag_len - sizeof(struct libwifi_tag_header);
+ memcpy((unsigned char *)it.tag_data - sizeof(struct libwifi_tag_header), it.tag_data + it.tag_header->tag_len, copy_len);
tags->parameters = realloc(tags->parameters, new_len);
tags->length = new_len;
break;At least the code of concept above test_libwifi_remove_tag gives no error and the expected output when compiled against a libwifi compiled with the patch
Metadata
Metadata
Assignees
Labels
No labels