From 5715e465ccf937f5cae5bd623f581cfa5b75fdd1 Mon Sep 17 00:00:00 2001 From: Hui Peng <phui@google.com> Date: Mon, 10 Jul 2023 09:04:29 +0000 Subject: [PATCH] Add validation on sdp attr type and size in hidh_api.cc Bug: 263958603 Test: atest net_test_stack_hid Ignore-AOSP-First: security Tag: #security Change-Id: Ia2e8e588ad890b531b94e2fca84279de603dcc05 --- system/stack/hid/hidh_api.cc | 58 ++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/system/stack/hid/hidh_api.cc b/system/stack/hid/hidh_api.cc index 27595db9538..572f3f6f142 100644 --- a/system/stack/hid/hidh_api.cc +++ b/system/stack/hid/hidh_api.cc @@ -94,13 +94,18 @@ void hidh_get_str_attr(tSDP_DISC_REC* p_rec, uint16_t attr_id, uint16_t max_len, p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec(p_rec, attr_id); if (p_attr != NULL) { - name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type); - if (name_len < max_len) { - memcpy(str, (char*)p_attr->attr_value.v.array, name_len); - str[name_len] = '\0'; + if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == TEXT_STR_DESC_TYPE) { + name_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type); + if (name_len < max_len) { + memcpy(str, (char*)p_attr->attr_value.v.array, name_len); + str[name_len] = '\0'; + } else { + memcpy(str, (char*)p_attr->attr_value.v.array, max_len - 1); + str[max_len - 1] = '\0'; + } } else { - memcpy(str, (char*)p_attr->attr_value.v.array, max_len - 1); - str[max_len - 1] = '\0'; + str[0] = '\0'; + LOG_ERROR("attr type not str!!"); } } else str[0] = '\0'; @@ -152,36 +157,49 @@ static void hidh_search_callback(UNUSED_ATTR const RawAddress& bd_addr, if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_HID_VIRTUAL_CABLE)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1 && (p_attr->attr_value.v.u8)) { attr_mask |= HID_VIRTUAL_CABLE; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_HID_RECONNECT_INITIATE)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1 && (p_attr->attr_value.v.u8)) { attr_mask |= HID_RECONN_INIT; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_HID_NORMALLY_CONNECTABLE)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1 && (p_attr->attr_value.v.u8)) { attr_mask |= HID_NORMALLY_CONNECTABLE; } + // this attribute is deprecated, should we still keep it? if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_HID_SDP_DISABLE)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1 && (p_attr->attr_value.v.u8)) { attr_mask |= HID_SDP_DISABLE; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_HID_BATTERY_POWER)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1 && (p_attr->attr_value.v.u8)) { attr_mask |= HID_BATTERY_POWER; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( p_rec, ATTR_ID_HID_REMOTE_WAKE)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == BOOLEAN_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1 && (p_attr->attr_value.v.u8)) { attr_mask |= HID_REMOTE_WAKE; } @@ -194,40 +212,54 @@ static void hidh_search_callback(UNUSED_ATTR const RawAddress& bd_addr, p_nvi->prov_name); if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_DEVICE_RELNUM)) != NULL)) { + p_rec, ATTR_ID_HID_DEVICE_RELNUM)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { p_nvi->rel_num = p_attr->attr_value.v.u16; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_COUNTRY_CODE)) != NULL)) { + p_rec, ATTR_ID_HID_COUNTRY_CODE)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) { p_nvi->ctry_code = p_attr->attr_value.v.u8; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) != NULL)) { + p_rec, ATTR_ID_HID_DEVICE_SUBCLASS)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 1) { p_nvi->sub_class = p_attr->attr_value.v.u8; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_PARSER_VERSION)) != NULL)) { + p_rec, ATTR_ID_HID_PARSER_VERSION)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { p_nvi->hpars_ver = p_attr->attr_value.v.u16; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) != NULL)) { + p_rec, ATTR_ID_HID_LINK_SUPERVISION_TO)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { attr_mask |= HID_SUP_TOUT_AVLBL; p_nvi->sup_timeout = p_attr->attr_value.v.u16; } if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) != NULL)) { + p_rec, ATTR_ID_HID_SSR_HOST_MAX_LAT)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { attr_mask |= HID_SSR_MAX_LATENCY; p_nvi->ssr_max_latency = p_attr->attr_value.v.u16; } else p_nvi->ssr_max_latency = HID_SSR_PARAM_INVALID; if (((p_attr = get_legacy_stack_sdp_api()->record.SDP_FindAttributeInRec( - p_rec, ATTR_ID_HID_SSR_HOST_MIN_TOUT)) != NULL)) { + p_rec, ATTR_ID_HID_SSR_HOST_MIN_TOUT)) != NULL) && + SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) == UINT_DESC_TYPE && + SDP_DISC_ATTR_LEN(p_attr->attr_len_type) >= 2) { attr_mask |= HID_SSR_MIN_TOUT; p_nvi->ssr_min_tout = p_attr->attr_value.v.u16; } else -- GitLab