diff options
| author | Marc <foxtrot@malloc.me> | 2022-01-12 22:19:01 +0000 |
|---|---|---|
| committer | Marc <foxtrot@malloc.me> | 2022-01-12 22:19:01 +0000 |
| commit | 2057ed8028b4a5c951ed5b6005c5088890c1e689 (patch) | |
| tree | 5e5f8090c317af898161966a442b2473d2086a67 | |
| parent | fe955af4811c73768f77ef9471550648df0b8ec8 (diff) | |
| download | libwifi-2057ed8028b4a5c951ed5b6005c5088890c1e689.tar.gz libwifi-2057ed8028b4a5c951ed5b6005c5088890c1e689.tar.bz2 libwifi-2057ed8028b4a5c951ed5b6005c5088890c1e689.zip | |
parse: Check frame minimum length when parsing Radiotap header
| -rw-r--r-- | src/libwifi/core/frame/frame.c | 2 | ||||
| -rw-r--r-- | src/libwifi/parse/misc/radiotap.c | 9 | ||||
| -rw-r--r-- | src/libwifi/parse/misc/radiotap.h | 7 | ||||
| -rw-r--r-- | utils/src/test_parsing.c | 22 |
4 files changed, 25 insertions, 15 deletions
| diff --git a/src/libwifi/core/frame/frame.c b/src/libwifi/core/frame/frame.c index b4f50ad..78fe069 100644 --- a/src/libwifi/core/frame/frame.c +++ b/src/libwifi/core/frame/frame.c | |||
| @@ -42,7 +42,7 @@ int libwifi_get_wifi_frame(struct libwifi_frame *fi, const unsigned char *frame, | |||
| 42 | 42 | ||
| 43 | if (radiotap) { | 43 | if (radiotap) { |
| 44 | struct libwifi_radiotap_info rtap_info = {0}; | 44 | struct libwifi_radiotap_info rtap_info = {0}; |
| 45 | libwifi_parse_radiotap_info(&rtap_info, frame_data); | 45 | libwifi_parse_radiotap_info(&rtap_info, frame_data, frame_len); |
| 46 | 46 | ||
| 47 | // Skip forward by the length of the radiotap header | 47 | // Skip forward by the length of the radiotap header |
| 48 | frame_data_len -= rtap_info.length; | 48 | frame_data_len -= rtap_info.length; |
| diff --git a/src/libwifi/parse/misc/radiotap.c b/src/libwifi/parse/misc/radiotap.c index 176167e..80ddced 100644 --- a/src/libwifi/parse/misc/radiotap.c +++ b/src/libwifi/parse/misc/radiotap.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "radiotap.h" | 16 | #include "radiotap.h" |
| 17 | #include "../../core/radiotap/radiotap_iter.h" | 17 | #include "../../core/radiotap/radiotap_iter.h" |
| 18 | 18 | ||
| 19 | #include <errno.h> | ||
| 19 | #include <endian.h> | 20 | #include <endian.h> |
| 20 | #include <stdint.h> | 21 | #include <stdint.h> |
| 21 | 22 | ||
| @@ -23,9 +24,13 @@ | |||
| 23 | * The libwifi radiotap parser uses the usual ieee80211_radiotap_iterator to parse incoming | 24 | * The libwifi radiotap parser uses the usual ieee80211_radiotap_iterator to parse incoming |
| 24 | * radiotap headers into a consumable libwifi_radiotap_info struct. | 25 | * radiotap headers into a consumable libwifi_radiotap_info struct. |
| 25 | */ | 26 | */ |
| 26 | void libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame) { | 27 | int libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame, size_t frame_len) { |
| 27 | memset(info, 0, sizeof(struct libwifi_radiotap_info)); | 28 | memset(info, 0, sizeof(struct libwifi_radiotap_info)); |
| 28 | 29 | ||
| 30 | if (frame_len < sizeof(struct ieee80211_radiotap_header)) { | ||
| 31 | return -EINVAL; | ||
| 32 | } | ||
| 33 | |||
| 29 | struct ieee80211_radiotap_header *rh = (struct ieee80211_radiotap_header *) frame; | 34 | struct ieee80211_radiotap_header *rh = (struct ieee80211_radiotap_header *) frame; |
| 30 | struct ieee80211_radiotap_iterator it = {0}; | 35 | struct ieee80211_radiotap_iterator it = {0}; |
| 31 | int ret = ieee80211_radiotap_iterator_init(&it, (void *) frame, rh->it_len, NULL); | 36 | int ret = ieee80211_radiotap_iterator_init(&it, (void *) frame, rh->it_len, NULL); |
| @@ -99,6 +104,8 @@ void libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsig | |||
| 99 | 104 | ||
| 100 | ret = ieee80211_radiotap_iterator_next(&it); | 105 | ret = ieee80211_radiotap_iterator_next(&it); |
| 101 | } | 106 | } |
| 107 | |||
| 108 | return 0; | ||
| 102 | } | 109 | } |
| 103 | 110 | ||
| 104 | /** | 111 | /** |
| diff --git a/src/libwifi/parse/misc/radiotap.h b/src/libwifi/parse/misc/radiotap.h index 8f74e6a..d57a760 100644 --- a/src/libwifi/parse/misc/radiotap.h +++ b/src/libwifi/parse/misc/radiotap.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #define LIBWIFI_PARSE_RADIOTAP_H | 17 | #define LIBWIFI_PARSE_RADIOTAP_H |
| 18 | 18 | ||
| 19 | #include "../../core/misc/radiotap.h" | 19 | #include "../../core/misc/radiotap.h" |
| 20 | #include <stddef.h> | ||
| 20 | #include <stdint.h> | 21 | #include <stdint.h> |
| 21 | 22 | ||
| 22 | /** | 23 | /** |
| @@ -25,8 +26,10 @@ | |||
| 25 | * | 26 | * |
| 26 | * @param info A libwifi_radiotap_info | 27 | * @param info A libwifi_radiotap_info |
| 27 | * @param frame A raw 802.11 frame | 28 | * @param frame A raw 802.11 frame |
| 28 | */ | 29 | * @param frame_len Length of the given 802.11 frame |
| 29 | void libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame); | 30 | * @returns Negative errno on error, 0 on success |
| 31 | */ | ||
| 32 | int libwifi_parse_radiotap_info(struct libwifi_radiotap_info *info, const unsigned char *frame, size_t frame_len); | ||
| 30 | 33 | ||
| 31 | /** | 34 | /** |
| 32 | * Retrieve the signal strength from a raw frame via radiotap header. | 35 | * Retrieve the signal strength from a raw frame via radiotap header. |
| diff --git a/utils/src/test_parsing.c b/utils/src/test_parsing.c index 293fbb0..339816e 100644 --- a/utils/src/test_parsing.c +++ b/utils/src/test_parsing.c | |||
| @@ -132,9 +132,9 @@ void print_tag_info(unsigned char *data, size_t data_len) { | |||
| 132 | } while (libwifi_tag_iterator_next(&it) != -1); | 132 | } while (libwifi_tag_iterator_next(&it) != -1); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | void parse_radiotap(const unsigned char *packet) { | 135 | void parse_radiotap(const unsigned char *packet, size_t packet_len) { |
| 136 | struct libwifi_radiotap_info rtap_info; | 136 | struct libwifi_radiotap_info rtap_info; |
| 137 | libwifi_parse_radiotap_info(&rtap_info, packet); | 137 | libwifi_parse_radiotap_info(&rtap_info, packet, packet_len); |
| 138 | 138 | ||
| 139 | printf("=== Radiotap Parsing ===\n"); | 139 | printf("=== Radiotap Parsing ===\n"); |
| 140 | printf("Radiotap Channel: %d\n", rtap_info.channel.freq); | 140 | printf("Radiotap Channel: %d\n", rtap_info.channel.freq); |
| @@ -166,7 +166,7 @@ void parse_beacon(struct libwifi_frame frame, unsigned char *args, const struct | |||
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | if (got_radiotap && parse_radiotap_header) { | 168 | if (got_radiotap && parse_radiotap_header) { |
| 169 | parse_radiotap(packet); | 169 | parse_radiotap(packet, header->caplen); |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | print_bss_info(&bss); | 172 | print_bss_info(&bss); |
| @@ -184,7 +184,7 @@ void parse_probe_request(struct libwifi_frame frame, unsigned char *args, const | |||
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | if (got_radiotap && parse_radiotap_header) { | 186 | if (got_radiotap && parse_radiotap_header) { |
| 187 | parse_radiotap(packet); | 187 | parse_radiotap(packet, header->caplen); |
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | print_sta_info(&sta); | 190 | print_sta_info(&sta); |
| @@ -201,7 +201,7 @@ void parse_probe_response(struct libwifi_frame frame, unsigned char *args, const | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | if (got_radiotap && parse_radiotap_header) { | 203 | if (got_radiotap && parse_radiotap_header) { |
| 204 | parse_radiotap(packet); | 204 | parse_radiotap(packet, header->caplen); |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | print_bss_info(&bss); | 207 | print_bss_info(&bss); |
| @@ -219,7 +219,7 @@ void parse_deauth(struct libwifi_frame frame, unsigned char *args, const struct | |||
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | if (got_radiotap && parse_radiotap_header) { | 221 | if (got_radiotap && parse_radiotap_header) { |
| 222 | parse_radiotap(packet); | 222 | parse_radiotap(packet, header->caplen); |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | printf("=== Deauthentication Frame ===\n"); | 225 | printf("=== Deauthentication Frame ===\n"); |
| @@ -258,7 +258,7 @@ void parse_disassoc(struct libwifi_frame frame, unsigned char *args, const struc | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | if (got_radiotap && parse_radiotap_header) { | 260 | if (got_radiotap && parse_radiotap_header) { |
| 261 | parse_radiotap(packet); | 261 | parse_radiotap(packet, header->caplen); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | printf("=== Disassociation Frame ===\n"); | 264 | printf("=== Disassociation Frame ===\n"); |
| @@ -296,7 +296,7 @@ void parse_assoc_request(struct libwifi_frame frame, unsigned char *args, const | |||
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | if (got_radiotap && parse_radiotap_header) { | 298 | if (got_radiotap && parse_radiotap_header) { |
| 299 | parse_radiotap(packet); | 299 | parse_radiotap(packet, header->caplen); |
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | print_sta_info(&sta); | 302 | print_sta_info(&sta); |
| @@ -313,7 +313,7 @@ void parse_assoc_response(struct libwifi_frame frame, unsigned char *args, const | |||
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | if (got_radiotap && parse_radiotap_header) { | 315 | if (got_radiotap && parse_radiotap_header) { |
| 316 | parse_radiotap(packet); | 316 | parse_radiotap(packet, header->caplen); |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | print_bss_info(&bss); | 319 | print_bss_info(&bss); |
| @@ -330,7 +330,7 @@ void parse_reassoc_request(struct libwifi_frame frame, unsigned char *args, cons | |||
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | if (got_radiotap && parse_radiotap_header) { | 332 | if (got_radiotap && parse_radiotap_header) { |
| 333 | parse_radiotap(packet); | 333 | parse_radiotap(packet, header->caplen); |
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | print_sta_info(&sta); | 336 | print_sta_info(&sta); |
| @@ -347,7 +347,7 @@ void parse_reassoc_response(struct libwifi_frame frame, unsigned char *args, con | |||
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | if (got_radiotap && parse_radiotap_header) { | 349 | if (got_radiotap && parse_radiotap_header) { |
| 350 | parse_radiotap(packet); | 350 | parse_radiotap(packet, header->caplen); |
| 351 | } | 351 | } |
| 352 | 352 | ||
| 353 | print_bss_info(&bss); | 353 | print_bss_info(&bss); |
