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 -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmYW5JMZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKcQjD/9JiPI2Tdb+LQ8g8WZDVEIG CefzSzDU1BQLDrU4JaaORPCUjTLNT+dDMTbDzcstmnL3g9yhMzUB8IfcTgcXWa7Z gs/cFyssPVtNEoDCZQwB3m83Hrx0e4dPxQAzs8qlIZDhedP33Uohy76jPiLqgoLM GtogGfezLthXeQlsCymwS7qju+37QW+GaBdid8N0g7YrAMPEqIkYRrx21OUxTKok q/4p9BDeYDpA7JdWXv3Izr2HT0cm6eaCkVu0rANj1pYSytalZxe2GAb10bP/uTLi DPxObxOz7J7gh93T6wDZhG3NHZIhRN9yBlO+9FAqKSs6RlPdBq33xNs+Fnilf2Rd iKu/cfjtbmc0N/NWih8dpnCMhNU277WJFJMZlOh2Wu0FwSTg0Sqy+sdNicm1cHP3 oR46lbsD4ctM1JhGX5Whl2BxMR7D8ty3R/d+sTxsICY9MoUFSAzwnsN1+jwCyeW2 PgPkHEs/gptA8l5XWyw33Rt206PO3B2jgdy96aJ+RN1fU8FkAl6WxnqXZZE2C8cN RcYFrFF6iq8pqyey9Y6+9dmzXolcxZ6bC0ooB84gGLRz5L2ptnD7NB1G8XvPkpKJ wyVLAdQ6w0KNEgorQkOvh4JVF3/dG04yE841Qz1MsOo8Pmr74j7vfFvko72uGdEC 49B98NoX3xEmcC815aO3rQ== =YwaX -----END PGP SIGNATURE----- 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.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
fe3eb40672
@ -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;
|
||||
err = bt_copy_from_sockptr(&qos, sizeof(qos), optval, optlen);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
if (len == sizeof(qos.ucast) && !check_ucast_qos(&qos)) {
|
||||
err = -EINVAL;
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user