aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2013-10-08 07:55:46 -0400
committerMarcel Holtmann <marcel@holtmann.org>2013-12-05 10:05:36 -0500
commit4946096d43d1d02fb07cc80f82e1747b01571c41 (patch)
tree0e18aaed28800e7c4e6ae8b591703742d7eac66a
parente77af7559238895ec5fd1706762e1c9f890dcc7e (diff)
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>
-rw-r--r--net/bluetooth/l2cap_core.c15
-rw-r--r--net/bluetooth/l2cap_sock.c40
2 files changed, 44 insertions, 11 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,
1861 return c1; 1861 return c1;
1862} 1862}
1863 1863
1864static bool is_valid_psm(u16 psm, u8 dst_type)
1865{
1866 if (!psm)
1867 return false;
1868
1869 if (bdaddr_type_is_le(dst_type))
1870 return (psm < 0x00ff);
1871
1872 /* PSM must be odd and lsb of upper byte must be 0 */
1873 return ((psm & 0x0101) == 0x0001);
1874}
1875
1864int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, 1876int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1865 bdaddr_t *dst, u8 dst_type) 1877 bdaddr_t *dst, u8 dst_type)
1866{ 1878{
@@ -1881,8 +1893,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
1881 1893
1882 l2cap_chan_lock(chan); 1894 l2cap_chan_lock(chan);
1883 1895
1884 /* PSM must be odd and lsb of upper byte must be 0 */ 1896 if (!is_valid_psm(__le16_to_cpu(psm), dst_type) && !cid &&
1885 if ((__le16_to_cpu(psm) & 0x0101) != 0x0001 && !cid &&
1886 chan->chan_type != L2CAP_CHAN_RAW) { 1897 chan->chan_type != L2CAP_CHAN_RAW) {
1887 err = -EINVAL; 1898 err = -EINVAL;
1888 goto done; 1899 goto done;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a51844a8c5eb..88fa9c07c503 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -53,6 +53,32 @@ bool l2cap_is_socket(struct socket *sock)
53} 53}
54EXPORT_SYMBOL(l2cap_is_socket); 54EXPORT_SYMBOL(l2cap_is_socket);
55 55
56static int l2cap_validate_bredr_psm(u16 psm)
57{
58 /* PSM must be odd and lsb of upper byte must be 0 */
59 if ((psm & 0x0101) != 0x0001)
60 return -EINVAL;
61
62 /* Restrict usage of well-known PSMs */
63 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE))
64 return -EACCES;
65
66 return 0;
67}
68
69static int l2cap_validate_le_psm(u16 psm)
70{
71 /* Valid LE_PSM ranges are defined only until 0x00ff */
72 if (psm > 0x00ff)
73 return -EINVAL;
74
75 /* Restrict fixed, SIG assigned PSM values to CAP_NET_BIND_SERVICE */
76 if (psm <= 0x007f && !capable(CAP_NET_BIND_SERVICE))
77 return -EACCES;
78
79 return 0;
80}
81
56static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) 82static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
57{ 83{
58 struct sock *sk = sock->sk; 84 struct sock *sk = sock->sk;
@@ -94,17 +120,13 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
94 if (la.l2_psm) { 120 if (la.l2_psm) {
95 __u16 psm = __le16_to_cpu(la.l2_psm); 121 __u16 psm = __le16_to_cpu(la.l2_psm);
96 122
97 /* PSM must be odd and lsb of upper byte must be 0 */ 123 if (la.l2_bdaddr_type == BDADDR_BREDR)
98 if ((psm & 0x0101) != 0x0001) { 124 err = l2cap_validate_bredr_psm(psm);
99 err = -EINVAL; 125 else
100 goto done; 126 err = l2cap_validate_le_psm(psm);
101 }
102 127
103 /* Restrict usage of well-known PSMs */ 128 if (err)
104 if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) {
105 err = -EACCES;
106 goto done; 129 goto done;
107 }
108 } 130 }
109 131
110 if (la.l2_cid) 132 if (la.l2_cid)