mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Bluetooth: Validate hci conn validity before refering wakelock.
Found in a rare case there is possibility that remote device sent disconnect on a connection and DUT is trying send data on the same. In that case accessing some released wakelock is causing issue. The current changes are to use locking mechanism to validate the connection before acting on the wake lock. CRs-Fixed: 394651 Change-Id: I6a4188a7d0d05a8cfbe66d3680473d549157917a Signed-off-by: Srinivas Krovvidi <skrovvid@codeaurora.org> (cherry picked from commit 6aadc41fcbd28dc3899a4b5d098e5f316588a029) Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
This commit is contained in:
parent
14585a7c95
commit
cdd13e5bfd
3 changed files with 14 additions and 7 deletions
|
@ -354,6 +354,7 @@ struct hci_conn {
|
|||
__u8 auth;
|
||||
void *smp_conn;
|
||||
struct timer_list smp_timer;
|
||||
__u8 conn_valid;
|
||||
|
||||
|
||||
void (*connect_cfm_cb) (struct hci_conn *conn, u8 status);
|
||||
|
|
|
@ -393,9 +393,7 @@ static void hci_conn_idle(unsigned long arg)
|
|||
|
||||
BT_DBG("conn %p mode %d", conn, conn->mode);
|
||||
|
||||
hci_dev_lock(conn->hdev);
|
||||
hci_conn_enter_sniff_mode(conn);
|
||||
hci_dev_unlock(conn->hdev);
|
||||
}
|
||||
|
||||
static void hci_conn_rssi_update(struct work_struct *work)
|
||||
|
@ -450,6 +448,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type,
|
|||
|
||||
conn->power_save = 1;
|
||||
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
|
||||
conn->conn_valid = true;
|
||||
spin_lock_init(&conn->lock);
|
||||
wake_lock_init(&conn->idle_lock, WAKE_LOCK_SUSPEND, "bt_idle");
|
||||
|
||||
switch (type) {
|
||||
|
@ -522,6 +522,10 @@ int hci_conn_del(struct hci_conn *conn)
|
|||
|
||||
BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
|
||||
|
||||
spin_lock_bh(&conn->lock);
|
||||
conn->conn_valid = false; /* conn data is being released */
|
||||
spin_unlock_bh(&conn->lock);
|
||||
|
||||
/* Make sure no timers are running */
|
||||
del_timer(&conn->idle_timer);
|
||||
wake_lock_destroy(&conn->idle_lock);
|
||||
|
@ -981,9 +985,13 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
|
|||
|
||||
timer:
|
||||
if (hdev->idle_timeout > 0) {
|
||||
mod_timer(&conn->idle_timer,
|
||||
jiffies + msecs_to_jiffies(hdev->idle_timeout));
|
||||
wake_lock(&conn->idle_lock);
|
||||
spin_lock_bh(&conn->lock);
|
||||
if (conn->conn_valid) {
|
||||
mod_timer(&conn->idle_timer,
|
||||
jiffies + msecs_to_jiffies(hdev->idle_timeout));
|
||||
wake_lock(&conn->idle_lock);
|
||||
}
|
||||
spin_unlock_bh(&conn->lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2285,7 +2285,6 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
|
|||
if (count > hdev->acl_cnt)
|
||||
return;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
hci_conn_enter_active_mode(conn, bt_cb(skb)->force_active);
|
||||
|
||||
hci_send_frame(skb);
|
||||
|
@ -2295,7 +2294,6 @@ static inline void hci_sched_acl(struct hci_dev *hdev)
|
|||
quote -= count;
|
||||
|
||||
conn->sent += count;
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue