diff options
Diffstat (limited to 'net/bluetooth')
| -rw-r--r-- | net/bluetooth/cmtp/capi.c | 39 | ||||
| -rw-r--r-- | net/bluetooth/hci_sysfs.c | 7 | ||||
| -rw-r--r-- | net/bluetooth/rfcomm/sock.c | 9 | ||||
| -rw-r--r-- | net/bluetooth/rfcomm/tty.c | 22 |
4 files changed, 60 insertions, 17 deletions
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index be04e9fb11f6..ab166b48ce8d 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
| @@ -196,6 +196,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s | |||
| 196 | 196 | ||
| 197 | switch (CAPIMSG_SUBCOMMAND(skb->data)) { | 197 | switch (CAPIMSG_SUBCOMMAND(skb->data)) { |
| 198 | case CAPI_CONF: | 198 | case CAPI_CONF: |
| 199 | if (skb->len < CAPI_MSG_BASELEN + 10) | ||
| 200 | break; | ||
| 201 | |||
| 199 | func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); | 202 | func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); |
| 200 | info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); | 203 | info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); |
| 201 | 204 | ||
| @@ -226,6 +229,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s | |||
| 226 | break; | 229 | break; |
| 227 | 230 | ||
| 228 | case CAPI_FUNCTION_GET_PROFILE: | 231 | case CAPI_FUNCTION_GET_PROFILE: |
| 232 | if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile)) | ||
| 233 | break; | ||
| 234 | |||
| 229 | controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); | 235 | controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); |
| 230 | msgnum = CAPIMSG_MSGID(skb->data); | 236 | msgnum = CAPIMSG_MSGID(skb->data); |
| 231 | 237 | ||
| @@ -246,17 +252,26 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s | |||
| 246 | break; | 252 | break; |
| 247 | 253 | ||
| 248 | case CAPI_FUNCTION_GET_MANUFACTURER: | 254 | case CAPI_FUNCTION_GET_MANUFACTURER: |
| 255 | if (skb->len < CAPI_MSG_BASELEN + 15) | ||
| 256 | break; | ||
| 257 | |||
| 249 | controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); | 258 | controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); |
| 250 | 259 | ||
| 251 | if (!info && ctrl) { | 260 | if (!info && ctrl) { |
| 261 | int len = min_t(uint, CAPI_MANUFACTURER_LEN, | ||
| 262 | skb->data[CAPI_MSG_BASELEN + 14]); | ||
| 263 | |||
| 264 | memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN); | ||
| 252 | strncpy(ctrl->manu, | 265 | strncpy(ctrl->manu, |
| 253 | skb->data + CAPI_MSG_BASELEN + 15, | 266 | skb->data + CAPI_MSG_BASELEN + 15, len); |
| 254 | skb->data[CAPI_MSG_BASELEN + 14]); | ||
| 255 | } | 267 | } |
| 256 | 268 | ||
| 257 | break; | 269 | break; |
| 258 | 270 | ||
| 259 | case CAPI_FUNCTION_GET_VERSION: | 271 | case CAPI_FUNCTION_GET_VERSION: |
| 272 | if (skb->len < CAPI_MSG_BASELEN + 32) | ||
| 273 | break; | ||
| 274 | |||
| 260 | controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); | 275 | controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); |
| 261 | 276 | ||
| 262 | if (!info && ctrl) { | 277 | if (!info && ctrl) { |
| @@ -269,13 +284,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s | |||
| 269 | break; | 284 | break; |
| 270 | 285 | ||
| 271 | case CAPI_FUNCTION_GET_SERIAL_NUMBER: | 286 | case CAPI_FUNCTION_GET_SERIAL_NUMBER: |
| 287 | if (skb->len < CAPI_MSG_BASELEN + 17) | ||
| 288 | break; | ||
| 289 | |||
| 272 | controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); | 290 | controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); |
| 273 | 291 | ||
| 274 | if (!info && ctrl) { | 292 | if (!info && ctrl) { |
| 293 | int len = min_t(uint, CAPI_SERIAL_LEN, | ||
| 294 | skb->data[CAPI_MSG_BASELEN + 16]); | ||
| 295 | |||
| 275 | memset(ctrl->serial, 0, CAPI_SERIAL_LEN); | 296 | memset(ctrl->serial, 0, CAPI_SERIAL_LEN); |
| 276 | strncpy(ctrl->serial, | 297 | strncpy(ctrl->serial, |
| 277 | skb->data + CAPI_MSG_BASELEN + 17, | 298 | skb->data + CAPI_MSG_BASELEN + 17, len); |
| 278 | skb->data[CAPI_MSG_BASELEN + 16]); | ||
| 279 | } | 299 | } |
| 280 | 300 | ||
| 281 | break; | 301 | break; |
| @@ -284,14 +304,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s | |||
| 284 | break; | 304 | break; |
| 285 | 305 | ||
| 286 | case CAPI_IND: | 306 | case CAPI_IND: |
| 307 | if (skb->len < CAPI_MSG_BASELEN + 6) | ||
| 308 | break; | ||
| 309 | |||
| 287 | func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); | 310 | func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); |
| 288 | 311 | ||
| 289 | if (func == CAPI_FUNCTION_LOOPBACK) { | 312 | if (func == CAPI_FUNCTION_LOOPBACK) { |
| 313 | int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6, | ||
| 314 | skb->data[CAPI_MSG_BASELEN + 5]); | ||
| 290 | appl = CAPIMSG_APPID(skb->data); | 315 | appl = CAPIMSG_APPID(skb->data); |
| 291 | msgnum = CAPIMSG_MSGID(skb->data); | 316 | msgnum = CAPIMSG_MSGID(skb->data); |
| 292 | cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, | 317 | cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, |
| 293 | skb->data + CAPI_MSG_BASELEN + 6, | 318 | skb->data + CAPI_MSG_BASELEN + 6, len); |
| 294 | skb->data[CAPI_MSG_BASELEN + 5]); | ||
| 295 | } | 319 | } |
| 296 | 320 | ||
| 297 | break; | 321 | break; |
| @@ -309,6 +333,9 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) | |||
| 309 | 333 | ||
| 310 | BT_DBG("session %p skb %p len %d", session, skb, skb->len); | 334 | BT_DBG("session %p skb %p len %d", session, skb, skb->len); |
| 311 | 335 | ||
| 336 | if (skb->len < CAPI_MSG_BASELEN) | ||
| 337 | return; | ||
| 338 | |||
| 312 | if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { | 339 | if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { |
| 313 | cmtp_recv_interopmsg(session, skb); | 340 | cmtp_recv_interopmsg(session, skb); |
| 314 | return; | 341 | return; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index d4c935692ccf..801d687ea4ef 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
| @@ -242,7 +242,7 @@ static void add_conn(struct work_struct *work) | |||
| 242 | struct hci_conn *conn = container_of(work, struct hci_conn, work); | 242 | struct hci_conn *conn = container_of(work, struct hci_conn, work); |
| 243 | int i; | 243 | int i; |
| 244 | 244 | ||
| 245 | if (device_register(&conn->dev) < 0) { | 245 | if (device_add(&conn->dev) < 0) { |
| 246 | BT_ERR("Failed to register connection device"); | 246 | BT_ERR("Failed to register connection device"); |
| 247 | return; | 247 | return; |
| 248 | } | 248 | } |
| @@ -272,6 +272,8 @@ void hci_conn_add_sysfs(struct hci_conn *conn) | |||
| 272 | 272 | ||
| 273 | dev_set_drvdata(&conn->dev, conn); | 273 | dev_set_drvdata(&conn->dev, conn); |
| 274 | 274 | ||
| 275 | device_initialize(&conn->dev); | ||
| 276 | |||
| 275 | INIT_WORK(&conn->work, add_conn); | 277 | INIT_WORK(&conn->work, add_conn); |
| 276 | 278 | ||
| 277 | schedule_work(&conn->work); | 279 | schedule_work(&conn->work); |
| @@ -287,6 +289,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn) | |||
| 287 | { | 289 | { |
| 288 | BT_DBG("conn %p", conn); | 290 | BT_DBG("conn %p", conn); |
| 289 | 291 | ||
| 292 | if (!device_is_registered(&conn->dev)) | ||
| 293 | return; | ||
| 294 | |||
| 290 | INIT_WORK(&conn->work, del_conn); | 295 | INIT_WORK(&conn->work, del_conn); |
| 291 | 296 | ||
| 292 | schedule_work(&conn->work); | 297 | schedule_work(&conn->work); |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 544d65b7baa7..cb7e855f0828 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
| @@ -557,7 +557,6 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 557 | struct sock *sk = sock->sk; | 557 | struct sock *sk = sock->sk; |
| 558 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; | 558 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; |
| 559 | struct sk_buff *skb; | 559 | struct sk_buff *skb; |
| 560 | int err; | ||
| 561 | int sent = 0; | 560 | int sent = 0; |
| 562 | 561 | ||
| 563 | if (msg->msg_flags & MSG_OOB) | 562 | if (msg->msg_flags & MSG_OOB) |
| @@ -572,6 +571,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 572 | 571 | ||
| 573 | while (len) { | 572 | while (len) { |
| 574 | size_t size = min_t(size_t, len, d->mtu); | 573 | size_t size = min_t(size_t, len, d->mtu); |
| 574 | int err; | ||
| 575 | 575 | ||
| 576 | skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, | 576 | skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, |
| 577 | msg->msg_flags & MSG_DONTWAIT, &err); | 577 | msg->msg_flags & MSG_DONTWAIT, &err); |
| @@ -582,13 +582,16 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 582 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 582 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
| 583 | if (err) { | 583 | if (err) { |
| 584 | kfree_skb(skb); | 584 | kfree_skb(skb); |
| 585 | sent = err; | 585 | if (sent == 0) |
| 586 | sent = err; | ||
| 586 | break; | 587 | break; |
| 587 | } | 588 | } |
| 588 | 589 | ||
| 589 | err = rfcomm_dlc_send(d, skb); | 590 | err = rfcomm_dlc_send(d, skb); |
| 590 | if (err < 0) { | 591 | if (err < 0) { |
| 591 | kfree_skb(skb); | 592 | kfree_skb(skb); |
| 593 | if (sent == 0) | ||
| 594 | sent = err; | ||
| 592 | break; | 595 | break; |
| 593 | } | 596 | } |
| 594 | 597 | ||
| @@ -598,7 +601,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 598 | 601 | ||
| 599 | release_sock(sk); | 602 | release_sock(sk); |
| 600 | 603 | ||
| 601 | return sent ? sent : err; | 604 | return sent; |
| 602 | } | 605 | } |
| 603 | 606 | ||
| 604 | static long rfcomm_sock_data_wait(struct sock *sk, long timeo) | 607 | static long rfcomm_sock_data_wait(struct sock *sk, long timeo) |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index e0e0d09023b2..eb2b52484c70 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
| @@ -697,9 +697,13 @@ static int rfcomm_tty_write_room(struct tty_struct *tty) | |||
| 697 | 697 | ||
| 698 | BT_DBG("tty %p", tty); | 698 | BT_DBG("tty %p", tty); |
| 699 | 699 | ||
| 700 | if (!dev || !dev->dlc) | ||
| 701 | return 0; | ||
| 702 | |||
| 700 | room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc); | 703 | room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc); |
| 701 | if (room < 0) | 704 | if (room < 0) |
| 702 | room = 0; | 705 | room = 0; |
| 706 | |||
| 703 | return room; | 707 | return room; |
| 704 | } | 708 | } |
| 705 | 709 | ||
| @@ -915,12 +919,14 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty) | |||
| 915 | static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) | 919 | static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) |
| 916 | { | 920 | { |
| 917 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; | 921 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; |
| 918 | struct rfcomm_dlc *dlc = dev->dlc; | ||
| 919 | 922 | ||
| 920 | BT_DBG("tty %p dev %p", tty, dev); | 923 | BT_DBG("tty %p dev %p", tty, dev); |
| 921 | 924 | ||
| 922 | if (!skb_queue_empty(&dlc->tx_queue)) | 925 | if (!dev || !dev->dlc) |
| 923 | return dlc->mtu; | 926 | return 0; |
| 927 | |||
| 928 | if (!skb_queue_empty(&dev->dlc->tx_queue)) | ||
| 929 | return dev->dlc->mtu; | ||
| 924 | 930 | ||
| 925 | return 0; | 931 | return 0; |
| 926 | } | 932 | } |
| @@ -928,11 +934,12 @@ static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) | |||
| 928 | static void rfcomm_tty_flush_buffer(struct tty_struct *tty) | 934 | static void rfcomm_tty_flush_buffer(struct tty_struct *tty) |
| 929 | { | 935 | { |
| 930 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; | 936 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; |
| 931 | if (!dev) | ||
| 932 | return; | ||
| 933 | 937 | ||
| 934 | BT_DBG("tty %p dev %p", tty, dev); | 938 | BT_DBG("tty %p dev %p", tty, dev); |
| 935 | 939 | ||
| 940 | if (!dev || !dev->dlc) | ||
| 941 | return; | ||
| 942 | |||
| 936 | skb_queue_purge(&dev->dlc->tx_queue); | 943 | skb_queue_purge(&dev->dlc->tx_queue); |
| 937 | 944 | ||
| 938 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup) | 945 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup) |
| @@ -952,11 +959,12 @@ static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) | |||
| 952 | static void rfcomm_tty_hangup(struct tty_struct *tty) | 959 | static void rfcomm_tty_hangup(struct tty_struct *tty) |
| 953 | { | 960 | { |
| 954 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; | 961 | struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; |
| 955 | if (!dev) | ||
| 956 | return; | ||
| 957 | 962 | ||
| 958 | BT_DBG("tty %p dev %p", tty, dev); | 963 | BT_DBG("tty %p dev %p", tty, dev); |
| 959 | 964 | ||
| 965 | if (!dev) | ||
| 966 | return; | ||
| 967 | |||
| 960 | rfcomm_tty_flush_buffer(tty); | 968 | rfcomm_tty_flush_buffer(tty); |
| 961 | 969 | ||
| 962 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) | 970 | if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) |
