Skip to contentSkip to conversation

Patch "IB/uverbs: Fix race between ib_uverbs_open and remove_one" has been added to the 4.1-stable tree

PATCH [email protected] 1 participant 1 message Sep 26, 2015

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

IB/uverbs: Fix race between ib_uverbs_open and remove_one

to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch
and it can be found in the queue-4.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 35d4a0b63dc0c6d1177d4f532a9deae958f0662c Mon Sep 17 00:00:00 2001

From: Yishai Hadas <[email protected]>
Date: Thu, 13 Aug 2015 18:32:03 +0300
Subject: IB/uverbs: Fix race between ib_uverbs_open and remove_one

From: Yishai Hadas <[email protected]>

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/[email protected]/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.

---
 drivers/infiniband/core/uverbs.h      |    3 +-
 drivers/infiniband/core/uverbs_main.c |   43 +++++++++++++++++++++++-----------
 2 files changed, 32 insertions(+), 14 deletions(-)
drivers/infiniband/core/uverbs.h +2 -1
@@ -85,7 +85,7 @@
  */
 
 struct ib_uverbs_device {
-	struct kref				ref;
+	atomic_t				refcount;
 	int					num_comp_vectors;
 	struct completion			comp;
 	struct device			       *dev;
@@ -94,6 +94,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 {
drivers/infiniband/core/uverbs_main.c +30 -13

125 lines not on this page · raw message

Patches currently in stable-queue which might be from [email protected] are

queue-4.1/ib-mlx4-fix-incorrect-cq-flushing-in-error-state.patch queue-4.1/ib-uverbs-fix-race-between-ib_uverbs_open-and-remove_one.patch