diff options
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 120 |
1 files changed, 112 insertions, 8 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5ffd75e20bde..7cc24d263caa 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -72,6 +72,15 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
72 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) | 72 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) |
73 | return -EINVAL; | 73 | return -EINVAL; |
74 | 74 | ||
75 | if (bdaddr_type_is_le(la.l2_bdaddr_type)) { | ||
76 | /* Connection oriented channels are not supported on LE */ | ||
77 | if (la.l2_psm) | ||
78 | return -EINVAL; | ||
79 | /* We only allow ATT user space socket */ | ||
80 | if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
75 | lock_sock(sk); | 84 | lock_sock(sk); |
76 | 85 | ||
77 | if (sk->sk_state != BT_OPEN) { | 86 | if (sk->sk_state != BT_OPEN) { |
@@ -150,12 +159,44 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, | |||
150 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) | 159 | if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) |
151 | return -EINVAL; | 160 | return -EINVAL; |
152 | 161 | ||
153 | if (chan->src_type == BDADDR_BREDR && la.l2_bdaddr_type != BDADDR_BREDR) | 162 | /* Check that the socket wasn't bound to something that |
154 | return -EINVAL; | 163 | * conflicts with the address given to connect(). If chan->src |
164 | * is BDADDR_ANY it means bind() was never used, in which case | ||
165 | * chan->src_type and la.l2_bdaddr_type do not need to match. | ||
166 | */ | ||
167 | if (chan->src_type == BDADDR_BREDR && bacmp(&chan->src, BDADDR_ANY) && | ||
168 | bdaddr_type_is_le(la.l2_bdaddr_type)) { | ||
169 | /* Old user space versions will try to incorrectly bind | ||
170 | * the ATT socket using BDADDR_BREDR. We need to accept | ||
171 | * this and fix up the source address type only when | ||
172 | * both the source CID and destination CID indicate | ||
173 | * ATT. Anything else is an invalid combination. | ||
174 | */ | ||
175 | if (chan->scid != L2CAP_CID_ATT || | ||
176 | la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) | ||
177 | return -EINVAL; | ||
178 | |||
179 | /* We don't have the hdev available here to make a | ||
180 | * better decision on random vs public, but since all | ||
181 | * user space versions that exhibit this issue anyway do | ||
182 | * not support random local addresses assuming public | ||
183 | * here is good enough. | ||
184 | */ | ||
185 | chan->src_type = BDADDR_LE_PUBLIC; | ||
186 | } | ||
155 | 187 | ||
156 | if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR) | 188 | if (chan->src_type != BDADDR_BREDR && la.l2_bdaddr_type == BDADDR_BREDR) |
157 | return -EINVAL; | 189 | return -EINVAL; |
158 | 190 | ||
191 | if (bdaddr_type_is_le(la.l2_bdaddr_type)) { | ||
192 | /* Connection oriented channels are not supported on LE */ | ||
193 | if (la.l2_psm) | ||
194 | return -EINVAL; | ||
195 | /* We only allow ATT user space socket */ | ||
196 | if (la.l2_cid != __constant_cpu_to_le16(L2CAP_CID_ATT)) | ||
197 | return -EINVAL; | ||
198 | } | ||
199 | |||
159 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), | 200 | err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), |
160 | &la.l2_bdaddr, la.l2_bdaddr_type); | 201 | &la.l2_bdaddr, la.l2_bdaddr_type); |
161 | if (err) | 202 | if (err) |
@@ -879,6 +920,38 @@ static void l2cap_sock_kill(struct sock *sk) | |||
879 | sock_put(sk); | 920 | sock_put(sk); |
880 | } | 921 | } |
881 | 922 | ||
923 | static int __l2cap_wait_ack(struct sock *sk) | ||
924 | { | ||
925 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
926 | DECLARE_WAITQUEUE(wait, current); | ||
927 | int err = 0; | ||
928 | int timeo = HZ/5; | ||
929 | |||
930 | add_wait_queue(sk_sleep(sk), &wait); | ||
931 | set_current_state(TASK_INTERRUPTIBLE); | ||
932 | while (chan->unacked_frames > 0 && chan->conn) { | ||
933 | if (!timeo) | ||
934 | timeo = HZ/5; | ||
935 | |||
936 | if (signal_pending(current)) { | ||
937 | err = sock_intr_errno(timeo); | ||
938 | break; | ||
939 | } | ||
940 | |||
941 | release_sock(sk); | ||
942 | timeo = schedule_timeout(timeo); | ||
943 | lock_sock(sk); | ||
944 | set_current_state(TASK_INTERRUPTIBLE); | ||
945 | |||
946 | err = sock_error(sk); | ||
947 | if (err) | ||
948 | break; | ||
949 | } | ||
950 | set_current_state(TASK_RUNNING); | ||
951 | remove_wait_queue(sk_sleep(sk), &wait); | ||
952 | return err; | ||
953 | } | ||
954 | |||
882 | static int l2cap_sock_shutdown(struct socket *sock, int how) | 955 | static int l2cap_sock_shutdown(struct socket *sock, int how) |
883 | { | 956 | { |
884 | struct sock *sk = sock->sk; | 957 | struct sock *sk = sock->sk; |
@@ -969,6 +1042,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) | |||
969 | { | 1042 | { |
970 | struct sock *sk, *parent = chan->data; | 1043 | struct sock *sk, *parent = chan->data; |
971 | 1044 | ||
1045 | lock_sock(parent); | ||
1046 | |||
972 | /* Check for backlog size */ | 1047 | /* Check for backlog size */ |
973 | if (sk_acceptq_is_full(parent)) { | 1048 | if (sk_acceptq_is_full(parent)) { |
974 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | 1049 | BT_DBG("backlog full %d", parent->sk_ack_backlog); |
@@ -986,6 +1061,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) | |||
986 | 1061 | ||
987 | bt_accept_enqueue(parent, sk); | 1062 | bt_accept_enqueue(parent, sk); |
988 | 1063 | ||
1064 | release_sock(parent); | ||
1065 | |||
989 | return l2cap_pi(sk)->chan; | 1066 | return l2cap_pi(sk)->chan; |
990 | } | 1067 | } |
991 | 1068 | ||
@@ -1072,26 +1149,33 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) | |||
1072 | release_sock(sk); | 1149 | release_sock(sk); |
1073 | } | 1150 | } |
1074 | 1151 | ||
1075 | static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state) | 1152 | static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state, |
1153 | int err) | ||
1076 | { | 1154 | { |
1077 | struct sock *sk = chan->data; | 1155 | struct sock *sk = chan->data; |
1078 | 1156 | ||
1079 | sk->sk_state = state; | 1157 | sk->sk_state = state; |
1158 | |||
1159 | if (err) | ||
1160 | sk->sk_err = err; | ||
1080 | } | 1161 | } |
1081 | 1162 | ||
1082 | static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, | 1163 | static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, |
1083 | unsigned long len, int nb) | 1164 | unsigned long len, int nb) |
1084 | { | 1165 | { |
1166 | struct sock *sk = chan->data; | ||
1085 | struct sk_buff *skb; | 1167 | struct sk_buff *skb; |
1086 | int err; | 1168 | int err; |
1087 | 1169 | ||
1088 | l2cap_chan_unlock(chan); | 1170 | l2cap_chan_unlock(chan); |
1089 | skb = bt_skb_send_alloc(chan->sk, len, nb, &err); | 1171 | skb = bt_skb_send_alloc(sk, len, nb, &err); |
1090 | l2cap_chan_lock(chan); | 1172 | l2cap_chan_lock(chan); |
1091 | 1173 | ||
1092 | if (!skb) | 1174 | if (!skb) |
1093 | return ERR_PTR(err); | 1175 | return ERR_PTR(err); |
1094 | 1176 | ||
1177 | bt_cb(skb)->chan = chan; | ||
1178 | |||
1095 | return skb; | 1179 | return skb; |
1096 | } | 1180 | } |
1097 | 1181 | ||
@@ -1117,11 +1201,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan) | |||
1117 | 1201 | ||
1118 | static void l2cap_sock_defer_cb(struct l2cap_chan *chan) | 1202 | static void l2cap_sock_defer_cb(struct l2cap_chan *chan) |
1119 | { | 1203 | { |
1120 | struct sock *sk = chan->data; | 1204 | struct sock *parent, *sk = chan->data; |
1121 | struct sock *parent = bt_sk(sk)->parent; | 1205 | |
1206 | lock_sock(sk); | ||
1122 | 1207 | ||
1208 | parent = bt_sk(sk)->parent; | ||
1123 | if (parent) | 1209 | if (parent) |
1124 | parent->sk_data_ready(parent, 0); | 1210 | parent->sk_data_ready(parent, 0); |
1211 | |||
1212 | release_sock(sk); | ||
1125 | } | 1213 | } |
1126 | 1214 | ||
1127 | static void l2cap_sock_resume_cb(struct l2cap_chan *chan) | 1215 | static void l2cap_sock_resume_cb(struct l2cap_chan *chan) |
@@ -1132,6 +1220,22 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan) | |||
1132 | sk->sk_state_change(sk); | 1220 | sk->sk_state_change(sk); |
1133 | } | 1221 | } |
1134 | 1222 | ||
1223 | static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan) | ||
1224 | { | ||
1225 | struct sock *sk = chan->data; | ||
1226 | |||
1227 | lock_sock(sk); | ||
1228 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
1229 | release_sock(sk); | ||
1230 | } | ||
1231 | |||
1232 | static long l2cap_sock_get_sndtimeo_cb(struct l2cap_chan *chan) | ||
1233 | { | ||
1234 | struct sock *sk = chan->data; | ||
1235 | |||
1236 | return sk->sk_sndtimeo; | ||
1237 | } | ||
1238 | |||
1135 | static struct l2cap_ops l2cap_chan_ops = { | 1239 | static struct l2cap_ops l2cap_chan_ops = { |
1136 | .name = "L2CAP Socket Interface", | 1240 | .name = "L2CAP Socket Interface", |
1137 | .new_connection = l2cap_sock_new_connection_cb, | 1241 | .new_connection = l2cap_sock_new_connection_cb, |
@@ -1142,6 +1246,8 @@ static struct l2cap_ops l2cap_chan_ops = { | |||
1142 | .ready = l2cap_sock_ready_cb, | 1246 | .ready = l2cap_sock_ready_cb, |
1143 | .defer = l2cap_sock_defer_cb, | 1247 | .defer = l2cap_sock_defer_cb, |
1144 | .resume = l2cap_sock_resume_cb, | 1248 | .resume = l2cap_sock_resume_cb, |
1249 | .set_shutdown = l2cap_sock_set_shutdown_cb, | ||
1250 | .get_sndtimeo = l2cap_sock_get_sndtimeo_cb, | ||
1145 | .alloc_skb = l2cap_sock_alloc_skb_cb, | 1251 | .alloc_skb = l2cap_sock_alloc_skb_cb, |
1146 | }; | 1252 | }; |
1147 | 1253 | ||
@@ -1268,8 +1374,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | |||
1268 | 1374 | ||
1269 | l2cap_chan_hold(chan); | 1375 | l2cap_chan_hold(chan); |
1270 | 1376 | ||
1271 | chan->sk = sk; | ||
1272 | |||
1273 | l2cap_pi(sk)->chan = chan; | 1377 | l2cap_pi(sk)->chan = chan; |
1274 | 1378 | ||
1275 | return sk; | 1379 | return sk; |