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
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index 15dfae1..b775d5d 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -341,7 +341,7 @@
  * Description  send encryption information command.
  ******************************************************************************/
 void smp_send_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
-  tBTM_LE_LENC_KEYS le_key;
+  tBTM_LE_KEY_VALUE le_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);
@@ -350,15 +350,14 @@
   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(le_key.lenc_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
+  le_key.lenc_key.div = p_cb->div;
+  le_key.lenc_key.key_size = p_cb->loc_enc_size;
+  le_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, &le_key, true);
 
   SMP_TRACE_WARNING("%s", __func__);
 
@@ -390,17 +389,16 @@
  * Description  send CSRK command.
  ******************************************************************************/
 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);
@@ -935,7 +933,7 @@
  ******************************************************************************/
 void smp_proc_master_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
   uint8_t* p = p_data->p_data;
-  tBTM_LE_PENC_KEYS le_key;
+  tBTM_LE_KEY_VALUE le_key;
 
   SMP_TRACE_DEBUG("%s", __func__);
 
@@ -948,18 +946,17 @@
 
   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);
 }
@@ -991,25 +988,24 @@
  ******************************************************************************/
 void smp_proc_id_addr(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
   uint8_t* p = p_data->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;
-  p_cb->id_addr = pid_key.static_addr;
+  p_cb->id_addr_type = pid_key.pid_key.addr_type;
+  p_cb->id_addr = pid_key.pid_key.static_addr;
 
   /* 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);
 }
 
@@ -1018,24 +1014,23 @@
  * Description  process security information from peer device
  ******************************************************************************/
 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;
+  le_key.pcsrk_key.sec_level = p_cb->sec_level;
 
   /* get peer CSRK */
-  maybe_non_aligned_memcpy(le_key.csrk, p_data->p_data, BT_OCTET16_LEN);
+  maybe_non_aligned_memcpy(le_key.pcsrk_key.csrk, p_data->p_data, BT_OCTET16_LEN);
 
   /* initialize the peer counter */
-  le_key.counter = 0;
+  le_key.pcsrk_key.counter = 0;
 
   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.cc b/stack/smp/smp_utils.cc
index 2bd0b24..5027e3d 100644
--- a/stack/smp/smp_utils.cc
+++ b/stack/smp/smp_utils.cc
@@ -1436,25 +1436,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);
 }
 
 /*******************************************************************************