Fix buffer overflow in btif_dm_data_copy
When we use a union, we should always define variables as the union type,
not as one of the field subtypes. If the latter is cast to the union type,
buffer overflow can happen.
Bug: 110166268
Test: compilation
Change-Id: I473c03b099ad5a326e7a3739f65efd33cf4775bd
Merged-In: I473c03b099ad5a326e7a3739f65efd33cf4775bd
(cherry picked from commit d1179759041eb66baf1b5cd398d69ce58849d848)
diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c
index 9c25e20..a986cbd 100644
--- a/stack/smp/smp_act.c
+++ b/stack/smp/smp_act.c
@@ -398,7 +398,7 @@
*******************************************************************************/
void smp_send_enc_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
- tBTM_LE_LENC_KEYS le_key;
+ tBTM_LE_KEY_VALUE key;
SMP_TRACE_DEBUG("%s p_cb->loc_enc_size = %d", __func__, p_cb->loc_enc_size);
smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, FALSE);
@@ -407,14 +407,13 @@
smp_send_cmd(SMP_OPCODE_MASTER_ID, p_cb);
/* save the DIV and key size information when acting as slave device */
- memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
- le_key.div = p_cb->div;
- le_key.key_size = p_cb->loc_enc_size;
- le_key.sec_level = p_cb->sec_level;
+ memcpy(key.lenc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
+ key.lenc_key.div = p_cb->div;
+ key.lenc_key.key_size = p_cb->loc_enc_size;
+ key.lenc_key.sec_level = p_cb->sec_level;
if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND))
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC,
- (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, &key, TRUE);
SMP_TRACE_WARNING ("%s", __func__);
@@ -448,17 +447,17 @@
*******************************************************************************/
void smp_send_csrk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
- tBTM_LE_LCSRK_KEYS key;
+ tBTM_LE_KEY_VALUE key;
SMP_TRACE_DEBUG("%s", __func__);
smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, FALSE);
if (smp_send_cmd(SMP_OPCODE_SIGN_INFO, p_cb))
{
- key.div = p_cb->div;
- key.sec_level = p_cb->sec_level;
- key.counter = 0; /* initialize the local counter */
- memcpy (key.csrk, p_cb->csrk, BT_OCTET16_LEN);
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK, (tBTM_LE_KEY_VALUE *)&key, TRUE);
+ key.lcsrk_key.div = p_cb->div;
+ key.lcsrk_key.sec_level = p_cb->sec_level;
+ key.lcsrk_key.counter = 0; /* initialize the local counter */
+ memcpy (key.lcsrk_key.csrk, p_cb->csrk, BT_OCTET16_LEN);
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LCSRK, &key, TRUE);
}
smp_key_distribution_by_transport(p_cb, NULL);
@@ -1035,7 +1034,7 @@
void smp_proc_master_id(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
UINT8 *p = (UINT8 *)p_data;
- tBTM_LE_PENC_KEYS le_key;
+ tBTM_LE_KEY_VALUE le_key;
SMP_TRACE_DEBUG("%s", __func__);
@@ -1048,18 +1047,16 @@
smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ENC, TRUE);
- STREAM_TO_UINT16(le_key.ediv, p);
- STREAM_TO_ARRAY(le_key.rand, p, BT_OCTET8_LEN );
+ STREAM_TO_UINT16(le_key.penc_key.ediv, p);
+ STREAM_TO_ARRAY(le_key.penc_key.rand, p, BT_OCTET8_LEN );
/* store the encryption keys from peer device */
- memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
- le_key.sec_level = p_cb->sec_level;
- le_key.key_size = p_cb->loc_enc_size;
+ memcpy(le_key.penc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
+ le_key.penc_key.sec_level = p_cb->sec_level;
+ le_key.penc_key.key_size = p_cb->loc_enc_size;
if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND))
- btm_sec_save_le_key(p_cb->pairing_bda,
- BTM_LE_KEY_PENC,
- (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, &le_key, TRUE);
smp_key_distribution(p_cb, NULL);
}
@@ -1092,24 +1089,23 @@
void smp_proc_id_addr(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
UINT8 *p = (UINT8 *)p_data;
- tBTM_LE_PID_KEYS pid_key;
+ tBTM_LE_KEY_VALUE pid_key;
SMP_TRACE_DEBUG("%s", __func__);
smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_ID, TRUE);
- STREAM_TO_UINT8(pid_key.addr_type, p);
- STREAM_TO_BDADDR(pid_key.static_addr, p);
- memcpy(pid_key.irk, p_cb->tk, BT_OCTET16_LEN);
+ STREAM_TO_UINT8(pid_key.pid_key.addr_type, p);
+ STREAM_TO_BDADDR(pid_key.pid_key.static_addr, p);
+ memcpy(pid_key.pid_key.irk, p_cb->tk, BT_OCTET16_LEN);
/* to use as BD_ADDR for lk derived from ltk */
p_cb->id_addr_rcvd = TRUE;
- p_cb->id_addr_type = pid_key.addr_type;
- memcpy(p_cb->id_addr, pid_key.static_addr, BD_ADDR_LEN);
+ p_cb->id_addr_type = pid_key.pid_key.addr_type;
+ memcpy(p_cb->id_addr, pid_key.pid_key.static_addr, BD_ADDR_LEN);
/* store the ID key from peer device */
if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND))
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID,
- (tBTM_LE_KEY_VALUE *)&pid_key, TRUE);
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PID, &pid_key, TRUE);
smp_key_distribution_by_transport(p_cb, NULL);
}
@@ -1119,20 +1115,18 @@
*******************************************************************************/
void smp_proc_srk_info(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
- tBTM_LE_PCSRK_KEYS le_key;
+ tBTM_LE_KEY_VALUE le_key;
SMP_TRACE_DEBUG("%s", __func__);
smp_update_key_mask (p_cb, SMP_SEC_KEY_TYPE_CSRK, TRUE);
/* save CSRK to security record */
- le_key.sec_level = p_cb->sec_level;
- memcpy (le_key.csrk, p_data, BT_OCTET16_LEN); /* get peer CSRK */
- le_key.counter = 0; /* initialize the peer counter */
+ le_key.pcsrk_key.sec_level = p_cb->sec_level;
+ memcpy (le_key.pcsrk_key.csrk, p_data, BT_OCTET16_LEN); /* get peer CSRK */
+ le_key.pcsrk_key.counter = 0; /* initialize the peer counter */
if ((p_cb->peer_auth_req & SMP_AUTH_BOND) && (p_cb->loc_auth_req & SMP_AUTH_BOND))
- btm_sec_save_le_key(p_cb->pairing_bda,
- BTM_LE_KEY_PCSRK,
- (tBTM_LE_KEY_VALUE *)&le_key, TRUE);
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PCSRK, &le_key, TRUE);
smp_key_distribution_by_transport(p_cb, NULL);
}
diff --git a/stack/smp/smp_utils.c b/stack/smp/smp_utils.c
index 675cb42..883e83b 100644
--- a/stack/smp/smp_utils.c
+++ b/stack/smp/smp_utils.c
@@ -1459,23 +1459,23 @@
*******************************************************************************/
void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb)
{
- tBTM_LE_LENC_KEYS lle_key;
- tBTM_LE_PENC_KEYS ple_key;
+ tBTM_LE_KEY_VALUE lle_key;
+ tBTM_LE_KEY_VALUE ple_key;
SMP_TRACE_DEBUG("%s-Save LTK as local LTK key", __func__);
- memcpy(lle_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
- lle_key.div = 0;
- lle_key.key_size = p_cb->loc_enc_size;
- lle_key.sec_level = p_cb->sec_level;
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, (tBTM_LE_KEY_VALUE *)&lle_key, TRUE);
+ memcpy(lle_key.lenc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
+ lle_key.lenc_key.div = 0;
+ lle_key.lenc_key.key_size = p_cb->loc_enc_size;
+ lle_key.lenc_key.sec_level = p_cb->sec_level;
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_LENC, &lle_key, TRUE);
SMP_TRACE_DEBUG("%s-Save LTK as peer LTK key", __func__);
- ple_key.ediv = 0;
- memset(ple_key.rand, 0, BT_OCTET8_LEN);
- memcpy(ple_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
- ple_key.sec_level = p_cb->sec_level;
- ple_key.key_size = p_cb->loc_enc_size;
- btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, (tBTM_LE_KEY_VALUE *)&ple_key, TRUE);
+ ple_key.penc_key.ediv = 0;
+ memset(ple_key.penc_key.rand, 0, BT_OCTET8_LEN);
+ memcpy(ple_key.penc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
+ ple_key.penc_key.sec_level = p_cb->sec_level;
+ ple_key.penc_key.key_size = p_cb->loc_enc_size;
+ btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC, &ple_key, TRUE);
}
/*******************************************************************************