Commit fe3eb406 authored by Paolo Abeni's avatar Paolo Abeni

Merge tag 'for-net-2024-04-10' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth

Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

  - L2CAP: Don't double set the HCI_CONN_MGMT_CONNECTED bit
  - Fix memory leak in hci_req_sync_complete
  - hci_sync: Fix using the same interval and window for Coded PHY
  - Fix not validating setsockopt user input

* tag 'for-net-2024-04-10' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: l2cap: Don't double set the HCI_CONN_MGMT_CONNECTED bit
  Bluetooth: hci_sock: Fix not validating setsockopt user input
  Bluetooth: ISO: Fix not validating setsockopt user input
  Bluetooth: L2CAP: Fix not validating setsockopt user input
  Bluetooth: RFCOMM: Fix not validating setsockopt user input
  Bluetooth: SCO: Fix not validating setsockopt user input
  Bluetooth: Fix memory leak in hci_req_sync_complete()
  Bluetooth: hci_sync: Fix using the same interval and window for Coded PHY
  Bluetooth: ISO: Don't reject BT_ISO_QOS if parameters are unset
====================

Link: https://lore.kernel.org/r/20240410191610.4156653-1-luiz.dentz@gmail.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 47d8ac01 600b0bbe
......@@ -585,6 +585,15 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
return skb;
}
static inline int bt_copy_from_sockptr(void *dst, size_t dst_size,
sockptr_t src, size_t src_size)
{
if (dst_size > src_size)
return -EINVAL;
return copy_from_sockptr(dst, src, dst_size);
}
int bt_to_errno(u16 code);
__u8 bt_status(int err);
......
......@@ -105,8 +105,10 @@ void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
if (hdev->req_status == HCI_REQ_PEND) {
hdev->req_result = result;
hdev->req_status = HCI_REQ_DONE;
if (skb)
if (skb) {
kfree_skb(hdev->req_skb);
hdev->req_skb = skb_get(skb);
}
wake_up_interruptible(&hdev->req_wait_q);
}
}
......
......@@ -1946,10 +1946,9 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
switch (optname) {
case HCI_DATA_DIR:
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
if (err)
break;
}
if (opt)
hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
......@@ -1958,10 +1957,9 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
break;
case HCI_TIME_STAMP:
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
if (err)
break;
}
if (opt)
hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
......@@ -1979,11 +1977,9 @@ static int hci_sock_setsockopt_old(struct socket *sock, int level, int optname,
uf.event_mask[1] = *((u32 *) f->event_mask + 1);
}
len = min_t(unsigned int, len, sizeof(uf));
if (copy_from_sockptr(&uf, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(&uf, sizeof(uf), optval, len);
if (err)
break;
}
if (!capable(CAP_NET_RAW)) {
uf.type_mask &= hci_sec_filter.type_mask;
......@@ -2042,10 +2038,9 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
goto done;
}
if (copy_from_sockptr(&opt, optval, sizeof(opt))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, len);
if (err)
break;
}
hci_pi(sk)->mtu = opt;
break;
......
......@@ -2814,8 +2814,8 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
if (qos->bcast.in.phy & BT_ISO_PHY_CODED) {
cp->scanning_phys |= LE_SCAN_PHY_CODED;
hci_le_scan_phy_params(phy, type,
interval,
window);
interval * 3,
window * 3);
num_phy++;
phy++;
}
......@@ -2835,7 +2835,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,
if (scan_coded(hdev)) {
cp->scanning_phys |= LE_SCAN_PHY_CODED;
hci_le_scan_phy_params(phy, type, interval, window);
hci_le_scan_phy_params(phy, type, interval * 3, window * 3);
num_phy++;
phy++;
}
......
......@@ -1451,8 +1451,8 @@ static bool check_ucast_qos(struct bt_iso_qos *qos)
static bool check_bcast_qos(struct bt_iso_qos *qos)
{
if (qos->bcast.sync_factor == 0x00)
return false;
if (!qos->bcast.sync_factor)
qos->bcast.sync_factor = 0x01;
if (qos->bcast.packing > 0x01)
return false;
......@@ -1475,6 +1475,9 @@ static bool check_bcast_qos(struct bt_iso_qos *qos)
if (qos->bcast.skip > 0x01f3)
return false;
if (!qos->bcast.sync_timeout)
qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
if (qos->bcast.sync_timeout < 0x000a || qos->bcast.sync_timeout > 0x4000)
return false;
......@@ -1484,6 +1487,9 @@ static bool check_bcast_qos(struct bt_iso_qos *qos)
if (qos->bcast.mse > 0x1f)
return false;
if (!qos->bcast.timeout)
qos->bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
if (qos->bcast.timeout < 0x000a || qos->bcast.timeout > 0x4000)
return false;
......@@ -1494,7 +1500,7 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
sockptr_t optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int len, err = 0;
int err = 0;
struct bt_iso_qos qos = default_qos;
u32 opt;
......@@ -1509,10 +1515,9 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt)
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
......@@ -1521,10 +1526,9 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
break;
case BT_PKT_STATUS:
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt)
set_bit(BT_SK_PKT_STATUS, &bt_sk(sk)->flags);
......@@ -1539,17 +1543,9 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
len = min_t(unsigned int, sizeof(qos), optlen);
if (copy_from_sockptr(&qos, optval, len)) {
err = -EFAULT;
break;
}
if (len == sizeof(qos.ucast) && !check_ucast_qos(&qos)) {
err = -EINVAL;
err = bt_copy_from_sockptr(&qos, sizeof(qos), optval, optlen);
if (err)
break;
}
iso_pi(sk)->qos = qos;
iso_pi(sk)->qos_user_set = true;
......@@ -1564,18 +1560,16 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
}
if (optlen > sizeof(iso_pi(sk)->base)) {
err = -EOVERFLOW;
err = -EINVAL;
break;
}
len = min_t(unsigned int, sizeof(iso_pi(sk)->base), optlen);
if (copy_from_sockptr(iso_pi(sk)->base, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(iso_pi(sk)->base, optlen, optval,
optlen);
if (err)
break;
}
iso_pi(sk)->base_len = len;
iso_pi(sk)->base_len = optlen;
break;
......
......@@ -4054,8 +4054,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
return -EPROTO;
hci_dev_lock(hdev);
if (hci_dev_test_flag(hdev, HCI_MGMT) &&
!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags))
if (hci_dev_test_flag(hdev, HCI_MGMT))
mgmt_device_connected(hdev, hcon, NULL, 0);
hci_dev_unlock(hdev);
......
......@@ -727,7 +727,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
struct sock *sk = sock->sk;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct l2cap_options opts;
int len, err = 0;
int err = 0;
u32 opt;
BT_DBG("sk %p", sk);
......@@ -754,11 +754,9 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
opts.max_tx = chan->max_tx;
opts.txwin_size = chan->tx_win;
len = min_t(unsigned int, sizeof(opts), optlen);
if (copy_from_sockptr(&opts, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opts, sizeof(opts), optval, optlen);
if (err)
break;
}
if (opts.txwin_size > L2CAP_DEFAULT_EXT_WINDOW) {
err = -EINVAL;
......@@ -801,10 +799,9 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname,
break;
case L2CAP_LM:
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt & L2CAP_LM_FIPS) {
err = -EINVAL;
......@@ -885,7 +882,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
struct bt_security sec;
struct bt_power pwr;
struct l2cap_conn *conn;
int len, err = 0;
int err = 0;
u32 opt;
u16 mtu;
u8 mode;
......@@ -911,11 +908,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
sec.level = BT_SECURITY_LOW;
len = min_t(unsigned int, sizeof(sec), optlen);
if (copy_from_sockptr(&sec, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
if (err)
break;
}
if (sec.level < BT_SECURITY_LOW ||
sec.level > BT_SECURITY_FIPS) {
......@@ -960,10 +955,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt) {
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,
break;
case BT_FLUSHABLE:
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt > BT_FLUSHABLE_ON) {
err = -EINVAL;
......@@ -1010,11 +1003,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
pwr.force_active = BT_POWER_FORCE_ACTIVE_ON;
len = min_t(unsigned int, sizeof(pwr), optlen);
if (copy_from_sockptr(&pwr, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(&pwr, sizeof(pwr), optval, optlen);
if (err)
break;
}
if (pwr.force_active)
set_bit(FLAG_FORCE_ACTIVE, &chan->flags);
......@@ -1023,10 +1014,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
case BT_CHANNEL_POLICY:
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
err = -EOPNOTSUPP;
break;
......@@ -1055,10 +1045,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (copy_from_sockptr(&mtu, optval, sizeof(u16))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&mtu, sizeof(mtu), optval, optlen);
if (err)
break;
}
if (chan->mode == L2CAP_MODE_EXT_FLOWCTL &&
sk->sk_state == BT_CONNECTED)
......@@ -1086,10 +1075,9 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (copy_from_sockptr(&mode, optval, sizeof(u8))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&mode, sizeof(mode), optval, optlen);
if (err)
break;
}
BT_DBG("mode %u", mode);
......
......@@ -629,7 +629,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname,
switch (optname) {
case RFCOMM_LM:
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
if (bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen)) {
err = -EFAULT;
break;
}
......@@ -664,7 +664,6 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk;
struct bt_security sec;
int err = 0;
size_t len;
u32 opt;
BT_DBG("sk %p", sk);
......@@ -686,11 +685,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname,
sec.level = BT_SECURITY_LOW;
len = min_t(unsigned int, sizeof(sec), optlen);
if (copy_from_sockptr(&sec, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(&sec, sizeof(sec), optval, optlen);
if (err)
break;
}
if (sec.level > BT_SECURITY_HIGH) {
err = -EINVAL;
......@@ -706,10 +703,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt)
set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
......
......@@ -824,7 +824,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
sockptr_t optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
int len, err = 0;
int err = 0;
struct bt_voice voice;
u32 opt;
struct bt_codecs *codecs;
......@@ -843,10 +843,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt)
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,
voice.setting = sco_pi(sk)->setting;
len = min_t(unsigned int, sizeof(voice), optlen);
if (copy_from_sockptr(&voice, optval, len)) {
err = -EFAULT;
err = bt_copy_from_sockptr(&voice, sizeof(voice), optval,
optlen);
if (err)
break;
}
/* Explicitly check for these values */
if (voice.setting != BT_VOICE_TRANSPARENT &&
......@@ -890,10 +888,9 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
break;
case BT_PKT_STATUS:
if (copy_from_sockptr(&opt, optval, sizeof(u32))) {
err = -EFAULT;
err = bt_copy_from_sockptr(&opt, sizeof(opt), optval, optlen);
if (err)
break;
}
if (opt)
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,
break;
}
if (copy_from_sockptr(buffer, optval, optlen)) {
err = bt_copy_from_sockptr(buffer, optlen, optval, optlen);
if (err) {
hci_dev_put(hdev);
err = -EFAULT;
break;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment