Skip to content

Commit b28b494

Browse files
Johan Hedbergholtmann
authored andcommitted
Bluetooth: Add strict checks for allowed SMP PDUs
SMP defines quite clearly when certain PDUs are to be expected/allowed and when not, but doesn't have any explicit request/response definition. So far the code has relied on each PDU handler to behave correctly if receiving PDUs at an unexpected moment, however this requires many different checks and is prone to errors. This patch introduces a generic way to keep track of allowed PDUs and thereby reduces the responsibility & load on individual command handlers. The tracking is implemented using a simple bit-mask where each opcode maps to its own bit. If the bit is set the corresponding PDU is allow and if the bit is not set the PDU is not allowed. As a simple example, when we send the Pairing Request we'd set the bit for Pairing Response, and when we receive the Pairing Response we'd clear the bit for Pairing Response. Since the disallowed PDU rejection is now done in a single central place we need to be a bit careful of which action makes most sense to all cases. Previously some, such as Security Request, have been simply ignored whereas others have caused an explicit disconnect. The only PDU rejection action that keeps good interoperability and can be used for all the applicable use cases is to drop the data. This may raise some concerns of us now being more lenient for misbehaving (and potentially malicious) devices, but the policy of simply dropping data has been a successful one for many years e.g. in L2CAP (where this is the *only* policy for such cases - we never request disconnection in l2cap_core.c because of bad data). Furthermore, we cannot prevent connected devices from creating the SMP context (through a Security or Pairing Request), and once the context exists looking up the corresponding bit for the received opcode and deciding to reject it is essentially an equally lightweight operation as the kind of rejection that l2cap_core.c already successfully does. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent c6e81e9 commit b28b494

File tree

2 files changed

+84
-38
lines changed

2 files changed

+84
-38
lines changed

net/bluetooth/smp.c

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131

3232
#include "smp.h"
3333

34+
#define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd)
35+
#define SMP_DISALLOW_CMD(smp, code) clear_bit(code, &smp->allow_cmd)
36+
3437
#define SMP_TIMEOUT msecs_to_jiffies(30000)
3538

3639
#define AUTH_REQ_MASK 0x07
@@ -47,6 +50,7 @@ enum {
4750
struct smp_chan {
4851
struct l2cap_conn *conn;
4952
struct delayed_work security_timer;
53+
unsigned long allow_cmd; /* Bitmask of allowed commands */
5054

5155
u8 preq[7]; /* SMP Pairing Request */
5256
u8 prsp[7]; /* SMP Pairing Response */
@@ -553,6 +557,11 @@ static u8 smp_confirm(struct smp_chan *smp)
553557

554558
smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp);
555559

560+
if (conn->hcon->out)
561+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
562+
else
563+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
564+
556565
return 0;
557566
}
558567

@@ -691,6 +700,20 @@ static void smp_notify_keys(struct l2cap_conn *conn)
691700
}
692701
}
693702

703+
static void smp_allow_key_dist(struct smp_chan *smp)
704+
{
705+
/* Allow the first expected phase 3 PDU. The rest of the PDUs
706+
* will be allowed in each PDU handler to ensure we receive
707+
* them in the correct order.
708+
*/
709+
if (smp->remote_key_dist & SMP_DIST_ENC_KEY)
710+
SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
711+
else if (smp->remote_key_dist & SMP_DIST_ID_KEY)
712+
SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
713+
else if (smp->remote_key_dist & SMP_DIST_SIGN)
714+
SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
715+
}
716+
694717
static void smp_distribute_keys(struct smp_chan *smp)
695718
{
696719
struct smp_cmd_pairing *req, *rsp;
@@ -704,8 +727,10 @@ static void smp_distribute_keys(struct smp_chan *smp)
704727
rsp = (void *) &smp->prsp[1];
705728

706729
/* The responder sends its keys first */
707-
if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK))
730+
if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) {
731+
smp_allow_key_dist(smp);
708732
return;
733+
}
709734

710735
req = (void *) &smp->preq[1];
711736

@@ -790,8 +815,10 @@ static void smp_distribute_keys(struct smp_chan *smp)
790815
}
791816

792817
/* If there are still keys to be received wait for them */
793-
if (smp->remote_key_dist & KEY_DIST_MASK)
818+
if (smp->remote_key_dist & KEY_DIST_MASK) {
819+
smp_allow_key_dist(smp);
794820
return;
821+
}
795822

796823
set_bit(SMP_FLAG_COMPLETE, &smp->flags);
797824
smp_notify_keys(conn);
@@ -829,6 +856,8 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
829856
smp->conn = conn;
830857
chan->data = smp;
831858

859+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL);
860+
832861
INIT_DELAYED_WORK(&smp->security_timer, smp_timeout);
833862

834863
hci_conn_hold(conn->hcon);
@@ -925,6 +954,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
925954
(req->auth_req & SMP_AUTH_BONDING))
926955
return SMP_PAIRING_NOTSUPP;
927956

957+
SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
958+
928959
smp->preq[0] = SMP_CMD_PAIRING_REQ;
929960
memcpy(&smp->preq[1], req, sizeof(*req));
930961
skb_pull(skb, sizeof(*req));
@@ -958,6 +989,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
958989
memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
959990

960991
smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
992+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
961993

962994
/* Request setup of TK */
963995
ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability);
@@ -983,6 +1015,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
9831015
if (conn->hcon->role != HCI_ROLE_MASTER)
9841016
return SMP_CMD_NOTSUPP;
9851017

1018+
SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
1019+
9861020
skb_pull(skb, sizeof(*rsp));
9871021

9881022
req = (void *) &smp->preq[1];
@@ -1040,13 +1074,19 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb)
10401074
if (skb->len < sizeof(smp->pcnf))
10411075
return SMP_INVALID_PARAMS;
10421076

1077+
SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM);
1078+
10431079
memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf));
10441080
skb_pull(skb, sizeof(smp->pcnf));
10451081

1046-
if (conn->hcon->out)
1082+
if (conn->hcon->out) {
10471083
smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd),
10481084
smp->prnd);
1049-
else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
1085+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1086+
return 0;
1087+
}
1088+
1089+
if (test_bit(SMP_FLAG_TK_VALID, &smp->flags))
10501090
return smp_confirm(smp);
10511091
else
10521092
set_bit(SMP_FLAG_CFM_PENDING, &smp->flags);
@@ -1064,6 +1104,8 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb)
10641104
if (skb->len < sizeof(smp->rrnd))
10651105
return SMP_INVALID_PARAMS;
10661106

1107+
SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM);
1108+
10671109
memcpy(smp->rrnd, skb->data, sizeof(smp->rrnd));
10681110
skb_pull(skb, sizeof(smp->rrnd));
10691111

@@ -1122,7 +1164,6 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
11221164
struct smp_cmd_security_req *rp = (void *) skb->data;
11231165
struct smp_cmd_pairing cp;
11241166
struct hci_conn *hcon = conn->hcon;
1125-
struct l2cap_chan *chan = conn->smp;
11261167
struct smp_chan *smp;
11271168
u8 sec_level;
11281169

@@ -1144,10 +1185,6 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
11441185
if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
11451186
return 0;
11461187

1147-
/* If SMP is already in progress ignore this request */
1148-
if (chan->data)
1149-
return 0;
1150-
11511188
smp = smp_chan_create(conn);
11521189
if (!smp)
11531190
return SMP_UNSPECIFIED;
@@ -1165,6 +1202,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
11651202
memcpy(&smp->preq[1], &cp, sizeof(cp));
11661203

11671204
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1205+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
11681206

11691207
return 0;
11701208
}
@@ -1227,10 +1265,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
12271265
memcpy(&smp->preq[1], &cp, sizeof(cp));
12281266

12291267
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
1268+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP);
12301269
} else {
12311270
struct smp_cmd_security_req cp;
12321271
cp.auth_req = authreq;
12331272
smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
1273+
SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ);
12341274
}
12351275

12361276
set_bit(SMP_FLAG_INITIATOR, &smp->flags);
@@ -1252,9 +1292,8 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
12521292
if (skb->len < sizeof(*rp))
12531293
return SMP_INVALID_PARAMS;
12541294

1255-
/* Ignore this PDU if it wasn't requested */
1256-
if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1257-
return 0;
1295+
SMP_DISALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO);
1296+
SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
12581297

12591298
skb_pull(skb, sizeof(*rp));
12601299

@@ -1278,13 +1317,13 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
12781317
if (skb->len < sizeof(*rp))
12791318
return SMP_INVALID_PARAMS;
12801319

1281-
/* Ignore this PDU if it wasn't requested */
1282-
if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
1283-
return 0;
1284-
12851320
/* Mark the information as received */
12861321
smp->remote_key_dist &= ~SMP_DIST_ENC_KEY;
12871322

1323+
SMP_DISALLOW_CMD(smp, SMP_CMD_MASTER_IDENT);
1324+
if (smp->remote_key_dist & SMP_DIST_ID_KEY)
1325+
SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1326+
12881327
skb_pull(skb, sizeof(*rp));
12891328

12901329
hci_dev_lock(hdev);
@@ -1311,9 +1350,8 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
13111350
if (skb->len < sizeof(*info))
13121351
return SMP_INVALID_PARAMS;
13131352

1314-
/* Ignore this PDU if it wasn't requested */
1315-
if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1316-
return 0;
1353+
SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_INFO);
1354+
SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
13171355

13181356
skb_pull(skb, sizeof(*info));
13191357

@@ -1336,13 +1374,13 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
13361374
if (skb->len < sizeof(*info))
13371375
return SMP_INVALID_PARAMS;
13381376

1339-
/* Ignore this PDU if it wasn't requested */
1340-
if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
1341-
return 0;
1342-
13431377
/* Mark the information as received */
13441378
smp->remote_key_dist &= ~SMP_DIST_ID_KEY;
13451379

1380+
SMP_DISALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO);
1381+
if (smp->remote_key_dist & SMP_DIST_SIGN)
1382+
SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1383+
13461384
skb_pull(skb, sizeof(*info));
13471385

13481386
hci_dev_lock(hcon->hdev);
@@ -1392,13 +1430,11 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb)
13921430
if (skb->len < sizeof(*rp))
13931431
return SMP_INVALID_PARAMS;
13941432

1395-
/* Ignore this PDU if it wasn't requested */
1396-
if (!(smp->remote_key_dist & SMP_DIST_SIGN))
1397-
return 0;
1398-
13991433
/* Mark the information as received */
14001434
smp->remote_key_dist &= ~SMP_DIST_SIGN;
14011435

1436+
SMP_DISALLOW_CMD(smp, SMP_CMD_SIGN_INFO);
1437+
14021438
skb_pull(skb, sizeof(*rp));
14031439

14041440
hci_dev_lock(hdev);
@@ -1418,6 +1454,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
14181454
{
14191455
struct l2cap_conn *conn = chan->conn;
14201456
struct hci_conn *hcon = conn->hcon;
1457+
struct smp_chan *smp;
14211458
__u8 code, reason;
14221459
int err = 0;
14231460

@@ -1437,18 +1474,19 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
14371474
code = skb->data[0];
14381475
skb_pull(skb, sizeof(code));
14391476

1440-
/*
1441-
* The SMP context must be initialized for all other PDUs except
1442-
* pairing and security requests. If we get any other PDU when
1443-
* not initialized simply disconnect (done if this function
1444-
* returns an error).
1477+
smp = chan->data;
1478+
1479+
if (code > SMP_CMD_MAX)
1480+
goto drop;
1481+
1482+
if (smp && !test_bit(code, &smp->allow_cmd))
1483+
goto drop;
1484+
1485+
/* If we don't have a context the only allowed commands are
1486+
* pairing request and security request.
14451487
*/
1446-
if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1447-
!chan->data) {
1448-
BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1449-
err = -EOPNOTSUPP;
1450-
goto done;
1451-
}
1488+
if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ)
1489+
goto drop;
14521490

14531491
switch (code) {
14541492
case SMP_CMD_PAIRING_REQ:
@@ -1510,6 +1548,12 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
15101548
}
15111549

15121550
return err;
1551+
1552+
drop:
1553+
BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name,
1554+
code, &hcon->dst);
1555+
kfree_skb(skb);
1556+
return 0;
15131557
}
15141558

15151559
static void smp_teardown_cb(struct l2cap_chan *chan, int err)

net/bluetooth/smp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ struct smp_cmd_security_req {
102102
__u8 auth_req;
103103
} __packed;
104104

105+
#define SMP_CMD_MAX 0x0b
106+
105107
#define SMP_PASSKEY_ENTRY_FAILED 0x01
106108
#define SMP_OOB_NOT_AVAIL 0x02
107109
#define SMP_AUTH_REQUIREMENTS 0x03

0 commit comments

Comments
 (0)