system/bt
Révision | 84055cd49535723c0cf534bae58b04c3048429b3 (tree) |
---|---|
l'heure | 2018-11-08 04:01:05 |
Auteur | Pavlin Radoslavov <pavlin@goog...> |
Commiter | syphyr |
Check AVRCP data length when parsing inside avrc_ctrl_pars_vendor_rsp()
Bug: 111450417
Test: PoC test program
Change-Id: Idd619e52dc7a2944d0d08af824505580e299c163
(cherry picked from commit 1c14e10cac53d5a5724dcf34c5679ad8819f9442)
(cherry picked from commit f779ebe368d245c0d9ac954cf7b2b102e7da56be)
@@ -28,6 +28,8 @@ | ||
28 | 28 | ** Global data |
29 | 29 | *****************************************************************************/ |
30 | 30 | |
31 | +#define MIN(x, y) ((x) < (y) ? (x) : (y)) | |
32 | + | |
31 | 33 | #if (AVRC_METADATA_INCLUDED == TRUE) |
32 | 34 | |
33 | 35 | /******************************************************************************* |
@@ -107,25 +109,36 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p | ||
107 | 109 | return status; |
108 | 110 | } |
109 | 111 | |
110 | -void avrc_parse_notification_rsp (UINT8 *p_stream, tAVRC_REG_NOTIF_RSP *p_rsp) | |
111 | -{ | |
112 | +tAVRC_STS avrc_parse_notification_rsp(UINT8* p_stream, UINT16 len, | |
113 | + tAVRC_REG_NOTIF_RSP* p_rsp) { | |
114 | + UINT16 min_len = 1; | |
115 | + | |
116 | + if (len < min_len) goto length_error; | |
112 | 117 | BE_STREAM_TO_UINT8(p_rsp->event_id, p_stream); |
113 | 118 | switch (p_rsp->event_id) |
114 | 119 | { |
115 | 120 | case AVRC_EVT_PLAY_STATUS_CHANGE: |
121 | + min_len += 1; | |
122 | + if (len < min_len) goto length_error; | |
116 | 123 | BE_STREAM_TO_UINT8(p_rsp->param.play_status, p_stream); |
117 | 124 | break; |
118 | 125 | |
119 | 126 | case AVRC_EVT_TRACK_CHANGE: |
127 | + min_len += 8; | |
128 | + if (len < min_len) goto length_error; | |
120 | 129 | BE_STREAM_TO_ARRAY(p_stream, p_rsp->param.track, 8); |
121 | 130 | break; |
122 | 131 | |
123 | 132 | case AVRC_EVT_APP_SETTING_CHANGE: |
133 | + min_len += 1; | |
134 | + if (len < min_len) goto length_error; | |
124 | 135 | BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream); |
125 | 136 | if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS) { |
126 | 137 | android_errorWriteLog(0x534e4554, "73782082"); |
127 | 138 | p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS; |
128 | 139 | } |
140 | + min_len += p_rsp->param.player_setting.num_attr * 2; | |
141 | + if (len < min_len) goto length_error; | |
129 | 142 | for (int index = 0; index < p_rsp->param.player_setting.num_attr; index++) |
130 | 143 | { |
131 | 144 | BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index], p_stream); |
@@ -153,6 +166,14 @@ void avrc_parse_notification_rsp (UINT8 *p_stream, tAVRC_REG_NOTIF_RSP *p_rsp) | ||
153 | 166 | default: |
154 | 167 | break; |
155 | 168 | } |
169 | + | |
170 | + return AVRC_STS_NO_ERROR; | |
171 | + | |
172 | +length_error: | |
173 | + android_errorWriteLog(0x534e4554, "111450417"); | |
174 | + AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d", | |
175 | + __func__, len, min_len); | |
176 | + return AVRC_STS_INTERNAL_ERR; | |
156 | 177 | } |
157 | 178 | |
158 | 179 | #if (AVRC_CTLR_INCLUDED == TRUE) |
@@ -170,17 +191,35 @@ void avrc_parse_notification_rsp (UINT8 *p_stream, tAVRC_REG_NOTIF_RSP *p_rsp) | ||
170 | 191 | static tAVRC_STS avrc_ctrl_pars_vendor_rsp( |
171 | 192 | tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result, UINT8* p_buf, UINT16* buf_len) |
172 | 193 | { |
194 | + if (p_msg->vendor_len < 4) | |
195 | + { | |
196 | + android_errorWriteLog(0x534e4554, "111450417"); | |
197 | + AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 4", | |
198 | + __func__, p_msg->vendor_len); | |
199 | + return AVRC_STS_INTERNAL_ERR; | |
200 | + } | |
201 | + | |
173 | 202 | UINT8 *p = p_msg->p_vendor_data; |
174 | 203 | BE_STREAM_TO_UINT8 (p_result->pdu, p); |
175 | 204 | p++; /* skip the reserved/packe_type byte */ |
176 | 205 | |
177 | 206 | UINT16 len; |
207 | + UINT16 min_len = 0; | |
178 | 208 | BE_STREAM_TO_UINT16 (len, p); |
179 | - AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d", | |
180 | - __func__, p_msg->hdr.ctype, p_result->pdu, len); | |
209 | + AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d vendor_len=0x%x", __func__, | |
210 | + p_msg->hdr.ctype, p_result->pdu, len, p_msg->vendor_len); | |
211 | + if (p_msg->vendor_len < len + 4) | |
212 | + { | |
213 | + android_errorWriteLog(0x534e4554, "111450417"); | |
214 | + AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d", | |
215 | + __func__, p_msg->vendor_len, len + 4); | |
216 | + return AVRC_STS_INTERNAL_ERR; | |
217 | + } | |
181 | 218 | /* Todo: Issue in handling reject, check */ |
182 | 219 | if (p_msg->hdr.ctype == AVRC_RSP_REJ) |
183 | 220 | { |
221 | + min_len += 1; | |
222 | + if (len < min_len) goto length_error; | |
184 | 223 | p_result->rsp.status = *p; |
185 | 224 | return p_result->rsp.status; |
186 | 225 | } |
@@ -192,8 +231,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
192 | 231 | /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */ |
193 | 232 | |
194 | 233 | case AVRC_PDU_REGISTER_NOTIFICATION: |
195 | - avrc_parse_notification_rsp(p, &p_result->reg_notif); | |
196 | - break; | |
234 | + return avrc_parse_notification_rsp(p, len, &p_result->reg_notif); | |
197 | 235 | |
198 | 236 | case AVRC_PDU_GET_CAPABILITIES: |
199 | 237 | if (len == 0) |
@@ -202,12 +240,16 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
202 | 240 | p_result->get_caps.capability_id = 0; |
203 | 241 | break; |
204 | 242 | } |
243 | + min_len += 2; | |
244 | + if (len < min_len) goto length_error; | |
205 | 245 | BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p); |
206 | 246 | BE_STREAM_TO_UINT8(p_result->get_caps.count, p); |
207 | 247 | AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ", |
208 | 248 | __func__, p_result->get_caps.capability_id, p_result->get_caps.count); |
209 | 249 | if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) |
210 | 250 | { |
251 | + min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_COMP_ID) * 3; | |
252 | + if (len < min_len) goto length_error; | |
211 | 253 | for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_COMP_ID)); |
212 | 254 | xx++) |
213 | 255 | { |
@@ -216,6 +258,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
216 | 258 | } |
217 | 259 | else if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED) |
218 | 260 | { |
261 | + min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_EVT_ID); | |
262 | + if (len < min_len) goto length_error; | |
219 | 263 | for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_EVT_ID)); |
220 | 264 | xx++) |
221 | 265 | { |
@@ -230,6 +274,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
230 | 274 | p_result->list_app_attr.num_attr = 0; |
231 | 275 | break; |
232 | 276 | } |
277 | + min_len += 1; | |
233 | 278 | BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p); |
234 | 279 | AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->list_app_attr.num_attr); |
235 | 280 |
@@ -238,6 +283,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
238 | 283 | p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE; |
239 | 284 | } |
240 | 285 | |
286 | + min_len += p_result->list_app_attr.num_attr; | |
287 | + if (len < min_len) goto length_error; | |
241 | 288 | for(int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) |
242 | 289 | { |
243 | 290 | BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p); |
@@ -250,6 +297,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
250 | 297 | p_result->list_app_values.num_val = 0; |
251 | 298 | break; |
252 | 299 | } |
300 | + min_len += 1; | |
253 | 301 | BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p); |
254 | 302 | if (p_result->list_app_values.num_val > AVRC_MAX_APP_ATTR_SIZE) |
255 | 303 | { |
@@ -258,6 +306,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
258 | 306 | } |
259 | 307 | |
260 | 308 | AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->list_app_values.num_val); |
309 | + min_len += p_result->list_app_values.num_val; | |
310 | + if (len < min_len) goto length_error; | |
261 | 311 | for(int xx = 0; xx < p_result->list_app_values.num_val; xx++) |
262 | 312 | { |
263 | 313 | BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p); |
@@ -271,9 +321,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
271 | 321 | p_result->get_cur_app_val.num_val = 0; |
272 | 322 | break; |
273 | 323 | } |
324 | + min_len += 1; | |
274 | 325 | BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p); |
275 | - tAVRC_APP_SETTING *app_sett = | |
276 | - (tAVRC_APP_SETTING*)osi_malloc(p_result->get_cur_app_val.num_val*sizeof(tAVRC_APP_SETTING)); | |
277 | 326 | AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_cur_app_val.num_val); |
278 | 327 | |
279 | 328 | if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) { |
@@ -281,6 +330,14 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
281 | 330 | p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE; |
282 | 331 | } |
283 | 332 | |
333 | + min_len += p_result->get_cur_app_val.num_val * 2; | |
334 | + if (len < min_len) | |
335 | + { | |
336 | + p_result->get_cur_app_val.num_val = 0; | |
337 | + goto length_error; | |
338 | + } | |
339 | + tAVRC_APP_SETTING* app_sett = (tAVRC_APP_SETTING*)osi_calloc( | |
340 | + p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING)); | |
284 | 341 | for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) |
285 | 342 | { |
286 | 343 | BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p); |
@@ -299,21 +356,44 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
299 | 356 | p_result->get_app_attr_txt.num_attr = 0; |
300 | 357 | break; |
301 | 358 | } |
359 | + min_len += 1; | |
302 | 360 | BE_STREAM_TO_UINT8(num_attrs, p); |
303 | 361 | if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) { |
304 | 362 | num_attrs = AVRC_MAX_APP_ATTR_SIZE; |
305 | 363 | } |
306 | 364 | AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_app_attr_txt.num_attr); |
307 | 365 | p_result->get_app_attr_txt.num_attr = num_attrs; |
308 | - p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_malloc(num_attrs * sizeof(tAVRC_APP_SETTING_TEXT)); | |
366 | + p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(num_attrs * sizeof(tAVRC_APP_SETTING_TEXT)); | |
309 | 367 | for (int xx = 0; xx < num_attrs; xx++) |
310 | 368 | { |
369 | + min_len += 4; | |
370 | + if (len < min_len) | |
371 | + { | |
372 | + for (int j = 0; j < xx; j++) | |
373 | + { | |
374 | + osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str); | |
375 | + } | |
376 | + osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs); | |
377 | + p_result->get_app_attr_txt.num_attr = 0; | |
378 | + goto length_error; | |
379 | + } | |
311 | 380 | BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p); |
312 | 381 | BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id, p); |
313 | 382 | BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p); |
383 | + min_len += p_result->get_app_attr_txt.p_attrs[xx].str_len; | |
384 | + if (len < min_len) | |
385 | + { | |
386 | + for (int j = 0; j < xx; j++) | |
387 | + { | |
388 | + osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str); | |
389 | + } | |
390 | + osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs); | |
391 | + p_result->get_app_attr_txt.num_attr = 0; | |
392 | + goto length_error; | |
393 | + } | |
314 | 394 | if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0) |
315 | 395 | { |
316 | - UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_attr_txt.p_attrs[xx].str_len); | |
396 | + UINT8 *p_str = (UINT8 *)osi_calloc(p_result->get_app_attr_txt.p_attrs[xx].str_len); | |
317 | 397 | BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_attr_txt.p_attrs[xx].str_len); |
318 | 398 | p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str; |
319 | 399 | } else { |
@@ -332,6 +412,7 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
332 | 412 | p_result->get_app_val_txt.num_attr = 0; |
333 | 413 | break; |
334 | 414 | } |
415 | + min_len += 1; | |
335 | 416 | BE_STREAM_TO_UINT8(num_vals, p); |
336 | 417 | if (num_vals > AVRC_MAX_APP_ATTR_SIZE) { |
337 | 418 | num_vals = AVRC_MAX_APP_ATTR_SIZE; |
@@ -339,13 +420,35 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
339 | 420 | p_result->get_app_val_txt.num_attr = num_vals; |
340 | 421 | AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->get_app_val_txt.num_attr); |
341 | 422 | |
342 | - p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT *)osi_malloc(num_vals * sizeof(tAVRC_APP_SETTING_TEXT)); | |
423 | + p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT *)osi_calloc(num_vals * sizeof(tAVRC_APP_SETTING_TEXT)); | |
343 | 424 | for (int i = 0; i < num_vals; i++) { |
425 | + min_len += 4; | |
426 | + if (len < min_len) | |
427 | + { | |
428 | + for (int j = 0; j < i; j++) | |
429 | + { | |
430 | + osi_free(p_result->get_app_val_txt.p_attrs[j].p_str); | |
431 | + } | |
432 | + osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs); | |
433 | + p_result->get_app_val_txt.num_attr = 0; | |
434 | + goto length_error; | |
435 | + } | |
344 | 436 | BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p); |
345 | 437 | BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p); |
346 | 438 | BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p); |
439 | + min_len += p_result->get_app_val_txt.p_attrs[i].str_len; | |
440 | + if (len < min_len) | |
441 | + { | |
442 | + for (int j = 0; j < i; j++) | |
443 | + { | |
444 | + osi_free(p_result->get_app_val_txt.p_attrs[j].p_str); | |
445 | + } | |
446 | + osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs); | |
447 | + p_result->get_app_val_txt.num_attr = 0; | |
448 | + goto length_error; | |
449 | + } | |
347 | 450 | if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) { |
348 | - UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_val_txt.p_attrs[i].str_len); | |
451 | + UINT8 *p_str = (UINT8 *)osi_calloc(p_result->get_app_val_txt.p_attrs[i].str_len); | |
349 | 452 | BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_val_txt.p_attrs[i].str_len); |
350 | 453 | p_result->get_app_val_txt.p_attrs[i].p_str = p_str; |
351 | 454 | } else { |
@@ -368,20 +471,49 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
368 | 471 | p_result->get_elem_attrs.num_attr = 0; |
369 | 472 | break; |
370 | 473 | } |
474 | + min_len += 1; | |
371 | 475 | BE_STREAM_TO_UINT8(num_attrs, p); |
372 | 476 | p_result->get_elem_attrs.num_attr = num_attrs; |
373 | 477 | if (num_attrs) |
374 | 478 | { |
375 | 479 | tAVRC_ATTR_ENTRY *p_attrs = |
376 | - (tAVRC_ATTR_ENTRY*)osi_malloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY)); | |
377 | - for (int i = 0; i < num_attrs; i++) { | |
480 | + (tAVRC_ATTR_ENTRY*)osi_calloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY)); | |
481 | + for (int i = 0; i < num_attrs; i++) | |
482 | + { | |
483 | + min_len += 8; | |
484 | + if (len < min_len) | |
485 | + { | |
486 | + for (int j = 0; j < i; j++) | |
487 | + { | |
488 | + osi_free(p_attrs[j].name.p_str); | |
489 | + } | |
490 | + osi_free(p_attrs); | |
491 | + p_result->get_attrs.num_attrs = 0; | |
492 | + goto length_error; | |
493 | + } | |
378 | 494 | BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p); |
379 | 495 | BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p); |
380 | 496 | BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p); |
381 | - if (p_attrs[i].name.str_len > 0) { | |
382 | - p_attrs[i].name.p_str = (UINT8 *)osi_malloc(p_attrs[i].name.str_len); | |
497 | + min_len += p_attrs[i].name.str_len; | |
498 | + if (len < min_len) | |
499 | + { | |
500 | + for (int j = 0; j < i; j++) | |
501 | + { | |
502 | + osi_free(p_attrs[j].name.p_str); | |
503 | + } | |
504 | + osi_free(p_attrs); | |
505 | + p_result->get_attrs.num_attrs = 0; | |
506 | + goto length_error; | |
507 | + } | |
508 | + if (p_attrs[i].name.str_len > 0) | |
509 | + { | |
510 | + p_attrs[i].name.p_str = (UINT8 *)osi_calloc(p_attrs[i].name.str_len); | |
383 | 511 | BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str, p_attrs[i].name.str_len); |
384 | 512 | } |
513 | + else | |
514 | + { | |
515 | + p_attrs[i].name.p_str = NULL; | |
516 | + } | |
385 | 517 | } |
386 | 518 | p_result->get_elem_attrs.p_attrs = p_attrs; |
387 | 519 | } |
@@ -393,6 +525,8 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
393 | 525 | { |
394 | 526 | break; |
395 | 527 | } |
528 | + min_len += 9; | |
529 | + if (len < min_len) goto length_error; | |
396 | 530 | BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p); |
397 | 531 | BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p); |
398 | 532 | BE_STREAM_TO_UINT8(p_result->get_play_status.play_status, p); |
@@ -402,6 +536,12 @@ static tAVRC_STS avrc_ctrl_pars_vendor_rsp( | ||
402 | 536 | return AVRC_STS_BAD_CMD; |
403 | 537 | } |
404 | 538 | return AVRC_STS_NO_ERROR; |
539 | + | |
540 | +length_error: | |
541 | + android_errorWriteLog(0x534e4554, "111450417"); | |
542 | + AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d", | |
543 | + __func__, len, min_len); | |
544 | + return AVRC_STS_INTERNAL_ERR; | |
405 | 545 | } |
406 | 546 | |
407 | 547 | /******************************************************************************* |