Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1242946
| From | Ben Hutchings <ben@decadent.org.uk> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH 3.2 058/107] IB/uverbs: Fix race between ib_uverbs_open and remove_one |
| Date | 2015-10-09 02:50 +0200 |
| Message-ID | <qhu2L-31O-37@gated-at.bofh.it> (permalink) |
| References | <qhtzH-2tg-3@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
3.2.72-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Yishai Hadas <yishaih@mellanox.com>
commit 35d4a0b63dc0c6d1177d4f532a9deae958f0662c upstream.
Fixes: 2a72f212263701b927559f6850446421d5906c41 ("IB/uverbs: Remove dev_table")
Before this commit there was a device look-up table that was protected
by a spin_lock used by ib_uverbs_open and by ib_uverbs_remove_one. When
it was dropped and container_of was used instead, it enabled the race
with remove_one as dev might be freed just after:
dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev) but
before the kref_get.
In addition, this buggy patch added some dead code as
container_of(x,y,z) can never be NULL and so dev can never be NULL.
As a result the comment above ib_uverbs_open saying "the open method
will either immediately run -ENXIO" is wrong as it can never happen.
The solution follows Jason Gunthorpe suggestion from below URL:
https://www.mail-archive.com/linux-rdma@vger.kernel.org/msg25692.html
cdev will hold a kref on the parent (the containing structure,
ib_uverbs_device) and only when that kref is released it is
guaranteed that open will never be called again.
In addition, fixes the active count scheme to use an atomic
not a kref to prevent WARN_ON as pointed by above comment
from Jason.
Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Shachar Raindel <raindel@mellanox.com>
Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/infiniband/core/uverbs.h | 3 ++-
drivers/infiniband/core/uverbs_main.c | 43 ++++++++++++++++++++++++-----------
2 files changed, 32 insertions(+), 14 deletions(-)
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -69,7 +69,7 @@
*/
struct ib_uverbs_device {
- struct kref ref;
+ atomic_t refcount;
int num_comp_vectors;
struct completion comp;
struct device *dev;
@@ -78,6 +78,7 @@ struct ib_uverbs_device {
struct cdev cdev;
struct rb_root xrcd_tree;
struct mutex xrcd_tree_mutex;
+ struct kobject kobj;
};
struct ib_uverbs_event_file {
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -117,14 +117,18 @@ static ssize_t (*uverbs_cmd_table[])(str
static void ib_uverbs_add_one(struct ib_device *device);
static void ib_uverbs_remove_one(struct ib_device *device);
-static void ib_uverbs_release_dev(struct kref *ref)
+static void ib_uverbs_release_dev(struct kobject *kobj)
{
struct ib_uverbs_device *dev =
- container_of(ref, struct ib_uverbs_device, ref);
+ container_of(kobj, struct ib_uverbs_device, kobj);
- complete(&dev->comp);
+ kfree(dev);
}
+static struct kobj_type ib_uverbs_dev_ktype = {
+ .release = ib_uverbs_release_dev,
+};
+
static void ib_uverbs_release_event_file(struct kref *ref)
{
struct ib_uverbs_event_file *file =
@@ -273,13 +277,19 @@ static int ib_uverbs_cleanup_ucontext(st
return context->device->dealloc_ucontext(context);
}
+static void ib_uverbs_comp_dev(struct ib_uverbs_device *dev)
+{
+ complete(&dev->comp);
+}
+
static void ib_uverbs_release_file(struct kref *ref)
{
struct ib_uverbs_file *file =
container_of(ref, struct ib_uverbs_file, ref);
module_put(file->device->ib_dev->owner);
- kref_put(&file->device->ref, ib_uverbs_release_dev);
+ if (atomic_dec_and_test(&file->device->refcount))
+ ib_uverbs_comp_dev(file->device);
kfree(file);
}
@@ -621,9 +631,7 @@ static int ib_uverbs_open(struct inode *
int ret;
dev = container_of(inode->i_cdev, struct ib_uverbs_device, cdev);
- if (dev)
- kref_get(&dev->ref);
- else
+ if (!atomic_inc_not_zero(&dev->refcount))
return -ENXIO;
if (!try_module_get(dev->ib_dev->owner)) {
@@ -644,6 +652,7 @@ static int ib_uverbs_open(struct inode *
mutex_init(&file->mutex);
filp->private_data = file;
+ kobject_get(&dev->kobj);
return nonseekable_open(inode, filp);
@@ -651,13 +660,16 @@ err_module:
module_put(dev->ib_dev->owner);
err:
- kref_put(&dev->ref, ib_uverbs_release_dev);
+ if (atomic_dec_and_test(&dev->refcount))
+ ib_uverbs_comp_dev(dev);
+
return ret;
}
static int ib_uverbs_close(struct inode *inode, struct file *filp)
{
struct ib_uverbs_file *file = filp->private_data;
+ struct ib_uverbs_device *dev = file->device;
ib_uverbs_cleanup_ucontext(file, file->ucontext);
@@ -665,6 +677,7 @@ static int ib_uverbs_close(struct inode
kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
kref_put(&file->ref, ib_uverbs_release_file);
+ kobject_put(&dev->kobj);
return 0;
}
@@ -760,10 +773,11 @@ static void ib_uverbs_add_one(struct ib_
if (!uverbs_dev)
return;
- kref_init(&uverbs_dev->ref);
+ atomic_set(&uverbs_dev->refcount, 1);
init_completion(&uverbs_dev->comp);
uverbs_dev->xrcd_tree = RB_ROOT;
mutex_init(&uverbs_dev->xrcd_tree_mutex);
+ kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype);
spin_lock(&map_lock);
devnum = find_first_zero_bit(dev_map, IB_UVERBS_MAX_DEVICES);
@@ -790,6 +804,7 @@ static void ib_uverbs_add_one(struct ib_
cdev_init(&uverbs_dev->cdev, NULL);
uverbs_dev->cdev.owner = THIS_MODULE;
uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
+ uverbs_dev->cdev.kobj.parent = &uverbs_dev->kobj;
kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum);
if (cdev_add(&uverbs_dev->cdev, base, 1))
goto err_cdev;
@@ -820,9 +835,10 @@ err_cdev:
clear_bit(devnum, overflow_map);
err:
- kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+ if (atomic_dec_and_test(&uverbs_dev->refcount))
+ ib_uverbs_comp_dev(uverbs_dev);
wait_for_completion(&uverbs_dev->comp);
- kfree(uverbs_dev);
+ kobject_put(&uverbs_dev->kobj);
return;
}
@@ -842,9 +858,10 @@ static void ib_uverbs_remove_one(struct
else
clear_bit(uverbs_dev->devnum - IB_UVERBS_MAX_DEVICES, overflow_map);
- kref_put(&uverbs_dev->ref, ib_uverbs_release_dev);
+ if (atomic_dec_and_test(&uverbs_dev->refcount))
+ ib_uverbs_comp_dev(uverbs_dev);
wait_for_completion(&uverbs_dev->comp);
- kfree(uverbs_dev);
+ kobject_put(&uverbs_dev->kobj);
}
static char *uverbs_devnode(struct device *dev, mode_t *mode)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH 3.2 000/107] 3.2.72-rc1 review Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 072/107] USB: option: add ZTE PIDs Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 069/107] hfs,hfsplus: cache pages correctly between bnode_create and bnode_free Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 015/107] ocfs2: fix BUG in ocfs2_downconvert_thread_do_work() Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 049/107] DRM - radeon: Don't link train DisplayPort on HPD until we get the dpcd Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 098/107] ipv6: lock socket in ip6_datagram_connect() Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 024/107] libfc: Fix fc_fcp_cleanup_each_cmd() Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:30 +0200
[PATCH 3.2 094/107] Initialize msg/shm IPC objects before doing ipc_addid() Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 060/107] drm/i915: Always mark the object as dirty when used by the GPU Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 047/107] eCryptfs: Invalidate dcache entries when lower i_nlink is zero Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 009/107] target: REPORT LUNS should return LUN 0 even for dynamic ACLs Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 095/107] net/tipc: initialize security state for new connection socket Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 018/107] x86/ldt: Make modify_ldt synchronous Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 036/107] PCI: Add VPD function 0 quirk for Intel Ethernet devices Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 016/107] net: Clone skb before setting peeked flag Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 026/107] x86/ldt: Further fix FPU emulation Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 029/107] sparc64: Fix userspace FPU register corruptions. Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 023/107] libiscsi: Fix host busy blocking during connection teardown Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 019/107] x86/ldt: Correct LDT access in single stepping logic Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 017/107] net: Fix skb_set_peeked use-after-free bug Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 005/107] crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 033/107] PCI: Fix TI816X class code quirk Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 051/107] rtlwifi: rtl8192cu: Add new device ID Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 032/107] [media] rc-core: fix remove uevent generation Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 068/107] powerpc/MSI: Fix race condition in tearing down MSI interrupts Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 037/107] usb: gadget: m66592-udc: forever loop in set_feature() Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 054/107] xfs: return errors from partial I/O failures to files Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 103/107] ipv6: prevent fib6_run_gc() contention Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 044/107] serial: 8250: bind to ALi Fast Infrared Controller (ALI5123) Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 070/107] hfs: fix B-tree corruption after insertion at position 0 Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 050/107] rtlwifi: rtl8192cu: Add new device ID Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 048/107] xfs: Fix xfs_attr_leafblock definition Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 025/107] ipc,sem: fix use after free on IPC_RMID after a task using same semaphore set exits Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 007/107] target/iscsi: Fix double free of a TUR followed by a solicited NOPOUT Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:40 +0200
[PATCH 3.2 081/107] usb: Use the USB_SS_MULT() macro to get the burst multiplier. Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 079/107] s390/compat: correct uc_sigmask of the compat signal frame Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 091/107] virtio-net: drop NETIF_F_FRAGLIST Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 053/107] drivercore: Fix unregistration path of platform devices Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 006/107] USB: sierra: add 1199:68AB device ID Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 059/107] spi: spi-pxa2xx: Check status register to determine if SSSR_TINT is disabled Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 002/107] pktgen: Require CONFIG_INET due to use of IPv4 checksum function Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 085/107] cifs: use server timestamp for ntlmv2 authentication Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 066/107] ARM: 8429/1: disable GCC SRA optimization Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 061/107] Add radeon suspend/resume quirk for HP Compaq dc5750. Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 046/107] USB: ftdi_sio: Added custom PID for CustomWare products Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 013/107] perf: Fix fasync handling on inherited events Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 074/107] btrfs: skip waiting on ordered range for special files Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 052/107] of/address: Don't loop forever in of_find_matching_node_by_address(). Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 042/107] NFSv4: don't set SETATTR for O_RDONLY|O_EXCL Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 093/107] ipc/sem.c: fully initialize sem_array before making it visible Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 039/107] auxdisplay: ks0108: fix refcount Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 083/107] usb: xhci: Clear XHCI_STATE_DYING on start Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 062/107] IB/uverbs: reject invalid or unknown opcodes Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 058/107] IB/uverbs: Fix race between ib_uverbs_open and remove_one Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 102/107] perf tools: Fix build with perl 5.18 Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 075/107] ARM: 7880/1: Clear the IT state independent of the Thumb-2 mode Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 105/107] parisc: Filter out spurious interrupts in PA-RISC irq handler Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 100/107] net/ipv6: Correct PIM6 mrt_lock handling Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 030/107] dcache: Handle escaped paths in prepend_path Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 041/107] windfarm: decrement client count when unregistering Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 076/107] ARM: fix Thumb2 signal handling when ARMv6 is enabled Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 057/107] IB/mlx4: Use correct SL on AH query under RoCE Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 090/107] ipv6: addrconf: validate new MTU before applying it Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 010/107] MIPS: Fix sched_getaffinity with MT FPAFF enabled Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 02:50 +0200
[PATCH 3.2 063/107] Input: evdev - do not report errors form flush() Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 078/107] ASoC: fix broken pxa SoC support Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 064/107] crypto: ghash-clmulni: specify context size for ghash async algorithm Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 065/107] fs: create and use seq_show_option for escaping Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 084/107] xhci: change xhci 1.0 only restrictions to support xhci 1.1 Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 071/107] perf header: Fixup reading of HEADER_NRCPUS feature Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 104/107] ipv6: update ip6_rt_last_gc every time GC is run Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 055/107] IB/qib: Change lkey table allocation to support more MRs Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 073/107] Btrfs: fix read corruption of compressed and shared extents Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
Re: [PATCH 3.2 000/107] 3.2.72-rc1 review Guenter Roeck <linux@roeck-us.net> - 2015-10-09 03:00 +0200
Re: [PATCH 3.2 000/107] 3.2.72-rc1 review Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:20 +0200
[PATCH 3.2 077/107] x86/platform: Fix Geode LX timekeeping in the generic x86 build Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 087/107] ocfs2/dlm: fix deadlock when dispatch assert master Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 056/107] SUNRPC: xs_reset_transport must mark the connection as disconnected Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
[PATCH 3.2 082/107] xhci: give command abortion one more chance before killing xhci Ben Hutchings <ben@decadent.org.uk> - 2015-10-09 03:00 +0200
csiph-web