Skip to content

Commit 51eda36

Browse files
committed
Bluetooth: SCO: Fix not validating setsockopt user input
syzbot reported sco_sock_setsockopt() is copying data without checking user input length. BUG: KASAN: slab-out-of-bounds in copy_from_sockptr_offset include/linux/sockptr.h:49 [inline] BUG: KASAN: slab-out-of-bounds in copy_from_sockptr include/linux/sockptr.h:55 [inline] BUG: KASAN: slab-out-of-bounds in sco_sock_setsockopt+0xc0b/0xf90 net/bluetooth/sco.c:893 Read of size 4 at addr ffff88805f7b15a3 by task syz-executor.5/12578 Fixes: ad10b1a ("Bluetooth: Add Bluetooth socket voice option") Fixes: b96e9c6 ("Bluetooth: Add BT_DEFER_SETUP option to sco socket") Fixes: 00398e1 ("Bluetooth: Add support for BT_PKT_STATUS CMSG data for SCO connections") Fixes: f687340 ("Bluetooth: Allow setting of codec for HFP offload use case") Reported-by: syzbot <[email protected]> Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 45d355a commit 51eda36

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,15 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
585585
return skb;
586586
}
587587

588+
static inline int bt_copy_from_sockptr(void *dst, size_t dst_size,
589+
sockptr_t src, size_t src_size)
590+
{
591+
if (dst_size > src_size)
592+
return -EINVAL;
593+
594+
return copy_from_sockptr(dst, src, dst_size);
595+
}
596+
588597
int bt_to_errno(u16 code);
589598
__u8 bt_status(int err);
590599

net/bluetooth/sco.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
824824
sockptr_t optval, unsigned int optlen)
825825
{
826826
struct sock *sk = sock->sk;
827-
int len, err = 0;
827+
int err = 0;
828828
struct bt_voice voice;
829829
u32 opt;
830830
struct bt_codecs *codecs;
@@ -843,10 +843,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
843843
break;
844844
}
845845

846-
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
847-
err = -EFAULT;
846+
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
847+
if (err)
848848
break;
849-
}
850849

851850
if (opt)
852851
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
@@ -863,11 +862,10 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
863862

864863
voice.setting = sco_pi(sk)->setting;
865864

866-
len = min_t(unsigned int, sizeof(voice), optlen);
867-
if (copy_from_sockptr(&voice, optval, len)) {
868-
err = -EFAULT;
865+
err = bt_copy_from_sockptr(&voice, sizeof(voice), optval,
866+
optlen);
867+
if (err)
869868
break;
870-
}
871869

872870
/* Explicitly check for these values */
873871
if (voice.setting != BT_VOICE_TRANSPARENT &&
@@ -890,10 +888,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
890888
break;
891889

892890
case BT_PKT_STATUS:
893-
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
894-
err = -EFAULT;
891+
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
892+
if (err)
895893
break;
896-
}
897894

898895
if (opt)
899896
set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
@@ -934,9 +931,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
934931
break;
935932
}
936933

937-
if (copy_from_sockptr(buffer, optval, optlen)) {
934+
err = bt_copy_from_sockptr(buffer, optlen, optval, optlen);
935+
if (err) {
938936
hci_dev_put(hdev);
939-
err = -EFAULT;
940937
break;
941938
}
942939

0 commit comments

Comments
 (0)