Merge the 2021-02-05 SPL branch from AOSP-Partner

* security-aosp-pi-release:
  ACL: Drop broadcasts
  Fix potential OOB write in libbluetooth
  Fix a security issue in sdp_server.cc
  Check Classic key before cross-key derivation
  Send a response to an smp security request depending on the callback event
  Return after removing sample LTK device
  Check whether local device is an ATV device to determine whether to show the consent dialog for BLE pairing in JUSTWORKS and ENCRYPTION_ONLY mode
  Shows a consent dialog on the local device when pairing a bluetooth low energy device if the local device has a display.

Change-Id: Iabdf85de3f3a41f828f5cd9d443a3c9b5359b29d
diff --git a/bta/dm/bta_dm_act.cc b/bta/dm/bta_dm_act.cc
index 5abda87..51201f5 100644
--- a/bta/dm/bta_dm_act.cc
+++ b/bta/dm/bta_dm_act.cc
@@ -3778,6 +3778,16 @@
 
       break;
 
+    case BTM_LE_CONSENT_REQ_EVT:
+      sec_event.ble_req.bd_addr = bda;
+      p_name = BTM_SecReadDevName(bda);
+      if (p_name != NULL)
+        strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
+      else
+        sec_event.ble_req.bd_name[0] = 0;
+      bta_dm_cb.p_sec_cback(BTA_DM_BLE_CONSENT_REQ_EVT, &sec_event);
+      break;
+
     case BTM_LE_SEC_REQUEST_EVT:
       sec_event.ble_req.bd_addr = bda;
       p_name = BTM_SecReadDevName(bda);
diff --git a/bta/include/bta_api.h b/bta/include/bta_api.h
index 9d4693e..cc6fa7c 100644
--- a/bta/include/bta_api.h
+++ b/bta/include/bta_api.h
@@ -389,6 +389,7 @@
                                     */
 #define BTA_DM_ENER_INFO_READ 28 /* Energy info read */
 #define BTA_DM_BLE_SC_OOB_REQ_EVT 29 /* SMP SC OOB request event */
+#define BTA_DM_BLE_CONSENT_REQ_EVT 30 /* SMP consent request event */
 typedef uint8_t tBTA_DM_SEC_EVT;
 
 /* Structure associated with BTA_DM_ENABLE_EVT */
diff --git a/btif/include/btif_api.h b/btif/include/btif_api.h
index 519fc9c..1f04d7c 100644
--- a/btif/include/btif_api.h
+++ b/btif/include/btif_api.h
@@ -105,6 +105,18 @@
 
 /*******************************************************************************
  *
+ * Function         is_atv_device
+ *
+ * Description      Returns true if the local device is an Android TV
+ *                  device, false if it is not.
+ *
+ * Returns          bool
+ *
+ ******************************************************************************/
+bool is_atv_device(void);
+
+/*******************************************************************************
+ *
  * Function         btif_get_adapter_properties
  *
  * Description      Fetches all local adapter properties
diff --git a/btif/include/btif_dm.h b/btif/include/btif_dm.h
index bdbce49..875f54a 100644
--- a/btif/include/btif_dm.h
+++ b/btif/include/btif_dm.h
@@ -102,7 +102,7 @@
                                 tBTA_BLE_LOCAL_ID_KEYS* p_id_keys);
 void btif_dm_save_ble_bonding_keys(RawAddress& bd_addr);
 void btif_dm_remove_ble_bonding_keys(void);
-void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req);
+void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent);
 
 void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr,
                                           BD_NAME bd_name,
diff --git a/btif/src/bluetooth.cc b/btif/src/bluetooth.cc
index 92a4092..c17d086 100644
--- a/btif/src/bluetooth.cc
+++ b/btif/src/bluetooth.cc
@@ -82,6 +82,7 @@
 
 bt_callbacks_t* bt_hal_cbacks = NULL;
 bool restricted_mode = false;
+bool is_local_device_atv = false;
 
 /*******************************************************************************
  *  Externs
@@ -138,7 +139,7 @@
  *
  ****************************************************************************/
 
-static int init(bt_callbacks_t* callbacks) {
+static int init(bt_callbacks_t* callbacks, bool is_atv) {
   LOG_INFO(LOG_TAG, "%s", __func__);
 
   if (interface_ready()) return BT_STATUS_DONE;
@@ -148,6 +149,7 @@
 #endif
 
   bt_hal_cbacks = callbacks;
+  is_local_device_atv = is_atv;
   stack_manager_get_interface()->init_stack();
   btif_debug_init();
   return BT_STATUS_SUCCESS;
@@ -175,6 +177,8 @@
 
 bool is_restricted_mode() { return restricted_mode; }
 
+bool is_atv_device() { return is_local_device_atv; }
+
 static int get_adapter_properties(void) {
   /* sanity check */
   if (!interface_ready()) return BT_STATUS_NOT_READY;
diff --git a/btif/src/btif_dm.cc b/btif/src/btif_dm.cc
index 1d52347..100aefb 100644
--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -1782,9 +1782,13 @@
           break;
       }
       break;
+    case BTA_DM_BLE_CONSENT_REQ_EVT:
+      BTIF_TRACE_DEBUG("BTA_DM_BLE_CONSENT_REQ_EVT. ");
+      btif_dm_ble_sec_req_evt(&p_data->ble_req, true);
+      break;
     case BTA_DM_BLE_SEC_REQ_EVT:
       BTIF_TRACE_DEBUG("BTA_DM_BLE_SEC_REQ_EVT. ");
-      btif_dm_ble_sec_req_evt(&p_data->ble_req);
+      btif_dm_ble_sec_req_evt(&p_data->ble_req, false);
       break;
     case BTA_DM_BLE_PASSKEY_NOTIF_EVT:
       BTIF_TRACE_DEBUG("BTA_DM_BLE_PASSKEY_NOTIF_EVT. ");
@@ -2975,14 +2979,14 @@
  * Returns          void
  *
  ******************************************************************************/
-void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req) {
+void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent) {
   bt_bdname_t bd_name;
   uint32_t cod;
   int dev_type;
 
   BTIF_TRACE_DEBUG("%s", __func__);
 
-  if (pairing_cb.state == BT_BOND_STATE_BONDING) {
+  if (!is_consent && pairing_cb.state == BT_BOND_STATE_BONDING) {
     BTIF_TRACE_DEBUG("%s Discard security request", __func__);
     return;
   }
diff --git a/hci/src/packet_fragmenter.cc b/hci/src/packet_fragmenter.cc
index 217b4fd..87d1df5 100644
--- a/hci/src/packet_fragmenter.cc
+++ b/hci/src/packet_fragmenter.cc
@@ -35,10 +35,12 @@
 #define APPLY_START_FLAG(handle) (((handle)&0xCFFF) | 0x2000)
 #define SUB_EVENT(event) ((event)&MSG_SUB_EVT_MASK)
 #define GET_BOUNDARY_FLAG(handle) (((handle) >> 12) & 0x0003)
+#define GET_BROADCAST_FLAG(handle) (((handle) >> 14) & 0x0003)
 
 #define HANDLE_MASK 0x0FFF
 #define START_PACKET_BOUNDARY 2
 #define CONTINUATION_PACKET_BOUNDARY 1
+#define POINT_TO_POINT 0
 #define L2CAP_HEADER_PDU_LEN_SIZE 2
 #define L2CAP_HEADER_CID_SIZE 2
 #define L2CAP_HEADER_SIZE (L2CAP_HEADER_PDU_LEN_SIZE + L2CAP_HEADER_CID_SIZE)
@@ -133,8 +135,16 @@
     CHECK(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);
 
     uint8_t boundary_flag = GET_BOUNDARY_FLAG(handle);
+    uint8_t broadcast_flag = GET_BROADCAST_FLAG(handle);
     handle = handle & HANDLE_MASK;
 
+    if (broadcast_flag != POINT_TO_POINT) {
+      LOG_WARN(LOG_TAG, "dropping broadcast packet");
+      android_errorWriteLog(0x534e4554, "169327567");
+      buffer_allocator->free(packet);
+      return;
+    }
+
     if (boundary_flag == START_PACKET_BOUNDARY) {
       auto map_iter = partial_packets.find(handle);
       if (map_iter != partial_packets.end()) {
diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h
index 36680bf..f6a2731 100644
--- a/include/hardware/bluetooth.h
+++ b/include/hardware/bluetooth.h
@@ -444,8 +444,9 @@
   /**
    * Opens the interface and provides the callback routines
    * to the implemenation of this interface.
+   * The |is_atv| flag indicates whether the local device is an Android TV
    */
-  int (*init)(bt_callbacks_t* callbacks);
+  int (*init)(bt_callbacks_t* callbacks, bool is_atv);
 
   /** Enable Bluetooth. */
   int (*enable)(bool guest_mode);
diff --git a/service/hal/bluetooth_interface.cc b/service/hal/bluetooth_interface.cc
index 9296966..d2824d7 100644
--- a/service/hal/bluetooth_interface.cc
+++ b/service/hal/bluetooth_interface.cc
@@ -247,7 +247,7 @@
 
     // Initialize the Bluetooth interface. Set up the adapter (Bluetooth DM) API
     // callbacks.
-    status = hal_iface_->init(&bt_callbacks);
+    status = hal_iface_->init(&bt_callbacks, false);
     if (status != BT_STATUS_SUCCESS) {
       LOG(ERROR) << "Failed to initialize Bluetooth stack";
       return false;
diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc
index c0504ee..3b7e231 100644
--- a/stack/avrc/avrc_pars_tg.cc
+++ b/stack/avrc/avrc_pars_tg.cc
@@ -301,6 +301,13 @@
         status = AVRC_STS_INTERNAL_ERR;
       else {
         BE_STREAM_TO_UINT8(p_result->reg_notif.event_id, p);
+        if (!AVRC_IS_VALID_EVENT_ID(p_result->reg_notif.event_id)) {
+          android_errorWriteLog(0x534e4554, "168802990");
+          AVRC_TRACE_ERROR("%s: Invalid event id: %d", __func__,
+                           p_result->reg_notif.event_id);
+          return AVRC_STS_BAD_PARAM;
+        }
+
         BE_STREAM_TO_UINT32(p_result->reg_notif.param, p);
       }
       break;
diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc
index 0c4bdd9..48f4496 100644
--- a/stack/btm/btm_ble.cc
+++ b/stack/btm/btm_ble.cc
@@ -2065,6 +2065,7 @@
         /* fall through */
         p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED;
 
+      case SMP_CONSENT_REQ_EVT:
       case SMP_SEC_REQUEST_EVT:
         if (event == SMP_SEC_REQUEST_EVT &&
             btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) {
@@ -2072,7 +2073,9 @@
           break;
         }
         btm_cb.pairing_bda = bd_addr;
-        p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+        if (event != SMP_CONSENT_REQ_EVT) {
+          p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+        }
         btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
       /* fall through */
 
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index e6f02eb..a89378d 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -4551,6 +4551,7 @@
               << p_dev_rec->bd_addr;
 
     bta_dm_remove_device(p_dev_rec->bd_addr);
+    return;
   }
 
   BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__,
diff --git a/stack/include/btm_api_types.h b/stack/include/btm_api_types.h
index df7b64d..02f5f2a 100644
--- a/stack/include/btm_api_types.h
+++ b/stack/include/btm_api_types.h
@@ -1567,6 +1567,7 @@
 #define BTM_LE_LAST_FROM_SMP BTM_LE_BR_KEYS_REQ_EVT
 /* KEY update event */
 #define BTM_LE_KEY_EVT (BTM_LE_LAST_FROM_SMP + 1)
+#define BTM_LE_CONSENT_REQ_EVT SMP_CONSENT_REQ_EVT
 typedef uint8_t tBTM_LE_EVT;
 
 #define BTM_LE_KEY_NONE 0
diff --git a/stack/include/smp_api_types.h b/stack/include/smp_api_types.h
index fad8b75..a24aab9 100644
--- a/stack/include/smp_api_types.h
+++ b/stack/include/smp_api_types.h
@@ -59,6 +59,7 @@
 /* SC OOB local data set is created (as result of SMP_CrLocScOobData(...)) */
 #define SMP_SC_LOC_OOB_DATA_UP_EVT 10
 #define SMP_BR_KEYS_REQ_EVT 12 /* SMP over BR keys request event */
+#define SMP_CONSENT_REQ_EVT 14 /* Consent request event */
 typedef uint8_t tSMP_EVT;
 
 /* pairing failure reason code */
diff --git a/stack/sdp/sdp_server.cc b/stack/sdp/sdp_server.cc
index 386f62f..07408a7 100644
--- a/stack/sdp/sdp_server.cc
+++ b/stack/sdp/sdp_server.cc
@@ -124,9 +124,11 @@
 
   if (p_req + sizeof(pdu_id) + sizeof(trans_num) > p_req_end) {
     android_errorWriteLog(0x534e4554, "69384124");
+    android_errorWriteLog(0x534e4554, "169342531");
     trans_num = 0;
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                             SDP_TEXT_BAD_HEADER);
+    return;
   }
 
   /* The first byte in the message is the pdu type */
@@ -137,8 +139,10 @@
 
   if (p_req + sizeof(param_len) > p_req_end) {
     android_errorWriteLog(0x534e4554, "69384124");
+    android_errorWriteLog(0x534e4554, "169342531");
     sdpu_build_n_send_error(p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX,
                             SDP_TEXT_BAD_HEADER);
+    return;
   }
 
   BE_STREAM_TO_UINT16(param_len, p_req);
diff --git a/stack/smp/smp_act.cc b/stack/smp/smp_act.cc
index b775d5d..08124dd 100644
--- a/stack/smp/smp_act.cc
+++ b/stack/smp/smp_act.cc
@@ -17,6 +17,7 @@
  ******************************************************************************/
 
 #include <string.h>
+#include "btif_api.h"
 #include "btif_common.h"
 #include "device/include/interop.h"
 #include "internal_include/bt_target.h"
@@ -1224,7 +1225,17 @@
     /* state check to prevent re-entrant */
     if (smp_get_state() == SMP_STATE_BOND_PENDING) {
       if (p_cb->derive_lk) {
-        smp_derive_link_key_from_long_term_key(p_cb, NULL);
+        tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(p_cb->pairing_bda);
+        if (!(p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_AUTHED) &&
+            (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)) {
+          SMP_TRACE_DEBUG(
+              "%s BR key is higher security than existing LE keys, don't "
+              "derive LK from LTK",
+              __func__);
+          android_errorWriteLog(0x534e4554, "158854097");
+        } else {
+          smp_derive_link_key_from_long_term_key(p_cb, NULL);
+        }
         p_cb->derive_lk = false;
       }
 
@@ -1272,18 +1283,28 @@
         smp_int_data.status = SMP_PAIR_AUTH_FAIL;
         int_evt = SMP_AUTH_CMPL_EVT;
       } else {
-        p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
-        SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
-                        p_cb->sec_level);
+        if (!is_atv_device() &&
+            (p_cb->local_io_capability == SMP_IO_CAP_IO ||
+             p_cb->local_io_capability == SMP_IO_CAP_KBDISP)) {
+          /* display consent dialog if this device has a display */
+          SMP_TRACE_DEBUG("ENCRYPTION_ONLY showing Consent Dialog");
+          p_cb->cb_evt = SMP_CONSENT_REQ_EVT;
+          smp_set_state(SMP_STATE_WAIT_NONCE);
+          smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL);
+        } else {
+          p_cb->sec_level = SMP_SEC_UNAUTHENTICATE;
+          SMP_TRACE_EVENT("p_cb->sec_level =%d (SMP_SEC_UNAUTHENTICATE) ",
+                          p_cb->sec_level);
 
-        tSMP_KEY key;
-        key.key_type = SMP_KEY_TYPE_TK;
-        key.p_data = p_cb->tk;
-        smp_int_data.key = key;
+          tSMP_KEY key;
+          key.key_type = SMP_KEY_TYPE_TK;
+          key.p_data = p_cb->tk;
+          smp_int_data.key = key;
 
-        memset(p_cb->tk, 0, BT_OCTET16_LEN);
-        /* TK, ready  */
-        int_evt = SMP_KEY_READY_EVT;
+          memset(p_cb->tk, 0, BT_OCTET16_LEN);
+          /* TK, ready  */
+          int_evt = SMP_KEY_READY_EVT;
+        }
       }
       break;
 
@@ -1630,8 +1651,18 @@
       }
 
       if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
-        /* go directly to phase 2 */
-        smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
+        if (!is_atv_device() &&
+            (p_cb->local_io_capability == SMP_IO_CAP_IO ||
+             p_cb->local_io_capability == SMP_IO_CAP_KBDISP)) {
+          /* display consent dialog */
+          SMP_TRACE_DEBUG("JUST WORKS showing Consent Dialog");
+          p_cb->cb_evt = SMP_CONSENT_REQ_EVT;
+          smp_set_state(SMP_STATE_WAIT_NONCE);
+          smp_sm_event(p_cb, SMP_SC_DSPL_NC_EVT, NULL);
+        } else {
+          /* go directly to phase 2 */
+          smp_sm_event(p_cb, SMP_SC_PHASE1_CMPLT_EVT, NULL);
+        }
       } else /* numeric comparison */
       {
         smp_set_state(SMP_STATE_WAIT_NONCE);
diff --git a/stack/smp/smp_api.cc b/stack/smp/smp_api.cc
index d096da5..e39ee79 100644
--- a/stack/smp/smp_api.cc
+++ b/stack/smp/smp_api.cc
@@ -249,6 +249,44 @@
 void SMP_SecurityGrant(const RawAddress& bd_addr, uint8_t res) {
   SMP_TRACE_EVENT("SMP_SecurityGrant ");
 
+  // If just showing consent dialog, send response
+  if (smp_cb.cb_evt == SMP_CONSENT_REQ_EVT) {
+    // If JUSTWORKS, this is used to display the consent dialog
+    if (smp_cb.selected_association_model == SMP_MODEL_SEC_CONN_JUSTWORKS) {
+      if (res == SMP_SUCCESS) {
+        smp_sm_event(&smp_cb, SMP_SC_NC_OK_EVT, NULL);
+      } else {
+        SMP_TRACE_WARNING("%s() - Consent dialog fails for JUSTWORKS",
+                          __func__);
+        /* send pairing failure */
+        tSMP_INT_DATA smp_int_data;
+        smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
+        smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+      }
+    } else if (smp_cb.selected_association_model == SMP_MODEL_ENCRYPTION_ONLY) {
+      if (res == SMP_SUCCESS) {
+        smp_cb.sec_level = SMP_SEC_UNAUTHENTICATE;
+
+        tSMP_KEY key;
+        tSMP_INT_DATA smp_int_data;
+        key.key_type = SMP_KEY_TYPE_TK;
+        key.p_data = smp_cb.tk;
+        smp_int_data.key = key;
+
+        memset(smp_cb.tk, 0, BT_OCTET16_LEN);
+        smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &smp_int_data);
+      } else {
+        SMP_TRACE_WARNING("%s() - Consent dialog fails for ENCRYPTION_ONLY",
+                          __func__);
+        /* send pairing failure */
+        tSMP_INT_DATA smp_int_data;
+        smp_int_data.status = SMP_NUMERIC_COMPAR_FAIL;
+        smp_sm_event(&smp_cb, SMP_AUTH_CMPL_EVT, &smp_int_data);
+      }
+    }
+    return;
+  }
+
   if (smp_cb.smp_over_br) {
     if (smp_cb.br_state != SMP_BR_STATE_WAIT_APP_RSP ||
         smp_cb.cb_evt != SMP_SEC_REQUEST_EVT || smp_cb.pairing_bda != bd_addr) {
diff --git a/test/suite/adapter/adapter_unittest.cc b/test/suite/adapter/adapter_unittest.cc
index 24ca3e5..c9fe606 100644
--- a/test/suite/adapter/adapter_unittest.cc
+++ b/test/suite/adapter/adapter_unittest.cc
@@ -179,7 +179,7 @@
   ASSERT_TRUE(bt_callbacks != nullptr);
 
   for (int i = 0; i < kTestRepeatCount; ++i) {
-    bt_interface()->init(bt_callbacks);
+    bt_interface()->init(bt_callbacks, false);
     EXPECT_EQ(bt_interface()->enable(false), BT_STATUS_SUCCESS);
     semaphore_wait(adapter_state_changed_callback_sem_);
     EXPECT_EQ(GetState(), BT_STATE_ON) << "Adapter did not turn on.";