aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorSzymon Janc <szymon.janc@tieto.com>2011-02-25 13:05:49 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-27 14:57:07 -0500
commitbdce7bafb786701004b2055e15d6ff4b3be678f3 (patch)
tree8293fd5214b73b1398ce0cd7386645f736b9b01e /net/bluetooth/mgmt.c
parent4e51eae9cdda4bf096e73a4ebe23f8f96a17596a (diff)
Bluetooth: Validate data size before accessing mgmt commands
Crafted (too small) data buffer could result in reading data outside of buffer. Validate buffer size and return EINVAL if size is wrong. Signed-off-by: Szymon Janc <szymon.janc@tieto.com> Acked-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 98c92aee623..16c7a4d0432 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -302,6 +302,9 @@ static int set_powered(struct sock *sk, u16 index, unsigned char *data, u16 len)
302 302
303 BT_DBG("request for hci%u", index); 303 BT_DBG("request for hci%u", index);
304 304
305 if (len != sizeof(*cp))
306 return cmd_status(sk, index, MGMT_OP_SET_POWERED, EINVAL);
307
305 hdev = hci_dev_get(index); 308 hdev = hci_dev_get(index);
306 if (!hdev) 309 if (!hdev)
307 return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV); 310 return cmd_status(sk, index, MGMT_OP_SET_POWERED, ENODEV);
@@ -351,6 +354,9 @@ static int set_discoverable(struct sock *sk, u16 index, unsigned char *data,
351 354
352 BT_DBG("request for hci%u", index); 355 BT_DBG("request for hci%u", index);
353 356
357 if (len != sizeof(*cp))
358 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, EINVAL);
359
354 hdev = hci_dev_get(index); 360 hdev = hci_dev_get(index);
355 if (!hdev) 361 if (!hdev)
356 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV); 362 return cmd_status(sk, index, MGMT_OP_SET_DISCOVERABLE, ENODEV);
@@ -409,6 +415,9 @@ static int set_connectable(struct sock *sk, u16 index, unsigned char *data,
409 415
410 BT_DBG("request for hci%u", index); 416 BT_DBG("request for hci%u", index);
411 417
418 if (len != sizeof(*cp))
419 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, EINVAL);
420
412 hdev = hci_dev_get(index); 421 hdev = hci_dev_get(index);
413 if (!hdev) 422 if (!hdev)
414 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV); 423 return cmd_status(sk, index, MGMT_OP_SET_CONNECTABLE, ENODEV);
@@ -499,6 +508,9 @@ static int set_pairable(struct sock *sk, u16 index, unsigned char *data,
499 508
500 BT_DBG("request for hci%u", index); 509 BT_DBG("request for hci%u", index);
501 510
511 if (len != sizeof(*cp))
512 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, EINVAL);
513
502 hdev = hci_dev_get(index); 514 hdev = hci_dev_get(index);
503 if (!hdev) 515 if (!hdev)
504 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV); 516 return cmd_status(sk, index, MGMT_OP_SET_PAIRABLE, ENODEV);
@@ -569,6 +581,9 @@ static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
569 581
570 BT_DBG("request for hci%u", index); 582 BT_DBG("request for hci%u", index);
571 583
584 if (len != sizeof(*cp))
585 return cmd_status(sk, index, MGMT_OP_ADD_UUID, EINVAL);
586
572 hdev = hci_dev_get(index); 587 hdev = hci_dev_get(index);
573 if (!hdev) 588 if (!hdev)
574 return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV); 589 return cmd_status(sk, index, MGMT_OP_ADD_UUID, ENODEV);
@@ -611,6 +626,9 @@ static int remove_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len)
611 626
612 BT_DBG("request for hci%u", index); 627 BT_DBG("request for hci%u", index);
613 628
629 if (len != sizeof(*cp))
630 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, EINVAL);
631
614 hdev = hci_dev_get(index); 632 hdev = hci_dev_get(index);
615 if (!hdev) 633 if (!hdev)
616 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV); 634 return cmd_status(sk, index, MGMT_OP_REMOVE_UUID, ENODEV);
@@ -663,6 +681,9 @@ static int set_dev_class(struct sock *sk, u16 index, unsigned char *data,
663 681
664 BT_DBG("request for hci%u", index); 682 BT_DBG("request for hci%u", index);
665 683
684 if (len != sizeof(*cp))
685 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, EINVAL);
686
666 hdev = hci_dev_get(index); 687 hdev = hci_dev_get(index);
667 if (!hdev) 688 if (!hdev)
668 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV); 689 return cmd_status(sk, index, MGMT_OP_SET_DEV_CLASS, ENODEV);
@@ -692,6 +713,10 @@ static int set_service_cache(struct sock *sk, u16 index, unsigned char *data,
692 713
693 cp = (void *) data; 714 cp = (void *) data;
694 715
716 if (len != sizeof(*cp))
717 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE,
718 EINVAL);
719
695 hdev = hci_dev_get(index); 720 hdev = hci_dev_get(index);
696 if (!hdev) 721 if (!hdev)
697 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV); 722 return cmd_status(sk, index, MGMT_OP_SET_SERVICE_CACHE, ENODEV);
@@ -726,6 +751,10 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
726 int i; 751 int i;
727 752
728 cp = (void *) data; 753 cp = (void *) data;
754
755 if (len < sizeof(*cp))
756 return -EINVAL;
757
729 key_count = get_unaligned_le16(&cp->key_count); 758 key_count = get_unaligned_le16(&cp->key_count);
730 759
731 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); 760 expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info);
@@ -775,6 +804,9 @@ static int remove_key(struct sock *sk, u16 index, unsigned char *data, u16 len)
775 804
776 cp = (void *) data; 805 cp = (void *) data;
777 806
807 if (len != sizeof(*cp))
808 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, EINVAL);
809
778 hdev = hci_dev_get(index); 810 hdev = hci_dev_get(index);
779 if (!hdev) 811 if (!hdev)
780 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV); 812 return cmd_status(sk, index, MGMT_OP_REMOVE_KEY, ENODEV);
@@ -821,6 +853,9 @@ static int disconnect(struct sock *sk, u16 index, unsigned char *data, u16 len)
821 853
822 cp = (void *) data; 854 cp = (void *) data;
823 855
856 if (len != sizeof(*cp))
857 return cmd_status(sk, index, MGMT_OP_DISCONNECT, EINVAL);
858
824 hdev = hci_dev_get(index); 859 hdev = hci_dev_get(index);
825 if (!hdev) 860 if (!hdev)
826 return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV); 861 return cmd_status(sk, index, MGMT_OP_DISCONNECT, ENODEV);
@@ -931,6 +966,9 @@ static int pin_code_reply(struct sock *sk, u16 index, unsigned char *data,
931 966
932 cp = (void *) data; 967 cp = (void *) data;
933 968
969 if (len != sizeof(*cp))
970 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, EINVAL);
971
934 hdev = hci_dev_get(index); 972 hdev = hci_dev_get(index);
935 if (!hdev) 973 if (!hdev)
936 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV); 974 return cmd_status(sk, index, MGMT_OP_PIN_CODE_REPLY, ENODEV);
@@ -975,6 +1013,10 @@ static int pin_code_neg_reply(struct sock *sk, u16 index, unsigned char *data,
975 1013
976 cp = (void *) data; 1014 cp = (void *) data;
977 1015
1016 if (len != sizeof(*cp))
1017 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
1018 EINVAL);
1019
978 hdev = hci_dev_get(index); 1020 hdev = hci_dev_get(index);
979 if (!hdev) 1021 if (!hdev)
980 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY, 1022 return cmd_status(sk, index, MGMT_OP_PIN_CODE_NEG_REPLY,
@@ -1017,6 +1059,10 @@ static int set_io_capability(struct sock *sk, u16 index, unsigned char *data,
1017 1059
1018 cp = (void *) data; 1060 cp = (void *) data;
1019 1061
1062 if (len != sizeof(*cp))
1063 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY,
1064 EINVAL);
1065
1020 hdev = hci_dev_get(index); 1066 hdev = hci_dev_get(index);
1021 if (!hdev) 1067 if (!hdev)
1022 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV); 1068 return cmd_status(sk, index, MGMT_OP_SET_IO_CAPABILITY, ENODEV);
@@ -1107,6 +1153,9 @@ static int pair_device(struct sock *sk, u16 index, unsigned char *data, u16 len)
1107 1153
1108 cp = (void *) data; 1154 cp = (void *) data;
1109 1155
1156 if (len != sizeof(*cp))
1157 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, EINVAL);
1158
1110 hdev = hci_dev_get(index); 1159 hdev = hci_dev_get(index);
1111 if (!hdev) 1160 if (!hdev)
1112 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV); 1161 return cmd_status(sk, index, MGMT_OP_PAIR_DEVICE, ENODEV);
@@ -1178,6 +1227,9 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data,
1178 hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY; 1227 hci_op = HCI_OP_USER_CONFIRM_NEG_REPLY;
1179 } 1228 }
1180 1229
1230 if (len != sizeof(*cp))
1231 return cmd_status(sk, index, mgmt_op, EINVAL);
1232
1181 hdev = hci_dev_get(index); 1233 hdev = hci_dev_get(index);
1182 if (!hdev) 1234 if (!hdev)
1183 return cmd_status(sk, index, mgmt_op, ENODEV); 1235 return cmd_status(sk, index, mgmt_op, ENODEV);