Bluetooth: BR/EDR: Validate remote requirements

According Core Spec 4.2 [Vol 2 Part E, 7.7.41], remote authentication
and IO capability requirements have defined valid ranges.

Change-Id: I0f7cfb79097abbf96b3fee79a757431b6beef665
Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
This commit is contained in:
Arkadiusz Lichwa 2016-03-14 15:19:23 +01:00 committed by Johan Hedberg
commit befb051595
2 changed files with 33 additions and 0 deletions

View file

@ -65,6 +65,7 @@ static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src)
#define BT_HCI_ERR_UNKNOWN_CONN_ID 0x02
#define BT_HCI_ERR_AUTHENTICATION_FAIL 0x05
#define BT_HCI_ERR_INSUFFICIENT_RESOURCES 0x0d
#define BT_HCI_ERR_UNSUPP_FEATURE_PARAMS_VAL 0x11
#define BT_HCI_ERR_REMOTE_USER_TERM_CONN 0x13
#define BT_HCI_ERR_PAIRING_NOT_ALLOWED 0x18
#define BT_HCI_ERR_UNSUPP_REMOTE_FEATURE 0x1a

View file

@ -1127,6 +1127,24 @@ static void link_key_req(struct net_buf *buf)
bt_conn_unref(conn);
}
static void io_capa_neg_reply(const bt_addr_t *bdaddr, const uint8_t reason)
{
struct bt_hci_cp_io_capability_neg_reply *cp;
struct net_buf *resp_buf;
resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_NEG_REPLY,
sizeof(*cp));
if (!resp_buf) {
BT_ERR("Out of command buffers");
return;
}
cp = net_buf_add(resp_buf, sizeof(*cp));
bt_addr_copy(&cp->bdaddr, bdaddr);
cp->reason = reason;
bt_hci_cmd_send_sync(BT_HCI_OP_IO_CAPABILITY_NEG_REPLY, resp_buf, NULL);
}
static void io_capa_resp(struct net_buf *buf)
{
struct bt_hci_evt_io_capa_resp *evt = (void *)buf->data;
@ -1135,6 +1153,20 @@ static void io_capa_resp(struct net_buf *buf)
BT_DBG("remote %s, IOcapa 0x%02x, auth 0x%02x",
bt_addr_str(&evt->bdaddr), evt->capability, evt->authentication);
if (evt->authentication > BT_HCI_GENERAL_BONDING_MITM) {
BT_ERR("Invalid remote authentication requirements");
io_capa_neg_reply(&evt->bdaddr,
BT_HCI_ERR_UNSUPP_FEATURE_PARAMS_VAL);
return;
}
if (evt->capability > BT_IO_NO_INPUT_OUTPUT) {
BT_ERR("Invalid remote io capability requirements");
io_capa_neg_reply(&evt->bdaddr,
BT_HCI_ERR_UNSUPP_FEATURE_PARAMS_VAL);
return;
}
conn = bt_conn_lookup_addr_br(&evt->bdaddr);
if (!conn) {
BT_ERR("Unable to find conn for %s", bt_addr_str(&evt->bdaddr));