diff options
author | Michael Bestas <mkbestas@lineageos.org> | 2021-09-16 18:09:37 +0300 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2021-09-16 18:09:37 +0300 |
commit | 1ed76589b97cb8ebafe7d2c78eceea3a22247347 (patch) | |
tree | 0b66917f0c332158e45bc444331302dc48b8e820 /net/bluetooth | |
parent | 42239a8d619a7b7264d77dc9262888f91349d205 (diff) | |
parent | 3f066f394dfbaa992235d8c987ded95f7bcd981f (diff) |
Merge remote-tracking branch 'common/android-4.4-p' into lineage-18.1-caf-msm8998
# By Thomas Gleixner (11) and others
# Via Greg Kroah-Hartman
* google/common/android-4.4-p:
Linux 4.4.283
Revert "floppy: reintroduce O_NDELAY fix"
fbmem: add margin check to fb_check_caps()
vt_kdsetmode: extend console locking
vringh: Use wiov->used to check for read/write desc order
virtio: Improve vq->broken access to avoid any compiler optimization
net: marvell: fix MVNETA_TX_IN_PRGRS bit number
e1000e: Fix the max snoop/no-snoop latency for 10M
USB: serial: option: add new VID/PID to support Fibocom FG150
Revert "USB: serial: ch341: fix character loss at high transfer rates"
can: usb: esd_usb2: esd_usb2_rx_event(): fix the interchange of the CAN RX and TX error counters
Linux 4.4.282
mmc: dw_mmc: Fix occasional hang after tuning on eMMC
ASoC: intel: atom: Fix breakage for PCM buffer address setup
ipack: tpci200: fix many double free issues in tpci200_pci_probe
ALSA: hda - fix the 'Capture Switch' value change notifications
mmc: dw_mmc: Fix hang on data CRC error
mmc: dw_mmc: call the dw_mci_prep_stop_abort() by default
mmc: dw_mmc: Wait for data transfer after response errors.
net: qlcnic: add missed unlock in qlcnic_83xx_flash_read32
net: 6pack: fix slab-out-of-bounds in decode_data
dccp: add do-while-0 stubs for dccp_pr_debug macros
Bluetooth: hidp: use correct wait queue when removing ctrl_wait
scsi: core: Avoid printing an error if target_alloc() returns -ENXIO
scsi: megaraid_mm: Fix end of loop tests for list_for_each_entry()
dmaengine: of-dma: router_xlate to return -EPROBE_DEFER if controller is not yet available
ARM: dts: am43x-epos-evm: Reduce i2c0 bus speed for tps65218
dmaengine: usb-dmac: Fix PM reference leak in usb_dmac_probe()
KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl (CVE-2021-3653)
vmlinux.lds.h: Handle clang's module.{c,d}tor sections
PCI/MSI: Enforce MSI[X] entry updates to be visible
PCI/MSI: Enforce that MSI-X table entry is masked for update
PCI/MSI: Mask all unused MSI-X entries
PCI/MSI: Protect msi_desc::masked for multi-MSI
PCI/MSI: Use msi_mask_irq() in pci_msi_shutdown()
PCI/MSI: Correct misleading comments
PCI/MSI: Do not set invalid bits in MSI mask
PCI/MSI: Enable and mask MSI-X early
x86/tools: Fix objdump version check again
xen/events: Fix race in set_evtchn_to_irq
net: Fix memory leak in ieee802154_raw_deliver
i2c: dev: zero out array used for i2c reads from userspace
ASoC: intel: atom: Fix reference to PCM buffer address
ANDROID: xt_quota2: set usersize in xt_match registration object
ANDROID: xt_quota2: clear quota2_log message before sending
ANDROID: xt_quota2: remove trailing junk which might have a digit in it
UPSTREAM: netfilter: x_tables: fix pointer leaks to userspace
Linux 4.4.281
ovl: prevent private clone if bind mount is not allowed
net: xilinx_emaclite: Do not print real IOMEM pointer
USB:ehci:fix Kunpeng920 ehci hardware problem
pipe: increase minimum default pipe size to 2 pages
net/qla3xxx: fix schedule while atomic in ql_wait_for_drvr_lock and ql_adapter_reset
alpha: Send stop IPI to send to online CPUs
reiserfs: check directory items on read from disk
reiserfs: add check for root_inode in reiserfs_fill_super
pcmcia: i82092: fix a null pointer dereference bug
MIPS: Malta: Do not byte-swap accesses to the CBUS UART
serial: 8250: Mask out floating 16/32-bit bus bits
media: rtl28xxu: fix zero-length control request
scripts/tracing: fix the bug that can't parse raw_trace_func
USB: serial: ftdi_sio: add device ID for Auto-M3 OP-COM v2
USB: serial: ch341: fix character loss at high transfer rates
USB: serial: option: add Telit FD980 composition 0x1056
Bluetooth: defer cleanup of resources in hci_unregister_dev()
net: vxge: fix use-after-free in vxge_device_unregister
net: pegasus: fix uninit-value in get_interrupt_interval
bnx2x: fix an error code in bnx2x_nic_load()
mips: Fix non-POSIX regexp
net: natsemi: Fix missing pci_disable_device() in probe and remove
media: videobuf2-core: dequeue if start_streaming fails
scsi: sr: Return correct event when media event code is 3
ALSA: seq: Fix racy deletion of subscriber
Linux 4.4.280
rcu: Update documentation of rcu_read_unlock()
futex,rt_mutex: Fix rt_mutex_cleanup_proxy_lock()
futex: Avoid freeing an active timer
futex: Handle transient "ownerless" rtmutex state correctly
rtmutex: Make wait_lock irq safe
futex: Futex_unlock_pi() determinism
futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock()
futex: Pull rt_mutex_futex_unlock() out from under hb->lock
futex,rt_mutex: Introduce rt_mutex_init_waiter()
futex: Cleanup refcounting
futex: Rename free_pi_state() to put_pi_state()
Linux 4.4.279
can: raw: raw_setsockopt(): fix raw_rcv panic for sock UAF
Revert "Bluetooth: Shutdown controller after workqueues are flushed or cancelled"
net: Fix zero-copy head len calculation.
r8152: Fix potential PM refcount imbalance
regulator: rt5033: Fix n_voltages settings for BUCK and LDO
btrfs: mark compressed range uptodate only if all bio succeed
Conflicts:
net/bluetooth/hci_core.c
net/netfilter/xt_quota2.c
Change-Id: I66e2384c8cc40448a7bff34bb935c74e6103e924
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 32 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 49 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 2 |
4 files changed, 53 insertions, 33 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 73808a164506..36d0e4bc592c 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1666,6 +1666,14 @@ int hci_dev_do_close(struct hci_dev *hdev) BT_DBG("%s %pK", hdev->name, hdev); + if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && + !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && + test_bit(HCI_UP, &hdev->flags)) { + /* Execute vendor specific shutdown routine */ + if (hdev->shutdown) + hdev->shutdown(hdev); + } + cancel_delayed_work(&hdev->power_off); hci_req_cancel(hdev, ENODEV); @@ -1738,14 +1746,6 @@ int hci_dev_do_close(struct hci_dev *hdev) clear_bit(HCI_INIT, &hdev->flags); } - if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && - !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && - test_bit(HCI_UP, &hdev->flags)) { - /* Execute vendor specific shutdown routine */ - if (hdev->shutdown) - hdev->shutdown(hdev); - } - /* flush cmd work */ flush_work(&hdev->cmd_work); @@ -3457,14 +3457,10 @@ EXPORT_SYMBOL(hci_register_dev); /* Unregister HCI device */ void hci_unregister_dev(struct hci_dev *hdev) { - int id; - BT_DBG("%pK name %s bus %d", hdev, hdev->name, hdev->bus); hci_dev_set_flag(hdev, HCI_UNREGISTER); - id = hdev->id; - write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); @@ -3493,7 +3489,14 @@ void hci_unregister_dev(struct hci_dev *hdev) } device_del(&hdev->dev); + /* Actual cleanup is deferred until hci_cleanup_dev(). */ + hci_dev_put(hdev); +} +EXPORT_SYMBOL(hci_unregister_dev); +/* Cleanup HCI device */ +void hci_cleanup_dev(struct hci_dev *hdev) +{ debugfs_remove_recursive(hdev->debugfs); destroy_workqueue(hdev->workqueue); @@ -3513,11 +3516,8 @@ void hci_unregister_dev(struct hci_dev *hdev) hci_discovery_filter_clear(hdev); hci_dev_unlock(hdev); - hci_dev_put(hdev); - - ida_simple_remove(&hci_index_ida, id); + ida_simple_remove(&hci_index_ida, hdev->id); } -EXPORT_SYMBOL(hci_unregister_dev); /* Suspend HCI device */ int hci_suspend_dev(struct hci_dev *hdev) diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index fbdf3ac7ef2a..f84cfd0d4c65 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -53,6 +53,17 @@ struct hci_pinfo { unsigned long flags; }; +static struct hci_dev *hci_hdev_from_sock(struct sock *sk) +{ + struct hci_dev *hdev = hci_pi(sk)->hdev; + + if (!hdev) + return ERR_PTR(-EBADFD); + if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) + return ERR_PTR(-EPIPE); + return hdev; +} + void hci_sock_set_flag(struct sock *sk, int nr) { set_bit(nr, &hci_pi(sk)->flags); @@ -480,19 +491,13 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) if (event == HCI_DEV_UNREG) { struct sock *sk; - /* Detach sockets from device */ + /* Wake up sockets using this dead device */ read_lock(&hci_sk_list.lock); sk_for_each(sk, &hci_sk_list.head) { - lock_sock(sk); if (hci_pi(sk)->hdev == hdev) { - hci_pi(sk)->hdev = NULL; sk->sk_err = EPIPE; - sk->sk_state = BT_OPEN; sk->sk_state_change(sk); - - hci_dev_put(hdev); } - release_sock(sk); } read_unlock(&hci_sk_list.lock); } @@ -631,10 +636,10 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) { - struct hci_dev *hdev = hci_pi(sk)->hdev; + struct hci_dev *hdev = hci_hdev_from_sock(sk); - if (!hdev) - return -EBADFD; + if (IS_ERR(hdev)) + return PTR_ERR(hdev); if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) return -EBUSY; @@ -766,6 +771,18 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, lock_sock(sk); + /* Allow detaching from dead device and attaching to alive device, if + * the caller wants to re-bind (instead of close) this socket in + * response to hci_sock_dev_event(HCI_DEV_UNREG) notification. + */ + hdev = hci_pi(sk)->hdev; + if (hdev && hci_dev_test_flag(hdev, HCI_UNREGISTER)) { + hci_pi(sk)->hdev = NULL; + sk->sk_state = BT_OPEN; + hci_dev_put(hdev); + } + hdev = NULL; + if (sk->sk_state == BT_BOUND) { err = -EALREADY; goto done; @@ -937,9 +954,9 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, lock_sock(sk); - hdev = hci_pi(sk)->hdev; - if (!hdev) { - err = -EBADFD; + hdev = hci_hdev_from_sock(sk); + if (IS_ERR(hdev)) { + err = PTR_ERR(hdev); goto done; } @@ -1191,9 +1208,9 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, goto done; } - hdev = hci_pi(sk)->hdev; - if (!hdev) { - err = -EBADFD; + hdev = hci_hdev_from_sock(sk); + if (IS_ERR(hdev)) { + err = PTR_ERR(hdev); goto done; } diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 4f78b28686ff..a76b1371a7fc 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -180,6 +180,9 @@ ATTRIBUTE_GROUPS(bt_host); static void bt_host_release(struct device *dev) { struct hci_dev *hdev = to_hci_dev(dev); + + if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) + hci_cleanup_dev(hdev); kfree(hdev); module_put(THIS_MODULE); } diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index e614940c4e98..960d4b718fd7 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1283,7 +1283,7 @@ static int hidp_session_thread(void *arg) /* cleanup runtime environment */ remove_wait_queue(sk_sleep(session->intr_sock->sk), &intr_wait); - remove_wait_queue(sk_sleep(session->intr_sock->sk), &ctrl_wait); + remove_wait_queue(sk_sleep(session->ctrl_sock->sk), &ctrl_wait); wake_up_interruptible(&session->report_queue); hidp_del_timer(session); |