Abort parsing in case of format error
Usecase:
1. Enable hf client and connect to AG.
2. Send +COPS with length more than allowed 16 characters.
Failure:
Crash might be seen while parsing +COPS response from AG.
Root cause:
sscanf used for parsing the AT commands does not update
the characters scanned when there is format error.
Fix:
Abort the processing in case of format error.
Change-Id: Id3ca80712df3d0251cf9ffb04d9c766be809ae84
diff --git a/bta/hf_client/bta_hf_client_at.c b/bta/hf_client/bta_hf_client_at.c
index 3eafa23..610bc88 100644
--- a/bta/hf_client/bta_hf_client_at.c
+++ b/bta/hf_client/bta_hf_client_at.c
@@ -692,7 +692,7 @@
static char *bta_hf_client_parse_cind_list(char *buffer)
{
- int offset;
+ int offset = 0;
char name[129];
UINT32 min, max;
UINT32 index = 0;
@@ -701,6 +701,12 @@
while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min, &max, &offset)) > 2)
{
bta_hf_client_handle_cind_list_item(name, min, max, index);
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
index++;
@@ -808,7 +814,7 @@
{
UINT32 index, value;
int res;
- int offset;
+ int offset = 0;
AT_CHECK_EVENT(buffer, "+CIEV:");
@@ -818,6 +824,12 @@
return NULL;
}
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
AT_CHECK_RN(buffer);
@@ -888,7 +900,7 @@
char number[33];
UINT32 type = 0;
int res;
- int offset;
+ int offset = 0;
AT_CHECK_EVENT(buffer, "+CLIP:");
@@ -899,6 +911,12 @@
return NULL;
}
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
AT_SKIP_REST(buffer);
@@ -916,7 +934,7 @@
char number[33];
UINT32 type = 0;
int res ;
- int offset;
+ int offset = 0;
AT_CHECK_EVENT(buffer, "+CCWA:");
@@ -927,6 +945,12 @@
return NULL;
}
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
AT_SKIP_REST(buffer);
@@ -953,6 +977,12 @@
{
return NULL;
}
+ /* Abort in case offset not set because of format error */
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
buffer += offset;
@@ -970,7 +1000,7 @@
/* phone number is 32 chars plus one for \0*/
char numstr[33];
int res;
- int offset;
+ int offset = 0;
AT_CHECK_EVENT(buffer, "+BINP:");
@@ -980,6 +1010,13 @@
return NULL;
}
+ /* Abort in case offset not set because of format error */
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
/* some phones might sent type as well, just skip it */
@@ -997,7 +1034,7 @@
char numstr[33]; /* spec forces 32 chars, plus one for \0*/
UINT16 type;
int res;
- int offset;
+ int offset = 0;
AT_CHECK_EVENT(buffer, "+CLCC:");
@@ -1008,7 +1045,15 @@
return NULL;
}
+ /* Abort in case offset not set because of format error */
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
+ offset = 0;
/* check optional part */
if (*buffer == ',')
@@ -1031,6 +1076,13 @@
if (res2 >= 2)
{
res += res2;
+ /* Abort in case offset not set because of format error */
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
}
}
@@ -1059,7 +1111,7 @@
UINT16 type;
UINT16 service = 0; /* 0 in case this optional parameter is not being sent */
int res;
- int offset;
+ int offset = 0;
AT_CHECK_EVENT(buffer, "+CNUM:");
@@ -1087,6 +1139,13 @@
return NULL;
}
+ /* Abort in case offset not set because of format error */
+ if (offset == 0)
+ {
+ APPL_TRACE_ERROR("%s: Format Error %s", __func__, buffer);
+ return NULL;
+ }
+
buffer += offset;
AT_CHECK_RN(buffer);
@@ -1431,6 +1490,11 @@
APPL_TRACE_DEBUG("%s", __FUNCTION__);
at_len = snprintf(buf, sizeof(buf), "AT+BRSF=%u\r", bta_hf_client_cb.scb.features);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
bta_hf_client_send_at(BTA_HF_CLIENT_AT_BRSF , buf, at_len);
}
@@ -1461,6 +1525,11 @@
APPL_TRACE_DEBUG("%s", __FUNCTION__);
at_len = snprintf(buf, sizeof(buf), "AT+BCS=%u\r", codec);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
bta_hf_client_send_at(BTA_HF_CLIENT_AT_BCS, buf, at_len);
}
@@ -1512,6 +1581,12 @@
else
at_len = snprintf(buf, sizeof(buf), "AT+CHLD=%c\r", cmd);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
+
bta_hf_client_send_at(BTA_HF_CLIENT_AT_CHLD, buf, at_len);
}
@@ -1605,6 +1680,11 @@
APPL_TRACE_DEBUG("%s", __FUNCTION__);
at_len = snprintf(buf, sizeof(buf), "AT+VGS=%u\r", volume);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
bta_hf_client_send_at(BTA_HF_CLIENT_AT_VGS, buf, at_len);
}
@@ -1617,6 +1697,11 @@
APPL_TRACE_DEBUG("%s", __FUNCTION__);
at_len = snprintf(buf, sizeof(buf), "AT+VGM=%u\r", volume);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
bta_hf_client_send_at(BTA_HF_CLIENT_AT_VGM, buf, at_len);
}
@@ -1633,13 +1718,19 @@
} else {
at_len = snprintf(buf, sizeof(buf), "ATD>%u;\r", memory);
}
+
if (at_len < 0) {
- APPL_TRACE_ERROR("%s: error preparing ATD command");
+ APPL_TRACE_ERROR("%s: error preparing ATD command", __func__);
return;
}
at_len = MIN((size_t)at_len, sizeof(buf));
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
bta_hf_client_send_at(BTA_HF_CLIENT_AT_ATD, buf, at_len);
}
@@ -1692,6 +1783,12 @@
at_len = snprintf(buf, sizeof(buf), "AT+BTRH=%u\r", val);
}
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
+
bta_hf_client_send_at(BTA_HF_CLIENT_AT_BTRH, buf, at_len);
}
@@ -1704,6 +1801,12 @@
at_len = snprintf(buf, sizeof(buf), "AT+VTS=%c\r", code);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
+
bta_hf_client_send_at(BTA_HF_CLIENT_AT_VTS, buf, at_len);
}
@@ -1755,6 +1858,12 @@
at_len = snprintf(buf, sizeof(buf), "AT+BINP=%u\r", action);
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
+
bta_hf_client_send_at(BTA_HF_CLIENT_AT_BINP, buf, at_len);
}
@@ -1782,6 +1891,12 @@
buf[at_len - 1] = '\r';
+ if (at_len < 0)
+ {
+ APPL_TRACE_ERROR("%s: AT command Framing error", __func__);
+ return;
+ }
+
bta_hf_client_send_at(BTA_HF_CLIENT_AT_BIA, buf, at_len);
}