diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2013-10-08 13:55:46 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2013-12-05 07:05:36 -0800 |
commit | 4946096d43d1d02fb07cc80f82e1747b01571c41 (patch) | |
tree | 0e18aaed28800e7c4e6ae8b591703742d7eac66a /net/bluetooth/l2cap_core.c | |
parent | e77af7559238895ec5fd1706762e1c9f890dcc7e (diff) | |
download | linux-4946096d43d1d02fb07cc80f82e1747b01571c41.tar.bz2 |
Bluetooth: Fix validating LE PSM values
LE PSM values have different ranges than those for BR/EDR. The valid
ranges for fixed, SIG assigned values is 0x0001-0x007f and for dynamic
PSM values 0x0080-0x00ff. We need to ensure that bind() and connect()
calls conform to these ranges when operating on LE CoC sockets.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap_core.c')
-rw-r--r-- | net/bluetooth/l2cap_core.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 76ebd18ff968..5941c65728b2 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1861,6 +1861,18 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, return c1; } +static bool is_valid_psm(u16 psm, u8 dst_type) +{ + if (!psm) + return false; + + if (bdaddr_type_is_le(dst_type)) + return (psm < 0x00ff); + + /* PSM must be odd and lsb of upper byte must be 0 */ + return ((psm & 0x0101) == 0x0001); +} + int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst, u8 dst_type) { @@ -1881,8 +1893,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, l2cap_chan_lock(chan); - /* PSM must be odd and lsb of upper byte must be 0 */ - if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid && + if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid && chan->chan_type != L2CAP_CHAN_RAW) { err = -EINVAL; goto done; |