mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 13:44:15 +08:00
bluetooth pull request for net:
- Fixes various issues related to ISO channel/socket support - Fixes issues when building with C=1 - Fix cancel uninitilized work which blocks syzbot to run -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmLxpdoZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKbjqEACZiIUKIACTYWa8Os0fTuzu LM/h4aOnh3L+W2KyA9Kh4Hmm7Caf9JtUZrTIMhMigGiTTN91eLPoScu6ATm7q0vY 7JgfRKbsLCjhUV8uQfypDBM0uQq7exbEiwd1KTHo8XfOgiheZL6ergN4r2g+V/gt up0a58j4ukc6PhWAxujc3UzvMj2c1Sb5jY6TIuyiQM7RONtWLH9VDzc0InRNGqpa eEpPDqCuXsgDTKDAvcJoWARwnj6nsODN3QaSWVlwgN1JgE0/OjXI9hoUNQ83ueCH pl6qigJIuCnGq4ZDbdDE+QcK5I2ouoGoJ9rQMLuUFdupmaBtTEdMK7pw7opzYt3c HqW/TvIR8t2LG0oFmrvFSKH+OMHkIH7D7zaCHGYx5T7B778x5fnUK4OfhvnJ4NPu HkKYD5BJv92X7cHacgclJwQdwwbParrr7wPbqGiSRgiw2ec2puC1VQSYj/+4nwV5 De3AJ2OORv+2kcIw+zi3T0wGzddQF07gXXpz7ckOnFQ1A5jiYX5yGrfGlJezvblX LnXikwvPkkl640ZRrSZvGQBPNySKv8N2yuE/FtbkKfNjoumAkC67PA+4NYOLc9g9 gkgPnR6y4Cm+h3yLILV3njcYbif+5Ue0KHx8L3rr523bZ9C7vUKdcE1i+Tkr9B0y I6rMyxtfkUFwVRRFKwvguw== =nFPi -----END PGP SIGNATURE----- Merge tag 'for-net-2022-08-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: - Fixes various issues related to ISO channel/socket support - Fixes issues when building with C=1 - Fix cancel uninitilized work which blocks syzbot to run * tag 'for-net-2022-08-08' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: ISO: Fix not using the correct QoS Bluetooth: don't try to cancel uninitialized works at mgmt_index_removed() Bluetooth: ISO: Fix iso_sock_getsockopt for BT_DEFER_SETUP Bluetooth: MGMT: Fixes build warnings with C=1 Bluetooth: hci_event: Fix build warning with C=1 Bluetooth: ISO: Fix memory corruption Bluetooth: Fix null pointer deref on unexpected status event Bluetooth: ISO: Fix info leak in iso_sock_getsockopt() Bluetooth: hci_conn: Fix updating ISO QoS PHY Bluetooth: ISO: unlock on error path in iso_sock_setsockopt() Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression ==================== Link: https://lore.kernel.org/r/20220809001224.412807-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
b8c3bf0ed2
@ -54,7 +54,10 @@ void aosp_do_open(struct hci_dev *hdev)
|
||||
/* LE Get Vendor Capabilities Command */
|
||||
skb = __hci_cmd_sync(hdev, hci_opcode_pack(0x3f, 0x153), 0, NULL,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
if (IS_ERR_OR_NULL(skb)) {
|
||||
if (!skb)
|
||||
skb = ERR_PTR(-EIO);
|
||||
|
||||
bt_dev_err(hdev, "AOSP get vendor capabilities (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return;
|
||||
@ -152,7 +155,10 @@ static int enable_quality_report(struct hci_dev *hdev)
|
||||
|
||||
skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
if (IS_ERR_OR_NULL(skb)) {
|
||||
if (!skb)
|
||||
skb = ERR_PTR(-EIO);
|
||||
|
||||
bt_dev_err(hdev, "Enabling Android BQR failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
@ -171,7 +177,10 @@ static int disable_quality_report(struct hci_dev *hdev)
|
||||
|
||||
skb = __hci_cmd_sync(hdev, BQR_OPCODE, sizeof(cp), &cp,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
if (IS_ERR_OR_NULL(skb)) {
|
||||
if (!skb)
|
||||
skb = ERR_PTR(-EIO);
|
||||
|
||||
bt_dev_err(hdev, "Disabling Android BQR failed (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
|
@ -1551,8 +1551,8 @@ static void cis_add(struct iso_list_data *d, struct bt_iso_qos *qos)
|
||||
cis->cis_id = qos->cis;
|
||||
cis->c_sdu = cpu_to_le16(qos->out.sdu);
|
||||
cis->p_sdu = cpu_to_le16(qos->in.sdu);
|
||||
cis->c_phy = qos->out.phy;
|
||||
cis->p_phy = qos->in.phy;
|
||||
cis->c_phy = qos->out.phy ? qos->out.phy : qos->in.phy;
|
||||
cis->p_phy = qos->in.phy ? qos->in.phy : qos->out.phy;
|
||||
cis->c_rtn = qos->out.rtn;
|
||||
cis->p_rtn = qos->in.rtn;
|
||||
|
||||
@ -1735,13 +1735,6 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
|
||||
if (!qos->in.latency)
|
||||
qos->in.latency = qos->out.latency;
|
||||
|
||||
/* Mirror PHYs that are disabled as SDU will be set to 0 */
|
||||
if (!qos->in.phy)
|
||||
qos->in.phy = qos->out.phy;
|
||||
|
||||
if (!qos->out.phy)
|
||||
qos->out.phy = qos->in.phy;
|
||||
|
||||
if (!hci_le_set_cig_params(cis, qos)) {
|
||||
hci_conn_drop(cis);
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -328,14 +328,17 @@ static u8 hci_cc_delete_stored_link_key(struct hci_dev *hdev, void *data,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct hci_rp_delete_stored_link_key *rp = data;
|
||||
u16 num_keys;
|
||||
|
||||
bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
|
||||
|
||||
if (rp->status)
|
||||
return rp->status;
|
||||
|
||||
if (rp->num_keys <= hdev->stored_num_keys)
|
||||
hdev->stored_num_keys -= le16_to_cpu(rp->num_keys);
|
||||
num_keys = le16_to_cpu(rp->num_keys);
|
||||
|
||||
if (num_keys <= hdev->stored_num_keys)
|
||||
hdev->stored_num_keys -= num_keys;
|
||||
else
|
||||
hdev->stored_num_keys = 0;
|
||||
|
||||
|
@ -44,6 +44,9 @@ static void iso_sock_kill(struct sock *sk);
|
||||
/* ----- ISO socket info ----- */
|
||||
#define iso_pi(sk) ((struct iso_pinfo *)sk)
|
||||
|
||||
#define EIR_SERVICE_DATA_LENGTH 4
|
||||
#define BASE_MAX_LENGTH (HCI_MAX_PER_AD_LENGTH - EIR_SERVICE_DATA_LENGTH)
|
||||
|
||||
struct iso_pinfo {
|
||||
struct bt_sock bt;
|
||||
bdaddr_t src;
|
||||
@ -57,7 +60,7 @@ struct iso_pinfo {
|
||||
__u32 flags;
|
||||
struct bt_iso_qos qos;
|
||||
__u8 base_len;
|
||||
__u8 base[HCI_MAX_PER_AD_LENGTH];
|
||||
__u8 base[BASE_MAX_LENGTH];
|
||||
struct iso_conn *conn;
|
||||
};
|
||||
|
||||
@ -370,15 +373,24 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct bt_iso_qos *iso_sock_get_qos(struct sock *sk)
|
||||
{
|
||||
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONNECT2)
|
||||
return &iso_pi(sk)->conn->hcon->iso_qos;
|
||||
|
||||
return &iso_pi(sk)->qos;
|
||||
}
|
||||
|
||||
static int iso_send_frame(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct iso_conn *conn = iso_pi(sk)->conn;
|
||||
struct bt_iso_qos *qos = iso_sock_get_qos(sk);
|
||||
struct hci_iso_data_hdr *hdr;
|
||||
int len = 0;
|
||||
|
||||
BT_DBG("sk %p len %d", sk, skb->len);
|
||||
|
||||
if (skb->len > iso_pi(sk)->qos.out.sdu)
|
||||
if (skb->len > qos->out.sdu)
|
||||
return -EMSGSIZE;
|
||||
|
||||
len = skb->len;
|
||||
@ -1177,8 +1189,10 @@ static int iso_sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
}
|
||||
|
||||
len = min_t(unsigned int, sizeof(qos), optlen);
|
||||
if (len != sizeof(qos))
|
||||
return -EINVAL;
|
||||
if (len != sizeof(qos)) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&qos, 0, sizeof(qos));
|
||||
|
||||
@ -1233,7 +1247,7 @@ static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
int len, err = 0;
|
||||
struct bt_iso_qos qos;
|
||||
struct bt_iso_qos *qos;
|
||||
u8 base_len;
|
||||
u8 *base;
|
||||
|
||||
@ -1246,7 +1260,7 @@ static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
|
||||
switch (optname) {
|
||||
case BT_DEFER_SETUP:
|
||||
if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
|
||||
if (sk->sk_state == BT_CONNECTED) {
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
@ -1258,13 +1272,10 @@ static int iso_sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
|
||||
case BT_ISO_QOS:
|
||||
if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONNECT2)
|
||||
qos = iso_pi(sk)->conn->hcon->iso_qos;
|
||||
else
|
||||
qos = iso_pi(sk)->qos;
|
||||
qos = iso_sock_get_qos(sk);
|
||||
|
||||
len = min_t(unsigned int, len, sizeof(qos));
|
||||
if (copy_to_user(optval, (char *)&qos, len))
|
||||
len = min_t(unsigned int, len, sizeof(*qos));
|
||||
if (copy_to_user(optval, qos, len))
|
||||
err = -EFAULT;
|
||||
|
||||
break;
|
||||
|
@ -1970,11 +1970,11 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
|
||||
bdaddr_t *dst,
|
||||
u8 link_type)
|
||||
{
|
||||
struct l2cap_chan *c, *c1 = NULL;
|
||||
struct l2cap_chan *c, *tmp, *c1 = NULL;
|
||||
|
||||
read_lock(&chan_list_lock);
|
||||
|
||||
list_for_each_entry(c, &chan_list, global_l) {
|
||||
list_for_each_entry_safe(c, tmp, &chan_list, global_l) {
|
||||
if (state && c->state != state)
|
||||
continue;
|
||||
|
||||
@ -1993,11 +1993,10 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
|
||||
dst_match = !bacmp(&c->dst, dst);
|
||||
if (src_match && dst_match) {
|
||||
c = l2cap_chan_hold_unless_zero(c);
|
||||
if (!c)
|
||||
continue;
|
||||
|
||||
read_unlock(&chan_list_lock);
|
||||
return c;
|
||||
if (c) {
|
||||
read_unlock(&chan_list_lock);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/* Closest match */
|
||||
|
@ -3819,7 +3819,7 @@ static int set_blocked_keys(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
|
||||
hci_blocked_keys_clear(hdev);
|
||||
|
||||
for (i = 0; i < keys->key_count; ++i) {
|
||||
for (i = 0; i < key_count; ++i) {
|
||||
struct blocked_key *b = kzalloc(sizeof(*b), GFP_KERNEL);
|
||||
|
||||
if (!b) {
|
||||
@ -4624,8 +4624,7 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
|
||||
u32 current_flags = __le32_to_cpu(cp->current_flags);
|
||||
|
||||
bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
|
||||
&cp->addr.bdaddr, cp->addr.type,
|
||||
__le32_to_cpu(current_flags));
|
||||
&cp->addr.bdaddr, cp->addr.type, current_flags);
|
||||
|
||||
// We should take hci_dev_lock() early, I think.. conn_flags can change
|
||||
supported_flags = hdev->conn_flags;
|
||||
@ -8936,6 +8935,8 @@ void mgmt_index_removed(struct hci_dev *hdev)
|
||||
HCI_MGMT_EXT_INDEX_EVENTS);
|
||||
|
||||
/* Cancel any remaining timed work */
|
||||
if (!hci_dev_test_flag(hdev, HCI_MGMT))
|
||||
return;
|
||||
cancel_delayed_work_sync(&hdev->discov_off);
|
||||
cancel_delayed_work_sync(&hdev->service_cache);
|
||||
cancel_delayed_work_sync(&hdev->rpa_expired);
|
||||
|
@ -120,7 +120,10 @@ static bool read_supported_features(struct hci_dev *hdev,
|
||||
|
||||
skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
if (IS_ERR_OR_NULL(skb)) {
|
||||
if (!skb)
|
||||
skb = ERR_PTR(-EIO);
|
||||
|
||||
bt_dev_err(hdev, "Failed to read MSFT supported features (%ld)",
|
||||
PTR_ERR(skb));
|
||||
return false;
|
||||
@ -319,8 +322,11 @@ static int msft_remove_monitor_sync(struct hci_dev *hdev,
|
||||
|
||||
skb = __hci_cmd_sync(hdev, hdev->msft_opcode, sizeof(cp), &cp,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb))
|
||||
if (IS_ERR_OR_NULL(skb)) {
|
||||
if (!skb)
|
||||
return -EIO;
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
return msft_le_cancel_monitor_advertisement_cb(hdev, hdev->msft_opcode,
|
||||
monitor, skb);
|
||||
@ -432,8 +438,11 @@ static int msft_add_monitor_sync(struct hci_dev *hdev,
|
||||
HCI_CMD_TIMEOUT);
|
||||
kfree(cp);
|
||||
|
||||
if (IS_ERR(skb))
|
||||
if (IS_ERR_OR_NULL(skb)) {
|
||||
if (!skb)
|
||||
return -EIO;
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
return msft_le_monitor_advertisement_cb(hdev, hdev->msft_opcode,
|
||||
monitor, skb);
|
||||
|
Loading…
Reference in New Issue
Block a user