Skip to content

Commit 4f39512

Browse files
committed
Bluetooth: L2CAP: Fix not validating setsockopt user input
Check user input length before copying data. Fixes: 33575df ("Bluetooth: move l2cap_sock_setsockopt() to l2cap_sock.c") Fixes: 3ee7b7c ("Bluetooth: Add BT_MODE socket option") Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent a97de7b commit 4f39512

File tree

1 file changed

+20
-32
lines changed

1 file changed

+20
-32
lines changed

net/bluetooth/l2cap_sock.c

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
727727
struct sock *sk = sock->sk;
728728
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
729729
struct l2cap_options opts;
730-
int len, err = 0;
730+
int err = 0;
731731
u32 opt;
732732

733733
BT_DBG("sk %p", sk);
@@ -754,11 +754,9 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
754754
opts.max_tx = chan->max_tx;
755755
opts.txwin_size = chan->tx_win;
756756

757-
len = min_t(unsigned int, sizeof(opts), optlen);
758-
if (copy_from_sockptr(&opts, optval, len)) {
759-
err = -EFAULT;
757+
err = bt_copy_from_sockptr(&opts, sizeof(opts), optval, optlen);
758+
if (err)
760759
break;
761-
}
762760

763761
if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
764762
err = -EINVAL;
@@ -801,10 +799,9 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
801799
break;
802800

803801
case L2CAP_LM:
804-
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
805-
err = -EFAULT;
802+
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
803+
if (err)
806804
break;
807-
}
808805

809806
if (opt & L2CAP_LM_FIPS) {
810807
err = -EINVAL;
@@ -885,7 +882,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
885882
struct bt_security sec;
886883
struct bt_power pwr;
887884
struct l2cap_conn *conn;
888-
int len, err = 0;
885+
int err = 0;
889886
u32 opt;
890887
u16 mtu;
891888
u8 mode;
@@ -911,11 +908,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
911908

912909
sec.level = BT_SECURITY_LOW;
913910

914-
len = min_t(unsigned int, sizeof(sec), optlen);
915-
if (copy_from_sockptr(&sec, optval, len)) {
916-
err = -EFAULT;
911+
err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
912+
if (err)
917913
break;
918-
}
919914

920915
if (sec.level < BT_SECURITY_LOW ||
921916
sec.level > BT_SECURITY_FIPS) {
@@ -960,10 +955,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
960955
break;
961956
}
962957

963-
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
964-
err = -EFAULT;
958+
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
959+
if (err)
965960
break;
966-
}
967961

968962
if (opt) {
969963
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
@@ -975,10 +969,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
975969
break;
976970

977971
case BT_FLUSHABLE:
978-
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
979-
err = -EFAULT;
972+
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
973+
if (err)
980974
break;
981-
}
982975

983976
if (opt > BT_FLUSHABLE_ON) {
984977
err = -EINVAL;
@@ -1010,11 +1003,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10101003

10111004
pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
10121005

1013-
len = min_t(unsigned int, sizeof(pwr), optlen);
1014-
if (copy_from_sockptr(&pwr, optval, len)) {
1015-
err = -EFAULT;
1006+
err = bt_copy_from_sockptr(&pwr, sizeof(pwr), optval, optlen);
1007+
if (err)
10161008
break;
1017-
}
10181009

10191010
if (pwr.force_active)
10201011
set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
@@ -1023,10 +1014,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10231014
break;
10241015

10251016
case BT_CHANNEL_POLICY:
1026-
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
1027-
err = -EFAULT;
1017+
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
1018+
if (err)
10281019
break;
1029-
}
10301020

10311021
err = -EOPNOTSUPP;
10321022
break;
@@ -1055,10 +1045,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10551045
break;
10561046
}
10571047

1058-
if (copy_from_sockptr(&mtu, optval, sizeof(u16))) {
1059-
err = -EFAULT;
1048+
err = bt_copy_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
1049+
if (err)
10601050
break;
1061-
}
10621051

10631052
if (chan->mode == L2CAP_MODE_EXT_FLOWCTL &&
10641053
sk->sk_state == BT_CONNECTED)
@@ -1086,10 +1075,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
10861075
break;
10871076
}
10881077

1089-
if (copy_from_sockptr(&mode, optval, sizeof(u8))) {
1090-
err = -EFAULT;
1078+
err = bt_copy_from_sockptr(&mode, sizeof(mode), optval, optlen);
1079+
if (err)
10911080
break;
1092-
}
10931081

10941082
BT_DBG("mode %u", mode);
10951083

0 commit comments

Comments
 (0)