Bluetooth: L2CAP: Elevate security level when connect request denied

Elevate the security level of the connection when the l2cap channel
connect request is denied with encryption or authentication error
code.
The l2cap channel required_sec_level was used, but this is not
correct as this is set by the user of the API. This resulted in
the call to bt_conn_set_security seeing that the current security
level was already set, decide there is nothing to be done and return
success.

Fixes: #27220

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-07-29 19:58:12 +02:00 committed by Carles Cufí
commit 9c3d006471

View file

@ -1308,6 +1308,8 @@ static void le_disconn_req(struct bt_l2cap *l2cap, uint8_t ident,
static int l2cap_change_security(struct bt_l2cap_le_chan *chan, uint16_t err)
{
struct bt_conn *conn = chan->chan.conn;
bt_security_t sec;
int ret;
if (atomic_test_bit(chan->chan.status,
@ -1317,18 +1319,19 @@ static int l2cap_change_security(struct bt_l2cap_le_chan *chan, uint16_t err)
switch (err) {
case BT_L2CAP_LE_ERR_ENCRYPTION:
if (chan->chan.required_sec_level >= BT_SECURITY_L2) {
if (conn->sec_level >= BT_SECURITY_L2) {
return -EALREADY;
}
chan->chan.required_sec_level = BT_SECURITY_L2;
sec = BT_SECURITY_L2;
break;
case BT_L2CAP_LE_ERR_AUTHENTICATION:
if (chan->chan.required_sec_level < BT_SECURITY_L2) {
chan->chan.required_sec_level = BT_SECURITY_L2;
} else if (chan->chan.required_sec_level < BT_SECURITY_L3) {
chan->chan.required_sec_level = BT_SECURITY_L3;
} else if (chan->chan.required_sec_level < BT_SECURITY_L4) {
chan->chan.required_sec_level = BT_SECURITY_L4;
if (conn->sec_level < BT_SECURITY_L2) {
sec = BT_SECURITY_L2;
} else if (conn->sec_level < BT_SECURITY_L3) {
sec = BT_SECURITY_L3;
} else if (conn->sec_level < BT_SECURITY_L4) {
sec = BT_SECURITY_L4;
} else {
return -EALREADY;
}
@ -1337,8 +1340,7 @@ static int l2cap_change_security(struct bt_l2cap_le_chan *chan, uint16_t err)
return -EINVAL;
}
ret = bt_conn_set_security(chan->chan.conn,
chan->chan.required_sec_level);
ret = bt_conn_set_security(chan->chan.conn, sec);
if (ret < 0) {
return ret;
}