2021-03-12 18:22:52

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH] Bluetooth: L2CAP: Fix not checking for maximum number of DCID

From: Luiz Augusto von Dentz <[email protected]>

When receiving L2CAP_CREDIT_BASED_CONNECTION_REQ the remote may request
more channels than allowed by the spec (10 octecs = 5 CIDs) so this
truncates the response allowing it to create only the maximum allowed.

Signed-off-by: Luiz Augusto von Dentz <[email protected]>
---
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/l2cap_core.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 61800a7b6192..3c4f550e5a8b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -494,6 +494,7 @@ struct l2cap_le_credits {

#define L2CAP_ECRED_MIN_MTU 64
#define L2CAP_ECRED_MIN_MPS 64
+#define L2CAP_ECRED_MAX_CID 5

struct l2cap_ecred_conn_req {
__le16 psm;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 72c2f5226d67..6325d4a89b31 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5921,7 +5921,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
struct l2cap_ecred_conn_req *req = (void *) data;
struct {
struct l2cap_ecred_conn_rsp rsp;
- __le16 dcid[5];
+ __le16 dcid[L2CAP_ECRED_MAX_CID];
} __packed pdu;
struct l2cap_chan *chan, *pchan;
u16 mtu, mps;
@@ -5973,7 +5973,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
cmd_len -= sizeof(*req);
num_scid = cmd_len / sizeof(u16);

- for (i = 0; i < num_scid; i++) {
+ for (i = 0; i < num_scid && i < ARRAY_SIZE(pdu.dcid); i++) {
u16 scid = __le16_to_cpu(req->scid[i]);

BT_DBG("scid[%d] 0x%4.4x", i, scid);
--
2.29.2


2021-03-12 19:50:53

by bluez.test.bot

[permalink] [raw]
Subject: RE: Bluetooth: L2CAP: Fix not checking for maximum number of DCID

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=447251

---Test result---

##############################
Test: CheckPatch - PASS


##############################
Test: CheckGitLint - PASS


##############################
Test: CheckBuildK - PASS


##############################
Test: CheckTestRunner: Setup - PASS


##############################
Test: CheckTestRunner: l2cap-tester - PASS
Total: 40, Passed: 34 (85.0%), Failed: 0, Not Run: 6

##############################
Test: CheckTestRunner: bnep-tester - PASS
Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: mgmt-tester - FAIL
Total: 416, Passed: 399 (95.9%), Failed: 3, Not Run: 14

##############################
Test: CheckTestRunner: rfcomm-tester - PASS
Total: 9, Passed: 9 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: sco-tester - PASS
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: smp-tester - PASS
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: userchan-tester - PASS
Total: 3, Passed: 3 (100.0%), Failed: 0, Not Run: 0



---
Regards,
Linux Bluetooth


Attachments:
l2cap-tester.log (42.33 kB)
bnep-tester.log (3.45 kB)
mgmt-tester.log (534.30 kB)
rfcomm-tester.log (11.38 kB)
sco-tester.log (9.66 kB)
smp-tester.log (11.52 kB)
userchan-tester.log (5.30 kB)
Download all attachments

2021-03-13 11:04:32

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: L2CAP: Fix not checking for maximum number of DCID

Hi Luiz,

> When receiving L2CAP_CREDIT_BASED_CONNECTION_REQ the remote may request
> more channels than allowed by the spec (10 octecs = 5 CIDs) so this
> truncates the response allowing it to create only the maximum allowed.

so what does the spec say the behavior should be? Truncate or actually respond with an error?

> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
> ---
> include/net/bluetooth/l2cap.h | 1 +
> net/bluetooth/l2cap_core.c | 4 ++--
> 2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 61800a7b6192..3c4f550e5a8b 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -494,6 +494,7 @@ struct l2cap_le_credits {
>
> #define L2CAP_ECRED_MIN_MTU 64
> #define L2CAP_ECRED_MIN_MPS 64
> +#define L2CAP_ECRED_MAX_CID 5
>
> struct l2cap_ecred_conn_req {
> __le16 psm;
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 72c2f5226d67..6325d4a89b31 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -5921,7 +5921,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
> struct l2cap_ecred_conn_req *req = (void *) data;
> struct {
> struct l2cap_ecred_conn_rsp rsp;
> - __le16 dcid[5];
> + __le16 dcid[L2CAP_ECRED_MAX_CID];
> } __packed pdu;
> struct l2cap_chan *chan, *pchan;
> u16 mtu, mps;
> @@ -5973,7 +5973,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
> cmd_len -= sizeof(*req);
> num_scid = cmd_len / sizeof(u16);
>
> - for (i = 0; i < num_scid; i++) {
> + for (i = 0; i < num_scid && i < ARRAY_SIZE(pdu.dcid); i++) {
> u16 scid = __le16_to_cpu(req->scid[i]);
>
> BT_DBG("scid[%d] 0x%4.4x", i, scid);

Is this really a good idea? I would prefer if we check the size first and then just respond with an error.

Regards

Marcel

2021-03-15 21:43:54

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: L2CAP: Fix not checking for maximum number of DCID

Hi Marcel,

On Sat, Mar 13, 2021 at 3:02 AM Marcel Holtmann <[email protected]> wrote:
>
> Hi Luiz,
>
> > When receiving L2CAP_CREDIT_BASED_CONNECTION_REQ the remote may request
> > more channels than allowed by the spec (10 octecs = 5 CIDs) so this
> > truncates the response allowing it to create only the maximum allowed.
>
> so what does the spec say the behavior should be? Truncate or actually respond with an error?

The spec is not very clear about this, well except by saying:

'The Source CID is an array of up to 5 two-octet values and represents the
channel endpoints on the device sending the request.'

So I guess responding with an error would still conform to the above
statement so we would just strictly follow the maximum number of
channels allowed.

> > Signed-off-by: Luiz Augusto von Dentz <[email protected]>
> > ---
> > include/net/bluetooth/l2cap.h | 1 +
> > net/bluetooth/l2cap_core.c | 4 ++--
> > 2 files changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> > index 61800a7b6192..3c4f550e5a8b 100644
> > --- a/include/net/bluetooth/l2cap.h
> > +++ b/include/net/bluetooth/l2cap.h
> > @@ -494,6 +494,7 @@ struct l2cap_le_credits {
> >
> > #define L2CAP_ECRED_MIN_MTU 64
> > #define L2CAP_ECRED_MIN_MPS 64
> > +#define L2CAP_ECRED_MAX_CID 5
> >
> > struct l2cap_ecred_conn_req {
> > __le16 psm;
> > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> > index 72c2f5226d67..6325d4a89b31 100644
> > --- a/net/bluetooth/l2cap_core.c
> > +++ b/net/bluetooth/l2cap_core.c
> > @@ -5921,7 +5921,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
> > struct l2cap_ecred_conn_req *req = (void *) data;
> > struct {
> > struct l2cap_ecred_conn_rsp rsp;
> > - __le16 dcid[5];
> > + __le16 dcid[L2CAP_ECRED_MAX_CID];
> > } __packed pdu;
> > struct l2cap_chan *chan, *pchan;
> > u16 mtu, mps;
> > @@ -5973,7 +5973,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
> > cmd_len -= sizeof(*req);
> > num_scid = cmd_len / sizeof(u16);
> >
> > - for (i = 0; i < num_scid; i++) {
> > + for (i = 0; i < num_scid && i < ARRAY_SIZE(pdu.dcid); i++) {
> > u16 scid = __le16_to_cpu(req->scid[i]);
> >
> > BT_DBG("scid[%d] 0x%4.4x", i, scid);
>
> Is this really a good idea? I would prefer if we check the size first and then just respond with an error.

Right, I will change it to just fail with L2CAP_CR_LE_INVALID_PARAMS instead.

> Regards
>
> Marcel
>


--
Luiz Augusto von Dentz