Skip to content

Commit 2486f6e

Browse files
author
Bastien Nocera
committed
Bluetooth: Improve setsockopt() handling of malformed user input
JIRA: https://issues.redhat.com/browse/RHEL-74483 commit 3e643e4 Author: Michal Luczaj <[email protected]> Date: Tue Nov 19 14:31:40 2024 +0100 Bluetooth: Improve setsockopt() handling of malformed user input The bt_copy_from_sockptr() return value is being misinterpreted by most users: a non-zero result is mistakenly assumed to represent an error code, but actually indicates the number of bytes that could not be copied. Remove bt_copy_from_sockptr() and adapt callers to use copy_safe_from_sockptr(). For sco_sock_setsockopt() (case BT_CODEC) use copy_struct_from_sockptr() to scrub parts of uninitialized buffer. Opportunistically, rename `len` to `optlen` in hci_sock_setsockopt_old() and hci_sock_setsockopt(). Fixes: 51eda36 ("Bluetooth: SCO: Fix not validating setsockopt user input") Fixes: a97de7b ("Bluetooth: RFCOMM: Fix not validating setsockopt user input") Fixes: 4f39512 ("Bluetooth: L2CAP: Fix not validating setsockopt user input") Fixes: 9e8742c ("Bluetooth: ISO: Fix not validating setsockopt user input") Fixes: b218606 ("Bluetooth: hci_sock: Fix not validating setsockopt user input") Reviewed-by: Luiz Augusto von Dentz <[email protected]> Reviewed-by: David Wei <[email protected]> Signed-off-by: Michal Luczaj <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]> Signed-off-by: Bastien Nocera <[email protected]>
1 parent 5fd497e commit 2486f6e

File tree

6 files changed

+33
-40
lines changed

6 files changed

+33
-40
lines changed

include/net/bluetooth/bluetooth.h

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

593-
static inline int bt_copy_from_sockptr(void *dst, size_t dst_size,
594-
sockptr_t src, size_t src_size)
595-
{
596-
if (dst_size > src_size)
597-
return -EINVAL;
598-
599-
return copy_from_sockptr(dst, src, dst_size);
600-
}
601-
602593
int bt_to_errno(u16 code);
603594
__u8 bt_status(int err);
604595

net/bluetooth/hci_sock.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
19381938
}
19391939

19401940
static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
1941-
sockptr_t optval, unsigned int len)
1941+
sockptr_t optval, unsigned int optlen)
19421942
{
19431943
struct hci_ufilter uf = { .opcode = 0 };
19441944
struct sock *sk = sock->sk;
@@ -1955,7 +1955,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
19551955

19561956
switch (optname) {
19571957
case HCI_DATA_DIR:
1958-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
1958+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
19591959
if (err)
19601960
break;
19611961

@@ -1966,7 +1966,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
19661966
break;
19671967

19681968
case HCI_TIME_STAMP:
1969-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
1969+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
19701970
if (err)
19711971
break;
19721972

@@ -1986,7 +1986,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
19861986
uf.event_mask[1] = *((u32 *) f->event_mask + 1);
19871987
}
19881988

1989-
err = bt_copy_from_sockptr(&uf, sizeof(uf), optval, len);
1989+
err = copy_safe_from_sockptr(&uf, sizeof(uf), optval, optlen);
19901990
if (err)
19911991
break;
19921992

@@ -2017,7 +2017,7 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
20172017
}
20182018

20192019
static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
2020-
sockptr_t optval, unsigned int len)
2020+
sockptr_t optval, unsigned int optlen)
20212021
{
20222022
struct sock *sk = sock->sk;
20232023
int err = 0;
@@ -2027,7 +2027,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
20272027

20282028
if (level == SOL_HCI)
20292029
return hci_sock_setsockopt_old(sock, level, optname, optval,
2030-
len);
2030+
optlen);
20312031

20322032
if (level != SOL_BLUETOOTH)
20332033
return -ENOPROTOOPT;
@@ -2047,7 +2047,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
20472047
goto done;
20482048
}
20492049

2050-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
2050+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
20512051
if (err)
20522052
break;
20532053

net/bluetooth/iso.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
15751575
break;
15761576
}
15771577

1578-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
1578+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
15791579
if (err)
15801580
break;
15811581

@@ -1586,7 +1586,7 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
15861586
break;
15871587

15881588
case BT_PKT_STATUS:
1589-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
1589+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
15901590
if (err)
15911591
break;
15921592

@@ -1605,7 +1605,7 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
16051605
break;
16061606
}
16071607

1608-
err = bt_copy_from_sockptr(&qos, sizeof(qos), optval, optlen);
1608+
err = copy_safe_from_sockptr(&qos, sizeof(qos), optval, optlen);
16091609
if (err)
16101610
break;
16111611

@@ -1626,8 +1626,8 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
16261626
break;
16271627
}
16281628

1629-
err = bt_copy_from_sockptr(iso_pi(sk)->base, optlen, optval,
1630-
optlen);
1629+
err = copy_safe_from_sockptr(iso_pi(sk)->base, optlen, optval,
1630+
optlen);
16311631
if (err)
16321632
break;
16331633

net/bluetooth/l2cap_sock.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
755755
opts.max_tx = chan->max_tx;
756756
opts.txwin_size = chan->tx_win;
757757

758-
err = bt_copy_from_sockptr(&opts, sizeof(opts), optval, optlen);
758+
err = copy_safe_from_sockptr(&opts, sizeof(opts), optval,
759+
optlen);
759760
if (err)
760761
break;
761762

@@ -800,7 +801,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
800801
break;
801802

802803
case L2CAP_LM:
803-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
804+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
804805
if (err)
805806
break;
806807

@@ -909,7 +910,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
909910

910911
sec.level = BT_SECURITY_LOW;
911912

912-
err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
913+
err = copy_safe_from_sockptr(&sec, sizeof(sec), optval, optlen);
913914
if (err)
914915
break;
915916

@@ -956,7 +957,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
956957
break;
957958
}
958959

959-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
960+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
960961
if (err)
961962
break;
962963

@@ -970,7 +971,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
970971
break;
971972

972973
case BT_FLUSHABLE:
973-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
974+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
974975
if (err)
975976
break;
976977

@@ -1004,7 +1005,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10041005

10051006
pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
10061007

1007-
err = bt_copy_from_sockptr(&pwr, sizeof(pwr), optval, optlen);
1008+
err = copy_safe_from_sockptr(&pwr, sizeof(pwr), optval, optlen);
10081009
if (err)
10091010
break;
10101011

@@ -1015,7 +1016,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10151016
break;
10161017

10171018
case BT_CHANNEL_POLICY:
1018-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
1019+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
10191020
if (err)
10201021
break;
10211022

@@ -1046,7 +1047,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10461047
break;
10471048
}
10481049

1049-
err = bt_copy_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
1050+
err = copy_safe_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
10501051
if (err)
10511052
break;
10521053

@@ -1076,7 +1077,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10761077
break;
10771078
}
10781079

1079-
err = bt_copy_from_sockptr(&mode, sizeof(mode), optval, optlen);
1080+
err = copy_safe_from_sockptr(&mode, sizeof(mode), optval,
1081+
optlen);
10801082
if (err)
10811083
break;
10821084

net/bluetooth/rfcomm/sock.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,9 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname,
629629

630630
switch (optname) {
631631
case RFCOMM_LM:
632-
if (bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen)) {
633-
err = -EFAULT;
632+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
633+
if (err)
634634
break;
635-
}
636635

637636
if (opt & RFCOMM_LM_FIPS) {
638637
err = -EINVAL;
@@ -685,7 +684,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname,
685684

686685
sec.level = BT_SECURITY_LOW;
687686

688-
err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
687+
err = copy_safe_from_sockptr(&sec, sizeof(sec), optval, optlen);
689688
if (err)
690689
break;
691690

@@ -703,7 +702,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname,
703702
break;
704703
}
705704

706-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
705+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
707706
if (err)
708707
break;
709708

net/bluetooth/sco.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
896896
break;
897897
}
898898

899-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
899+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
900900
if (err)
901901
break;
902902

@@ -915,8 +915,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
915915

916916
voice.setting = sco_pi(sk)->setting;
917917

918-
err = bt_copy_from_sockptr(&voice, sizeof(voice), optval,
919-
optlen);
918+
err = copy_safe_from_sockptr(&voice, sizeof(voice), optval,
919+
optlen);
920920
if (err)
921921
break;
922922

@@ -941,7 +941,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
941941
break;
942942

943943
case BT_PKT_STATUS:
944-
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
944+
err = copy_safe_from_sockptr(&opt, sizeof(opt), optval, optlen);
945945
if (err)
946946
break;
947947

@@ -984,7 +984,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
984984
break;
985985
}
986986

987-
err = bt_copy_from_sockptr(buffer, optlen, optval, optlen);
987+
err = copy_struct_from_sockptr(buffer, sizeof(buffer), optval,
988+
optlen);
988989
if (err) {
989990
hci_dev_put(hdev);
990991
break;

0 commit comments

Comments
 (0)