1. 20 8月, 2023 1 次提交
    • S
      Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb · ba8196b0
      Sungwoo Kim 提交于
      stable inclusion
      from stable-v4.19.290
      commit 82cdb2ccbe43337798393369f0ceb98699fe6037
      category: bugfix
      bugzilla: 189135, https://gitee.com/src-openeuler/kernel/issues/I7SXVG
      CVE: CVE-2023-40283
      
      Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=82cdb2ccbe43337798393369f0ceb98699fe6037
      
      --------------------------------
      
      commit 1728137b33c00d5a2b5110ed7aafb42e7c32e4a1 upstream.
      
      l2cap_sock_release(sk) frees sk. However, sk's children are still alive
      and point to the already free'd sk's address.
      To fix this, l2cap_sock_release(sk) also cleans sk's children.
      
      ==================================================================
      BUG: KASAN: use-after-free in l2cap_sock_ready_cb+0xb7/0x100 net/bluetooth/l2cap_sock.c:1650
      Read of size 8 at addr ffff888104617aa8 by task kworker/u3:0/276
      
      CPU: 0 PID: 276 Comm: kworker/u3:0 Not tainted 6.2.0-00001-gef397bd4d5fb-dirty #59
      Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
      Workqueue: hci2 hci_rx_work
      Call Trace:
       <TASK>
       __dump_stack lib/dump_stack.c:88 [inline]
       dump_stack_lvl+0x72/0x95 lib/dump_stack.c:106
       print_address_description mm/kasan/report.c:306 [inline]
       print_report+0x175/0x478 mm/kasan/report.c:417
       kasan_report+0xb1/0x130 mm/kasan/report.c:517
       l2cap_sock_ready_cb+0xb7/0x100 net/bluetooth/l2cap_sock.c:1650
       l2cap_chan_ready+0x10e/0x1e0 net/bluetooth/l2cap_core.c:1386
       l2cap_config_req+0x753/0x9f0 net/bluetooth/l2cap_core.c:4480
       l2cap_bredr_sig_cmd net/bluetooth/l2cap_core.c:5739 [inline]
       l2cap_sig_channel net/bluetooth/l2cap_core.c:6509 [inline]
       l2cap_recv_frame+0xe2e/0x43c0 net/bluetooth/l2cap_core.c:7788
       l2cap_recv_acldata+0x6ed/0x7e0 net/bluetooth/l2cap_core.c:8506
       hci_acldata_packet net/bluetooth/hci_core.c:3813 [inline]
       hci_rx_work+0x66e/0xbc0 net/bluetooth/hci_core.c:4048
       process_one_work+0x4ea/0x8e0 kernel/workqueue.c:2289
       worker_thread+0x364/0x8e0 kernel/workqueue.c:2436
       kthread+0x1b9/0x200 kernel/kthread.c:376
       ret_from_fork+0x2c/0x50 arch/x86/entry/entry_64.S:308
       </TASK>
      
      Allocated by task 288:
       kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
       kasan_set_track+0x25/0x30 mm/kasan/common.c:52
       ____kasan_kmalloc mm/kasan/common.c:374 [inline]
       __kasan_kmalloc+0x82/0x90 mm/kasan/common.c:383
       kasan_kmalloc include/linux/kasan.h:211 [inline]
       __do_kmalloc_node mm/slab_common.c:968 [inline]
       __kmalloc+0x5a/0x140 mm/slab_common.c:981
       kmalloc include/linux/slab.h:584 [inline]
       sk_prot_alloc+0x113/0x1f0 net/core/sock.c:2040
       sk_alloc+0x36/0x3c0 net/core/sock.c:2093
       l2cap_sock_alloc.constprop.0+0x39/0x1c0 net/bluetooth/l2cap_sock.c:1852
       l2cap_sock_create+0x10d/0x220 net/bluetooth/l2cap_sock.c:1898
       bt_sock_create+0x183/0x290 net/bluetooth/af_bluetooth.c:132
       __sock_create+0x226/0x380 net/socket.c:1518
       sock_create net/socket.c:1569 [inline]
       __sys_socket_create net/socket.c:1606 [inline]
       __sys_socket_create net/socket.c:1591 [inline]
       __sys_socket+0x112/0x200 net/socket.c:1639
       __do_sys_socket net/socket.c:1652 [inline]
       __se_sys_socket net/socket.c:1650 [inline]
       __x64_sys_socket+0x40/0x50 net/socket.c:1650
       do_syscall_x64 arch/x86/entry/common.c:50 [inline]
       do_syscall_64+0x3f/0x90 arch/x86/entry/common.c:80
       entry_SYSCALL_64_after_hwframe+0x72/0xdc
      
      Freed by task 288:
       kasan_save_stack+0x22/0x50 mm/kasan/common.c:45
       kasan_set_track+0x25/0x30 mm/kasan/common.c:52
       kasan_save_free_info+0x2e/0x50 mm/kasan/generic.c:523
       ____kasan_slab_free mm/kasan/common.c:236 [inline]
       ____kasan_slab_free mm/kasan/common.c:200 [inline]
       __kasan_slab_free+0x10a/0x190 mm/kasan/common.c:244
       kasan_slab_free include/linux/kasan.h:177 [inline]
       slab_free_hook mm/slub.c:1781 [inline]
       slab_free_freelist_hook mm/slub.c:1807 [inline]
       slab_free mm/slub.c:3787 [inline]
       __kmem_cache_free+0x88/0x1f0 mm/slub.c:3800
       sk_prot_free net/core/sock.c:2076 [inline]
       __sk_destruct+0x347/0x430 net/core/sock.c:2168
       sk_destruct+0x9c/0xb0 net/core/sock.c:2183
       __sk_free+0x82/0x220 net/core/sock.c:2194
       sk_free+0x7c/0xa0 net/core/sock.c:2205
       sock_put include/net/sock.h:1991 [inline]
       l2cap_sock_kill+0x256/0x2b0 net/bluetooth/l2cap_sock.c:1257
       l2cap_sock_release+0x1a7/0x220 net/bluetooth/l2cap_sock.c:1428
       __sock_release+0x80/0x150 net/socket.c:650
       sock_close+0x19/0x30 net/socket.c:1368
       __fput+0x17a/0x5c0 fs/file_table.c:320
       task_work_run+0x132/0x1c0 kernel/task_work.c:179
       resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
       exit_to_user_mode_loop kernel/entry/common.c:171 [inline]
       exit_to_user_mode_prepare+0x113/0x120 kernel/entry/common.c:203
       __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline]
       syscall_exit_to_user_mode+0x21/0x50 kernel/entry/common.c:296
       do_syscall_64+0x4c/0x90 arch/x86/entry/common.c:86
       entry_SYSCALL_64_after_hwframe+0x72/0xdc
      
      The buggy address belongs to the object at ffff888104617800
       which belongs to the cache kmalloc-1k of size 1024
      The buggy address is located 680 bytes inside of
       1024-byte region [ffff888104617800, ffff888104617c00)
      
      The buggy address belongs to the physical page:
      page:00000000dbca6a80 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888104614000 pfn:0x104614
      head:00000000dbca6a80 order:2 compound_mapcount:0 subpages_mapcount:0 compound_pincount:0
      flags: 0x200000000010200(slab|head|node=0|zone=2)
      raw: 0200000000010200 ffff888100041dc0 ffffea0004212c10 ffffea0004234b10
      raw: ffff888104614000 0000000000080002 00000001ffffffff 0000000000000000
      page dumped because: kasan: bad access detected
      
      Memory state around the buggy address:
       ffff888104617980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
       ffff888104617a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      >ffff888104617a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                        ^
       ffff888104617b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
       ffff888104617b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      ==================================================================
      
      Ack: This bug is found by FuzzBT with a modified Syzkaller. Other
      contributors are Ruoyu Wu and Hui Peng.
      Signed-off-by: NSungwoo Kim <iam@sung-woo.kim>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      Signed-off-by: NJakub Kicinski <kuba@kernel.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NDong Chenchen <dongchenchen2@huawei.com>
      ba8196b0
  2. 29 9月, 2021 1 次提交
    • W
      Bluetooth: fix use-after-free error in lock_sock_nested() · 4356e06a
      Wang ShaoBo 提交于
      mainline inclusion
      from mainline-v5.16
      commit 1bff51ea
      category: bugfix
      bugzilla: NA
      CVE: CVE-2021-3752
      
      ---------------------------
      
      use-after-free error in lock_sock_nested is reported:
      
      [  179.140137][ T3731] =====================================================
      [  179.142675][ T3731] BUG: KMSAN: use-after-free in lock_sock_nested+0x280/0x2c0
      [  179.145494][ T3731] CPU: 4 PID: 3731 Comm: kworker/4:2 Not tainted 5.12.0-rc6+ #54
      [  179.148432][ T3731] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
      [  179.151806][ T3731] Workqueue: events l2cap_chan_timeout
      [  179.152730][ T3731] Call Trace:
      [  179.153301][ T3731]  dump_stack+0x24c/0x2e0
      [  179.154063][ T3731]  kmsan_report+0xfb/0x1e0
      [  179.154855][ T3731]  __msan_warning+0x5c/0xa0
      [  179.155579][ T3731]  lock_sock_nested+0x280/0x2c0
      [  179.156436][ T3731]  ? kmsan_get_metadata+0x116/0x180
      [  179.157257][ T3731]  l2cap_sock_teardown_cb+0xb8/0x890
      [  179.158154][ T3731]  ? __msan_metadata_ptr_for_load_8+0x10/0x20
      [  179.159141][ T3731]  ? kmsan_get_metadata+0x116/0x180
      [  179.159994][ T3731]  ? kmsan_get_shadow_origin_ptr+0x84/0xb0
      [  179.160959][ T3731]  ? l2cap_sock_recv_cb+0x420/0x420
      [  179.161834][ T3731]  l2cap_chan_del+0x3e1/0x1d50
      [  179.162608][ T3731]  ? kmsan_get_metadata+0x116/0x180
      [  179.163435][ T3731]  ? kmsan_get_shadow_origin_ptr+0x84/0xb0
      [  179.164406][ T3731]  l2cap_chan_close+0xeea/0x1050
      [  179.165189][ T3731]  ? kmsan_internal_unpoison_shadow+0x42/0x70
      [  179.166180][ T3731]  l2cap_chan_timeout+0x1da/0x590
      [  179.167066][ T3731]  ? __msan_metadata_ptr_for_load_8+0x10/0x20
      [  179.168023][ T3731]  ? l2cap_chan_create+0x560/0x560
      [  179.168818][ T3731]  process_one_work+0x121d/0x1ff0
      [  179.169598][ T3731]  worker_thread+0x121b/0x2370
      [  179.170346][ T3731]  kthread+0x4ef/0x610
      [  179.171010][ T3731]  ? process_one_work+0x1ff0/0x1ff0
      [  179.171828][ T3731]  ? kthread_blkcg+0x110/0x110
      [  179.172587][ T3731]  ret_from_fork+0x1f/0x30
      [  179.173348][ T3731]
      [  179.173752][ T3731] Uninit was created at:
      [  179.174409][ T3731]  kmsan_internal_poison_shadow+0x5c/0xf0
      [  179.175373][ T3731]  kmsan_slab_free+0x76/0xc0
      [  179.176060][ T3731]  kfree+0x3a5/0x1180
      [  179.176664][ T3731]  __sk_destruct+0x8af/0xb80
      [  179.177375][ T3731]  __sk_free+0x812/0x8c0
      [  179.178032][ T3731]  sk_free+0x97/0x130
      [  179.178686][ T3731]  l2cap_sock_release+0x3d5/0x4d0
      [  179.179457][ T3731]  sock_close+0x150/0x450
      [  179.180117][ T3731]  __fput+0x6bd/0xf00
      [  179.180787][ T3731]  ____fput+0x37/0x40
      [  179.181481][ T3731]  task_work_run+0x140/0x280
      [  179.182219][ T3731]  do_exit+0xe51/0x3e60
      [  179.182930][ T3731]  do_group_exit+0x20e/0x450
      [  179.183656][ T3731]  get_signal+0x2dfb/0x38f0
      [  179.184344][ T3731]  arch_do_signal_or_restart+0xaa/0xe10
      [  179.185266][ T3731]  exit_to_user_mode_prepare+0x2d2/0x560
      [  179.186136][ T3731]  syscall_exit_to_user_mode+0x35/0x60
      [  179.186984][ T3731]  do_syscall_64+0xc5/0x140
      [  179.187681][ T3731]  entry_SYSCALL_64_after_hwframe+0x44/0xae
      [  179.188604][ T3731] =====================================================
      
      In our case, there are two Thread A and B:
      
      Context: Thread A:              Context: Thread B:
      
      l2cap_chan_timeout()            __se_sys_shutdown()
        l2cap_chan_close()              l2cap_sock_shutdown()
          l2cap_chan_del()                l2cap_chan_close()
            l2cap_sock_teardown_cb()        l2cap_sock_teardown_cb()
      
      Once l2cap_sock_teardown_cb() excuted, this sock will be marked as SOCK_ZAPPED,
      and can be treated as killable in l2cap_sock_kill() if sock_orphan() has
      excuted, at this time we close sock through sock_close() which end to call
      l2cap_sock_kill() like Thread C:
      
      Context: Thread C:
      
      sock_close()
        l2cap_sock_release()
          sock_orphan()
          l2cap_sock_kill()  #free sock if refcnt is 1
      
      If C completed, Once A or B reaches l2cap_sock_teardown_cb() again,
      use-after-free happened.
      
      We should set chan->data to NULL if sock is destructed, for telling teardown
      operation is not allowed in l2cap_sock_teardown_cb(), and also we should
      avoid killing an already killed socket in l2cap_sock_close_cb().
      Signed-off-by: NWang ShaoBo <bobo.shaobowang@huawei.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      4356e06a
  3. 19 10月, 2020 1 次提交
  4. 27 12月, 2019 1 次提交
    • M
      Bluetooth: Fix locking in bt_accept_enqueue() for BH context · 77824bd1
      Matthias Kaehlcke 提交于
      commit c4f5627f upstream.
      
      With commit e1633762 ("Bluetooth: Handle bt_accept_enqueue() socket
      atomically") lock_sock[_nested]() is used to acquire the socket lock
      before manipulating the socket. lock_sock[_nested]() may block, which
      is problematic since bt_accept_enqueue() can be called in bottom half
      context (e.g. from rfcomm_connect_ind()):
      
      [<ffffff80080d81ec>] __might_sleep+0x4c/0x80
      [<ffffff800876c7b0>] lock_sock_nested+0x24/0x58
      [<ffffff8000d7c27c>] bt_accept_enqueue+0x48/0xd4 [bluetooth]
      [<ffffff8000e67d8c>] rfcomm_connect_ind+0x190/0x218 [rfcomm]
      
      Add a parameter to bt_accept_enqueue() to indicate whether the
      function is called from BH context, and acquire the socket lock
      with bh_lock_sock_nested() if that's the case.
      
      Also adapt all callers of bt_accept_enqueue() to pass the new
      parameter:
      
      - l2cap_sock_new_connection_cb()
        - uses lock_sock() to lock the parent socket => process context
      
      - rfcomm_connect_ind()
        - acquires the parent socket lock with bh_lock_sock() => BH
          context
      
      - __sco_chan_add()
        - called from sco_chan_add(), which is called from sco_connect().
          parent is NULL, hence bt_accept_enqueue() isn't called in this
          code path and we can ignore it
        - also called from sco_conn_ready(). uses bh_lock_sock() to acquire
          the parent lock => BH context
      
      Fixes: e1633762 ("Bluetooth: Handle bt_accept_enqueue() socket atomically")
      Signed-off-by: NMatthias Kaehlcke <mka@chromium.org>
      Reviewed-by: NDouglas Anderson <dianders@chromium.org>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      Cc: stable@vger.kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
      77824bd1
  5. 29 6月, 2018 1 次提交
    • L
      Revert changes to convert to ->poll_mask() and aio IOCB_CMD_POLL · a11e1d43
      Linus Torvalds 提交于
      The poll() changes were not well thought out, and completely
      unexplained.  They also caused a huge performance regression, because
      "->poll()" was no longer a trivial file operation that just called down
      to the underlying file operations, but instead did at least two indirect
      calls.
      
      Indirect calls are sadly slow now with the Spectre mitigation, but the
      performance problem could at least be largely mitigated by changing the
      "->get_poll_head()" operation to just have a per-file-descriptor pointer
      to the poll head instead.  That gets rid of one of the new indirections.
      
      But that doesn't fix the new complexity that is completely unwarranted
      for the regular case.  The (undocumented) reason for the poll() changes
      was some alleged AIO poll race fixing, but we don't make the common case
      slower and more complex for some uncommon special case, so this all
      really needs way more explanations and most likely a fundamental
      redesign.
      
      [ This revert is a revert of about 30 different commits, not reverted
        individually because that would just be unnecessarily messy  - Linus ]
      
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Christoph Hellwig <hch@lst.de>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      a11e1d43
  6. 26 5月, 2018 1 次提交
  7. 13 2月, 2018 1 次提交
    • D
      net: make getname() functions return length rather than use int* parameter · 9b2c45d4
      Denys Vlasenko 提交于
      Changes since v1:
      Added changes in these files:
          drivers/infiniband/hw/usnic/usnic_transport.c
          drivers/staging/lustre/lnet/lnet/lib-socket.c
          drivers/target/iscsi/iscsi_target_login.c
          drivers/vhost/net.c
          fs/dlm/lowcomms.c
          fs/ocfs2/cluster/tcp.c
          security/tomoyo/network.c
      
      Before:
      All these functions either return a negative error indicator,
      or store length of sockaddr into "int *socklen" parameter
      and return zero on success.
      
      "int *socklen" parameter is awkward. For example, if caller does not
      care, it still needs to provide on-stack storage for the value
      it does not need.
      
      None of the many FOO_getname() functions of various protocols
      ever used old value of *socklen. They always just overwrite it.
      
      This change drops this parameter, and makes all these functions, on success,
      return length of sockaddr. It's always >= 0 and can be differentiated
      from an error.
      
      Tests in callers are changed from "if (err)" to "if (err < 0)", where needed.
      
      rpc_sockname() lost "int buflen" parameter, since its only use was
      to be passed to kernel_getsockname() as &buflen and subsequently
      not used in any way.
      
      Userspace API is not changed.
      
          text    data     bss      dec     hex filename
      30108430 2633624  873672 33615726 200ef6e vmlinux.before.o
      30108109 2633612  873672 33615393 200ee21 vmlinux.o
      Signed-off-by: NDenys Vlasenko <dvlasenk@redhat.com>
      CC: David S. Miller <davem@davemloft.net>
      CC: linux-kernel@vger.kernel.org
      CC: netdev@vger.kernel.org
      CC: linux-bluetooth@vger.kernel.org
      CC: linux-decnet-user@lists.sourceforge.net
      CC: linux-wireless@vger.kernel.org
      CC: linux-rdma@vger.kernel.org
      CC: linux-sctp@vger.kernel.org
      CC: linux-nfs@vger.kernel.org
      CC: linux-x25@vger.kernel.org
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      9b2c45d4
  8. 29 6月, 2017 1 次提交
  9. 10 3月, 2017 1 次提交
    • D
      net: Work around lockdep limitation in sockets that use sockets · cdfbabfb
      David Howells 提交于
      Lockdep issues a circular dependency warning when AFS issues an operation
      through AF_RXRPC from a context in which the VFS/VM holds the mmap_sem.
      
      The theory lockdep comes up with is as follows:
      
       (1) If the pagefault handler decides it needs to read pages from AFS, it
           calls AFS with mmap_sem held and AFS begins an AF_RXRPC call, but
           creating a call requires the socket lock:
      
      	mmap_sem must be taken before sk_lock-AF_RXRPC
      
       (2) afs_open_socket() opens an AF_RXRPC socket and binds it.  rxrpc_bind()
           binds the underlying UDP socket whilst holding its socket lock.
           inet_bind() takes its own socket lock:
      
      	sk_lock-AF_RXRPC must be taken before sk_lock-AF_INET
      
       (3) Reading from a TCP socket into a userspace buffer might cause a fault
           and thus cause the kernel to take the mmap_sem, but the TCP socket is
           locked whilst doing this:
      
      	sk_lock-AF_INET must be taken before mmap_sem
      
      However, lockdep's theory is wrong in this instance because it deals only
      with lock classes and not individual locks.  The AF_INET lock in (2) isn't
      really equivalent to the AF_INET lock in (3) as the former deals with a
      socket entirely internal to the kernel that never sees userspace.  This is
      a limitation in the design of lockdep.
      
      Fix the general case by:
      
       (1) Double up all the locking keys used in sockets so that one set are
           used if the socket is created by userspace and the other set is used
           if the socket is created by the kernel.
      
       (2) Store the kern parameter passed to sk_alloc() in a variable in the
           sock struct (sk_kern_sock).  This informs sock_lock_init(),
           sock_init_data() and sk_clone_lock() as to the lock keys to be used.
      
           Note that the child created by sk_clone_lock() inherits the parent's
           kern setting.
      
       (3) Add a 'kern' parameter to ->accept() that is analogous to the one
           passed in to ->create() that distinguishes whether kernel_accept() or
           sys_accept4() was the caller and can be passed to sk_alloc().
      
           Note that a lot of accept functions merely dequeue an already
           allocated socket.  I haven't touched these as the new socket already
           exists before we get the parameter.
      
           Note also that there are a couple of places where I've made the accepted
           socket unconditionally kernel-based:
      
      	irda_accept()
      	rds_rcp_accept_one()
      	tcp_accept_from_sock()
      
           because they follow a sock_create_kern() and accept off of that.
      
      Whilst creating this, I noticed that lustre and ocfs don't create sockets
      through sock_create_kern() and thus they aren't marked as for-kernel,
      though they appear to be internal.  I wonder if these should do that so
      that they use the new set of lock keys.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      cdfbabfb
  10. 02 3月, 2017 1 次提交
  11. 24 8月, 2016 1 次提交
    • D
      Bluetooth: split sk_filter in l2cap_sock_recv_cb · dbb50887
      Daniel Borkmann 提交于
      During an audit for sk_filter(), we found that rx_busy_skb handling
      in l2cap_sock_recv_cb() and l2cap_sock_recvmsg() looks not quite as
      intended.
      
      The assumption from commit e328140f ("Bluetooth: Use event-driven
      approach for handling ERTM receive buffer") is that errors returned
      from sock_queue_rcv_skb() are due to receive buffer shortage. However,
      nothing should prevent doing a setsockopt() with SO_ATTACH_FILTER on
      the socket, that could drop some of the incoming skbs when handled in
      sock_queue_rcv_skb().
      
      In that case sock_queue_rcv_skb() will return with -EPERM, propagated
      from sk_filter() and if in L2CAP_MODE_ERTM mode, wrong assumption was
      that we failed due to receive buffer being full. From that point onwards,
      due to the to-be-dropped skb being held in rx_busy_skb, we cannot make
      any forward progress as rx_busy_skb is never cleared from l2cap_sock_recvmsg(),
      due to the filter drop verdict over and over coming from sk_filter().
      Meanwhile, in l2cap_sock_recv_cb() all new incoming skbs are being
      dropped due to rx_busy_skb being occupied.
      
      Instead, just use __sock_queue_rcv_skb() where an error really tells that
      there's a receive buffer issue. Split the sk_filter() and enable it for
      non-segmented modes at queuing time since at this point in time the skb has
      already been through the ERTM state machine and it has been acked, so dropping
      is not allowed. Instead, for ERTM and streaming mode, call sk_filter() in
      l2cap_data_rcv() so the packet can be dropped before the state machine sees it.
      
      Fixes: e328140f ("Bluetooth: Use event-driven approach for handling ERTM receive buffer")
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: NMat Martineau <mathew.j.martineau@linux.intel.com>
      Acked-by: NWillem de Bruijn <willemb@google.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      dbb50887
  12. 18 7月, 2016 1 次提交
  13. 09 4月, 2016 1 次提交
  14. 29 1月, 2016 2 次提交
  15. 21 10月, 2015 3 次提交
    • D
      Bluetooth: l2cap_disconnection_req priority over shutdown · 9f7378a9
      Dean Jenkins 提交于
      There is a L2CAP protocol race between the local peer and
      the remote peer demanding disconnection of the L2CAP link.
      
      When L2CAP ERTM is used, l2cap_sock_shutdown() can be called
      from userland to disconnect L2CAP. However, there can be a
      delay introduced by waiting for ACKs. During this waiting
      period, the remote peer may have sent a Disconnection Request.
      Therefore, recheck the shutdown status of the socket
      after waiting for ACKs because there is no need to do
      further processing if the connection has gone.
      Signed-off-by: NDean Jenkins <Dean_Jenkins@mentor.com>
      Signed-off-by: NHarish Jenny K N <harish_kandiga@mentor.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      9f7378a9
    • D
      Bluetooth: Reorganize mutex lock in l2cap_sock_shutdown() · 04ba72e6
      Dean Jenkins 提交于
      This commit reorganizes the mutex lock and is now
      only protecting l2cap_chan_close(). This is now consistent
      with other places where l2cap_chan_close() is called.
      
      If a conn connection exists, call
      mutex_lock(&conn->chan_lock) before calling l2cap_chan_close()
      to ensure other L2CAP protocol operations do not interfere.
      
      Note that the conn structure has to be protected from being
      freed as it is possible for the connection to be disconnected
      whilst the locks are not held. This solution allows the mutex
      lock to be used even when the connection has just been
      disconnected.
      
      This commit also reduces the scope of chan locking.
      
      The only place where chan locking is needed is the call to
      l2cap_chan_close(chan, 0) which if necessary closes the channel.
      Therefore, move the l2cap_chan_lock(chan) and
      l2cap_chan_lock(chan) locking calls to around
      l2cap_chan_close(chan, 0).
      
      This allows __l2cap_wait_ack(sk, chan) to be called with no
      chan locks being held so L2CAP messaging over the ACL link
      can be done unimpaired.
      Signed-off-by: NDean Jenkins <Dean_Jenkins@mentor.com>
      Signed-off-by: NHarish Jenny K N <harish_kandiga@mentor.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      04ba72e6
    • D
      Bluetooth: Unwind l2cap_sock_shutdown() · e7456437
      Dean Jenkins 提交于
      l2cap_sock_shutdown() is designed to only action shutdown
      of the channel when shutdown is not already in progress.
      Therefore, reorganise the code flow by adding a goto
      to jump to the end of function handling when shutdown is
      already being actioned. This removes one level of code
      indentation and make the code more readable.
      Signed-off-by: NDean Jenkins <Dean_Jenkins@mentor.com>
      Signed-off-by: NHarish Jenny K N <harish_kandiga@mentor.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      e7456437
  16. 23 7月, 2015 5 次提交
  17. 11 5月, 2015 1 次提交
  18. 31 3月, 2015 1 次提交
  19. 03 3月, 2015 1 次提交
  20. 24 1月, 2015 1 次提交
    • P
      Bluetooth: Fix nested sleeps · dfb2fae7
      Peter Hurley 提交于
      l2cap/rfcomm/sco_sock_accept() are wait loops which may acquire
      sleeping locks. Since both wait loops and sleeping locks use
      task_struct.state to sleep and wake, the nested sleeping locks
      destroy the wait loop state.
      
      Use the newly-minted wait_woken() and DEFINE_WAIT_FUNC() for the
      wait loop. DEFINE_WAIT_FUNC() allows an alternate wake function
      to be specified; in this case, the predefined scheduler function,
      woken_wake_function(). This wait construct ensures wakeups will
      not be missed without requiring the wait loop to set the
      task state before condition evaluation. How this works:
      
       CPU 0                            |  CPU 1
                                        |
                                        | is <condition> set?
                                        | no
      set <condition>                   |
                                        |
      wake_up_interruptible             |
        woken_wake_function             |
          set WQ_FLAG_WOKEN             |
          try_to_wake_up                |
                                        | wait_woken
                                        |   set TASK_INTERRUPTIBLE
                                        |   WQ_FLAG_WOKEN? yes
                                        |   set TASK_RUNNING
                                        |
                                        | - loop -
      				  |
      				  | is <condition> set?
                                        | yes - exit wait loop
      
      Fixes "do not call blocking ops when !TASK_RUNNING" warnings
      in l2cap_sock_accept(), rfcomm_sock_accept() and sco_sock_accept().
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      dfb2fae7
  21. 12 1月, 2015 1 次提交
  22. 10 12月, 2014 2 次提交
  23. 15 11月, 2014 1 次提交
  24. 13 11月, 2014 3 次提交
    • J
      Bluetooth: Fix L2CAP nesting level initialization location · ff714119
      Johan Hedberg 提交于
      There's no reason why all users of L2CAP would need to worry about
      initializing chan->nesting to L2CAP_NESTING_NORMAL (which is important
      since 0 is the same as NESTING_SMP). This patch moves the initialization
      to the common place that's used to create all new channels, i.e. the
      l2cap_chan_create() function.
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      ff714119
    • J
      Bluetooth: Fix L2CAP socket lock nesting level · 3b2ab39e
      Johan Hedberg 提交于
      The teardown callback for L2CAP channels is problematic in that it is
      explicitly called for all types of channels from l2cap_chan_del(),
      meaning it's not possible to hard-code a nesting level when taking the
      socket lock. The simplest way to have a correct nesting level for the
      socket locking is to use the same value as for the chan. This also means
      that the other places trying to lock parent sockets need to be update to
      use the chan value (since L2CAP_NESTING_PARENT is defined as 2 whereas
      SINGLE_DEPTH_NESTING has the value 1).
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      3b2ab39e
    • J
      Bluetooth: Use proper nesting annotation for l2cap_chan lock · abe84903
      Johan Hedberg 提交于
      By default lockdep considers all L2CAP channels equal. This would mean
      that we get warnings if a channel is locked when another one's lock is
      tried to be acquired in the same thread. This kind of inter-channel
      locking dependencies exist in the form of parent-child channels as well
      as any channel wishing to elevate the security by requesting procedures
      on the SMP channel.
      
      To eliminate the chance for these lockdep warnings we introduce a
      nesting level for each channel and use that when acquiring the channel
      lock. For now there exists the earlier mentioned three identified
      categories: SMP, "normal" channels and parent channels (i.e. those in
      BT_LISTEN state). The nesting level is defined as atomic_t since we need
      access to it before the lock is actually acquired.
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      abe84903
  25. 12 11月, 2014 1 次提交
    • J
      Bluetooth: Fix l2cap_sock_teardown_cb lockdep warning · f0356704
      Johan Hedberg 提交于
      Any code calling bt_accept_dequeue() to get a new child socket from a
      server socket should use lock_sock_nested to avoid lockdep warnings due
      to the parent and child sockets being locked at the same time. The
      l2cap_sock_accept() function is already doing this correctly but a
      second place calling bt_accept_dequeue() is the code path from
      l2cap_sock_teardown_cb() that calls l2cap_sock_cleanup_listen().
      
      This patch fixes the proper nested locking annotation and thereby avoids
      the following style of lockdep warning.
      
      [  +0.000224] [ INFO: possible recursive locking detected ]
      [  +0.000222] 3.17.0+ #1153 Not tainted
      [  +0.000130] ---------------------------------------------
      [  +0.000227] l2cap-tester/562 is trying to acquire lock:
      [  +0.000210]  (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [<c1393f47>] bt_accept_dequeue+0x68/0x11b
      [  +0.000467]
      but task is already holding lock:
      [  +0.000186]  (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+...}, at: [<c13b949a>] lock_sock+0xa/0xc
      [  +0.000421]
      other info that might help us debug this:
      [  +0.000199]  Possible unsafe locking scenario:
      
      [  +0.000117]        CPU0
      [  +0.000000]        ----
      [  +0.000000]   lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
      [  +0.000000]   lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
      [  +0.000000]
       *** DEADLOCK ***
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      f0356704
  26. 09 9月, 2014 1 次提交
    • J
      Bluetooth: Fix hci_conn reference counting for fixed channels · c16900cf
      Johan Hedberg 提交于
      Now that SMP has been converted to use fixed channels we've got a bit of
      a problem with the hci_conn reference counting. So far the L2CAP code
      has kept a reference for each L2CAP channel that was notified of the
      connection. With SMP however this would mean that the connection is
      never dropped even though there are no other users of it. Furthermore,
      SMP already does its own hci_conn reference counting internally,
      starting from a security or pairing request and ending with the key
      distribution.
      
      This patch makes L2CAP fixed channels default to the L2CAP core not
      keeping a hci_conn reference for them. A new FLAG_HOLD_HCI_CONN flag is
      added so that L2CAP users can declare an exception to this rule and hold
      a reference even for their fixed channels. One such exception is the
      L2CAP socket layer which does want a reference for each socket (e.g. an
      ATT socket which uses a fixed channel).
      Signed-off-by: NJohan Hedberg <johan.hedberg@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      c16900cf
  27. 14 8月, 2014 2 次提交
  28. 18 7月, 2014 1 次提交
  29. 17 7月, 2014 1 次提交