system/bt
修订版 | 457d2c4ab906e1166e8b2e19bf4b57dcbfd4b3c8 (tree) |
---|---|
时间 | 2018-11-27 02:19:57 |
作者 | Chienyuan <chienyuanhuang@goog...> |
Commiter | android-build-team Robot |
DO NOT MERGE HFP: Check AT command buffer boundary during parsing
* add p_end parameter to tBTA_AG_AT_CMD_CBACK, bta_ag_at_hsp_cback
* add checks for buffer copy overflow in bta_ag_at_hsp_cback and
* add packet legnth checks with p_end in bta_ag_parse_cmer
* add packet length checks with p_end in bta_ag_parse_bac
Bug: 112860487
Test: manual
Change-Id: I6bbbc2ba29ad025c7d3ba023d8191af6a11c4aa9
(cherry picked from commit 749063afebb8324276a47bdfbf320aa70f94a8ba)
(cherry picked from commit 9cb959d00d33737b399377cfc0f4070081d48f5e)
@@ -58,7 +58,7 @@ const tBTA_SERVICE_MASK bta_ag_svc_mask[BTA_AG_NUM_IDX] = { | ||
58 | 58 | BTA_HSP_SERVICE_MASK, BTA_HFP_SERVICE_MASK}; |
59 | 59 | |
60 | 60 | typedef void (*tBTA_AG_ATCMD_CBACK)(tBTA_AG_SCB* p_scb, uint16_t cmd, |
61 | - uint8_t arg_type, char* p_arg, | |
61 | + uint8_t arg_type, char* p_arg, char* p_end, | |
62 | 62 | int16_t int_arg); |
63 | 63 | |
64 | 64 | const tBTA_AG_ATCMD_CBACK bta_ag_at_cback_tbl[BTA_AG_NUM_IDX] = { |
@@ -26,6 +26,7 @@ | ||
26 | 26 | |
27 | 27 | #include "bt_common.h" |
28 | 28 | #include "bta_ag_at.h" |
29 | +#include "log/log.h" | |
29 | 30 | #include "utl.h" |
30 | 31 | |
31 | 32 | /***************************************************************************** |
@@ -76,7 +77,7 @@ void bta_ag_at_reinit(tBTA_AG_AT_CB* p_cb) { | ||
76 | 77 | * Returns void |
77 | 78 | * |
78 | 79 | *****************************************************************************/ |
79 | -void bta_ag_process_at(tBTA_AG_AT_CB* p_cb) { | |
80 | +void bta_ag_process_at(tBTA_AG_AT_CB* p_cb, char* p_end) { | |
80 | 81 | uint16_t idx; |
81 | 82 | uint8_t arg_type; |
82 | 83 | char* p_arg; |
@@ -92,6 +93,11 @@ void bta_ag_process_at(tBTA_AG_AT_CB* p_cb) { | ||
92 | 93 | if (p_cb->p_at_tbl[idx].p_cmd[0] != 0) { |
93 | 94 | /* start of argument is p + strlen matching command */ |
94 | 95 | p_arg = p_cb->p_cmd_buf + strlen(p_cb->p_at_tbl[idx].p_cmd); |
96 | + if (p_arg > p_end) { | |
97 | + (*p_cb->p_err_cback)(p_cb->p_user, false, NULL); | |
98 | + android_errorWriteLog(0x534e4554, "112860487"); | |
99 | + return; | |
100 | + } | |
95 | 101 | |
96 | 102 | /* if no argument */ |
97 | 103 | if (p_arg[0] == 0) { |
@@ -132,11 +138,11 @@ void bta_ag_process_at(tBTA_AG_AT_CB* p_cb) { | ||
132 | 138 | (*p_cb->p_err_cback)(p_cb->p_user, false, NULL); |
133 | 139 | } else { |
134 | 140 | (*p_cb->p_cmd_cback)(p_cb->p_user, p_cb->p_at_tbl[idx].command_id, |
135 | - arg_type, p_arg, int_arg); | |
141 | + arg_type, p_arg, p_end, int_arg); | |
136 | 142 | } |
137 | 143 | } else { |
138 | 144 | (*p_cb->p_cmd_cback)(p_cb->p_user, p_cb->p_at_tbl[idx].command_id, |
139 | - arg_type, p_arg, int_arg); | |
145 | + arg_type, p_arg, p_end, int_arg); | |
140 | 146 | } |
141 | 147 | } |
142 | 148 | /* else error */ |
@@ -187,8 +193,9 @@ void bta_ag_at_parse(tBTA_AG_AT_CB* p_cb, char* p_buf, uint16_t len) { | ||
187 | 193 | (p_cb->p_cmd_buf[0] == 'A' || p_cb->p_cmd_buf[0] == 'a') && |
188 | 194 | (p_cb->p_cmd_buf[1] == 'T' || p_cb->p_cmd_buf[1] == 't')) { |
189 | 195 | p_save = p_cb->p_cmd_buf; |
196 | + char* p_end = p_cb->p_cmd_buf + p_cb->cmd_pos; | |
190 | 197 | p_cb->p_cmd_buf += 2; |
191 | - bta_ag_process_at(p_cb); | |
198 | + bta_ag_process_at(p_cb, p_end); | |
192 | 199 | p_cb->p_cmd_buf = p_save; |
193 | 200 | } |
194 | 201 |
@@ -55,7 +55,7 @@ typedef struct { | ||
55 | 55 | |
56 | 56 | /* callback function executed when command is parsed */ |
57 | 57 | typedef void(tBTA_AG_AT_CMD_CBACK)(void* p_user, uint16_t command_id, |
58 | - uint8_t arg_type, char* p_arg, | |
58 | + uint8_t arg_type, char* p_arg, char* p_end, | |
59 | 59 | int16_t int_arg); |
60 | 60 | |
61 | 61 | /* callback function executed to send "ERROR" result code */ |
@@ -30,6 +30,7 @@ | ||
30 | 30 | #include "bta_ag_int.h" |
31 | 31 | #include "bta_api.h" |
32 | 32 | #include "bta_sys.h" |
33 | +#include "log/log.h" | |
33 | 34 | #include "osi/include/log.h" |
34 | 35 | #include "osi/include/osi.h" |
35 | 36 | #include "port_api.h" |
@@ -378,23 +379,23 @@ static void bta_ag_send_ind(tBTA_AG_SCB* p_scb, uint16_t id, uint16_t value, | ||
378 | 379 | * Returns true if parsed ok, false otherwise. |
379 | 380 | * |
380 | 381 | ******************************************************************************/ |
381 | -static bool bta_ag_parse_cmer(char* p_s, bool* p_enabled) { | |
382 | +static bool bta_ag_parse_cmer(char* p_s, char* p_end, bool* p_enabled) { | |
382 | 383 | int16_t n[4] = {-1, -1, -1, -1}; |
383 | 384 | int i; |
384 | 385 | char* p; |
385 | 386 | |
386 | - for (i = 0; i < 4; i++) { | |
387 | + for (i = 0; i < 4; i++, p_s = p + 1) { | |
387 | 388 | /* skip to comma delimiter */ |
388 | - for (p = p_s; *p != ',' && *p != 0; p++) | |
389 | + for (p = p_s; p < p_end && *p != ',' && *p != 0; p++) | |
389 | 390 | ; |
390 | 391 | |
391 | 392 | /* get integer value */ |
393 | + if (p > p_end) { | |
394 | + android_errorWriteLog(0x534e4554, "112860487"); | |
395 | + return false; | |
396 | + } | |
392 | 397 | *p = 0; |
393 | 398 | n[i] = utl_str2int(p_s); |
394 | - p_s = p + 1; | |
395 | - if (p_s == 0) { | |
396 | - break; | |
397 | - } | |
398 | 399 | } |
399 | 400 | |
400 | 401 | /* process values */ |
@@ -452,7 +453,8 @@ static uint8_t bta_ag_parse_chld(UNUSED_ATTR tBTA_AG_SCB* p_scb, char* p_s) { | ||
452 | 453 | * Returns Returns bitmap of supported codecs. |
453 | 454 | * |
454 | 455 | ******************************************************************************/ |
455 | -static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s) { | |
456 | +static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s, | |
457 | + char* p_end) { | |
456 | 458 | tBTA_AG_PEER_CODEC retval = BTA_AG_CODEC_NONE; |
457 | 459 | uint16_t uuid_codec; |
458 | 460 | bool cont = false; /* Continue processing */ |
@@ -460,10 +462,14 @@ static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s) { | ||
460 | 462 | |
461 | 463 | while (p_s) { |
462 | 464 | /* skip to comma delimiter */ |
463 | - for (p = p_s; *p != ',' && *p != 0; p++) | |
465 | + for (p = p_s; p < p_end && *p != ',' && *p != 0; p++) | |
464 | 466 | ; |
465 | 467 | |
466 | 468 | /* get integre value */ |
469 | + if (p > p_end) { | |
470 | + android_errorWriteLog(0x534e4554, "112860487"); | |
471 | + break; | |
472 | + } | |
467 | 473 | if (*p != 0) { |
468 | 474 | *p = 0; |
469 | 475 | cont = true; |
@@ -597,7 +603,8 @@ void bta_ag_send_call_inds(tBTA_AG_SCB* p_scb, tBTA_AG_RES result) { | ||
597 | 603 | * |
598 | 604 | ******************************************************************************/ |
599 | 605 | void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id, |
600 | - uint8_t arg_type, char* p_arg, int16_t int_arg) { | |
606 | + uint8_t arg_type, char* p_arg, char* p_end, | |
607 | + int16_t int_arg) { | |
601 | 608 | APPL_TRACE_DEBUG("AT cmd:%d arg_type:%d arg:%d arg:%s", command_id, arg_type, |
602 | 609 | int_arg, p_arg); |
603 | 610 |
@@ -607,6 +614,13 @@ void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t command_id, | ||
607 | 614 | val.hdr.handle = bta_ag_scb_to_idx(p_scb); |
608 | 615 | val.hdr.app_id = p_scb->app_id; |
609 | 616 | val.num = (uint16_t)int_arg; |
617 | + | |
618 | + if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) { | |
619 | + APPL_TRACE_ERROR("%s: p_arg is too long, send error and return", __func__); | |
620 | + bta_ag_send_error(p_scb, BTA_AG_ERR_TEXT_TOO_LONG); | |
621 | + android_errorWriteLog(0x534e4554, "112860487"); | |
622 | + return; | |
623 | + } | |
610 | 624 | strlcpy(val.str, p_arg, sizeof(val.str)); |
611 | 625 | |
612 | 626 | /* call callback with event */ |
@@ -836,7 +850,7 @@ static bool bta_ag_parse_biev_response(tBTA_AG_SCB* p_scb, tBTA_AG_VAL* val) { | ||
836 | 850 | * |
837 | 851 | ******************************************************************************/ |
838 | 852 | void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, |
839 | - char* p_arg, int16_t int_arg) { | |
853 | + char* p_arg, char* p_end, int16_t int_arg) { | |
840 | 854 | tBTA_AG_VAL val; |
841 | 855 | tBTA_AG_SCB* ag_scb; |
842 | 856 | uint32_t i, ind_id; |
@@ -856,6 +870,13 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, | ||
856 | 870 | val.hdr.status = BTA_AG_SUCCESS; |
857 | 871 | val.num = int_arg; |
858 | 872 | val.bd_addr = p_scb->peer_addr; |
873 | + | |
874 | + if ((p_end - p_arg + 1) >= (long)sizeof(val.str)) { | |
875 | + APPL_TRACE_ERROR("%s: p_arg is too long, send error and return", __func__); | |
876 | + bta_ag_send_error(p_scb, BTA_AG_ERR_TEXT_TOO_LONG); | |
877 | + android_errorWriteLog(0x534e4554, "112860487"); | |
878 | + return; | |
879 | + } | |
859 | 880 | strlcpy(val.str, p_arg, sizeof(val.str)); |
860 | 881 | |
861 | 882 | /** |
@@ -1034,7 +1055,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, | ||
1034 | 1055 | |
1035 | 1056 | case BTA_AG_LOCAL_EVT_CMER: |
1036 | 1057 | /* if parsed ok store setting, send OK */ |
1037 | - if (bta_ag_parse_cmer(p_arg, &p_scb->cmer_enabled)) { | |
1058 | + if (bta_ag_parse_cmer(p_arg, p_end, &p_scb->cmer_enabled)) { | |
1038 | 1059 | bta_ag_send_ok(p_scb); |
1039 | 1060 | |
1040 | 1061 | /* if service level conn. not already open and our features and |
@@ -1195,7 +1216,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type, | ||
1195 | 1216 | /* store available codecs from the peer */ |
1196 | 1217 | if ((p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC) && |
1197 | 1218 | (p_scb->features & BTA_AG_FEAT_CODEC)) { |
1198 | - p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg); | |
1219 | + p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg, p_end); | |
1199 | 1220 | p_scb->codec_updated = true; |
1200 | 1221 | |
1201 | 1222 | if (p_scb->peer_codecs & BTA_AG_CODEC_MSBC) { |
@@ -361,9 +361,11 @@ extern void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb, | ||
361 | 361 | |
362 | 362 | /* AT command functions */ |
363 | 363 | extern void bta_ag_at_hsp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, |
364 | - uint8_t arg_type, char* p_arg, int16_t int_arg); | |
364 | + uint8_t arg_type, char* p_arg, char* p_end, | |
365 | + int16_t int_arg); | |
365 | 366 | extern void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, |
366 | - uint8_t arg_type, char* p_arg, int16_t int_arg); | |
367 | + uint8_t arg_type, char* p_arg, char* p_end, | |
368 | + int16_t int_arg); | |
367 | 369 | extern void bta_ag_at_err_cback(tBTA_AG_SCB* p_scb, bool unknown, char* p_arg); |
368 | 370 | extern bool bta_ag_inband_enabled(tBTA_AG_SCB* p_scb); |
369 | 371 | extern void bta_ag_send_call_inds(tBTA_AG_SCB* p_scb, tBTA_AG_RES result); |