stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Bart Van Assche <bvanassche@acm.org>,
	Yann Droneaud <ydroneaud@opteya.com>,
	Roland Dreier <roland@purestorage.com>
Subject: [PATCH 3.4 12/19] IB/umad: Fix use-after-free on close
Date: Fri,  4 Jul 2014 15:15:22 -0700	[thread overview]
Message-ID: <20140704221436.990386492@linuxfoundation.org> (raw)
In-Reply-To: <20140704221436.423715636@linuxfoundation.org>

3.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <bvanassche@acm.org>

commit 60e1751cb52cc6d1ae04b6bd3c2b96e770b5823f upstream.

Avoid that closing /dev/infiniband/umad<n> or /dev/infiniband/issm<n>
triggers a use-after-free.  __fput() invokes f_op->release() before it
invokes cdev_put().  Make sure that the ib_umad_device structure is
freed by the cdev_put() call instead of f_op->release().  This avoids
that changing the port mode from IB into Ethernet and back to IB
followed by restarting opensmd triggers the following kernel oops:

    general protection fault: 0000 [#1] PREEMPT SMP
    RIP: 0010:[<ffffffff810cc65c>]  [<ffffffff810cc65c>] module_put+0x2c/0x170
    Call Trace:
     [<ffffffff81190f20>] cdev_put+0x20/0x30
     [<ffffffff8118e2ce>] __fput+0x1ae/0x1f0
     [<ffffffff8118e35e>] ____fput+0xe/0x10
     [<ffffffff810723bc>] task_work_run+0xac/0xe0
     [<ffffffff81002a9f>] do_notify_resume+0x9f/0xc0
     [<ffffffff814b8398>] int_signal+0x12/0x17

Reference: https://bugzilla.kernel.org/show_bug.cgi?id=75051
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/infiniband/core/user_mad.c |   30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -98,7 +98,7 @@ struct ib_umad_port {
 
 struct ib_umad_device {
 	int                  start_port, end_port;
-	struct kref          ref;
+	struct kobject       kobj;
 	struct ib_umad_port  port[0];
 };
 
@@ -134,14 +134,18 @@ static DECLARE_BITMAP(dev_map, IB_UMAD_M
 static void ib_umad_add_one(struct ib_device *device);
 static void ib_umad_remove_one(struct ib_device *device);
 
-static void ib_umad_release_dev(struct kref *ref)
+static void ib_umad_release_dev(struct kobject *kobj)
 {
 	struct ib_umad_device *dev =
-		container_of(ref, struct ib_umad_device, ref);
+		container_of(kobj, struct ib_umad_device, kobj);
 
 	kfree(dev);
 }
 
+static struct kobj_type ib_umad_dev_ktype = {
+	.release = ib_umad_release_dev,
+};
+
 static int hdr_size(struct ib_umad_file *file)
 {
 	return file->use_pkey_index ? sizeof (struct ib_user_mad_hdr) :
@@ -812,7 +816,7 @@ static int ib_umad_open(struct inode *in
 		goto out;
 	}
 
-	kref_get(&port->umad_dev->ref);
+	kobject_get(&port->umad_dev->kobj);
 
 out:
 	mutex_unlock(&port->file_mutex);
@@ -851,7 +855,7 @@ static int ib_umad_close(struct inode *i
 	mutex_unlock(&file->port->file_mutex);
 
 	kfree(file);
-	kref_put(&dev->ref, ib_umad_release_dev);
+	kobject_put(&dev->kobj);
 
 	return 0;
 }
@@ -902,7 +906,7 @@ static int ib_umad_sm_open(struct inode
 	if (ret)
 		goto err_clr_sm_cap;
 
-	kref_get(&port->umad_dev->ref);
+	kobject_get(&port->umad_dev->kobj);
 
 	return 0;
 
@@ -932,7 +936,7 @@ static int ib_umad_sm_close(struct inode
 
 	up(&port->sm_sem);
 
-	kref_put(&port->umad_dev->ref, ib_umad_release_dev);
+	kobject_put(&port->umad_dev->kobj);
 
 	return ret;
 }
@@ -1000,6 +1004,7 @@ static int find_overflow_devnum(void)
 }
 
 static int ib_umad_init_port(struct ib_device *device, int port_num,
+			     struct ib_umad_device *umad_dev,
 			     struct ib_umad_port *port)
 {
 	int devnum;
@@ -1032,6 +1037,7 @@ static int ib_umad_init_port(struct ib_d
 
 	cdev_init(&port->cdev, &umad_fops);
 	port->cdev.owner = THIS_MODULE;
+	port->cdev.kobj.parent = &umad_dev->kobj;
 	kobject_set_name(&port->cdev.kobj, "umad%d", port->dev_num);
 	if (cdev_add(&port->cdev, base, 1))
 		goto err_cdev;
@@ -1050,6 +1056,7 @@ static int ib_umad_init_port(struct ib_d
 	base += IB_UMAD_MAX_PORTS;
 	cdev_init(&port->sm_cdev, &umad_sm_fops);
 	port->sm_cdev.owner = THIS_MODULE;
+	port->sm_cdev.kobj.parent = &umad_dev->kobj;
 	kobject_set_name(&port->sm_cdev.kobj, "issm%d", port->dev_num);
 	if (cdev_add(&port->sm_cdev, base, 1))
 		goto err_sm_cdev;
@@ -1143,7 +1150,7 @@ static void ib_umad_add_one(struct ib_de
 	if (!umad_dev)
 		return;
 
-	kref_init(&umad_dev->ref);
+	kobject_init(&umad_dev->kobj, &ib_umad_dev_ktype);
 
 	umad_dev->start_port = s;
 	umad_dev->end_port   = e;
@@ -1151,7 +1158,8 @@ static void ib_umad_add_one(struct ib_de
 	for (i = s; i <= e; ++i) {
 		umad_dev->port[i - s].umad_dev = umad_dev;
 
-		if (ib_umad_init_port(device, i, &umad_dev->port[i - s]))
+		if (ib_umad_init_port(device, i, umad_dev,
+				      &umad_dev->port[i - s]))
 			goto err;
 	}
 
@@ -1163,7 +1171,7 @@ err:
 	while (--i >= s)
 		ib_umad_kill_port(&umad_dev->port[i - s]);
 
-	kref_put(&umad_dev->ref, ib_umad_release_dev);
+	kobject_put(&umad_dev->kobj);
 }
 
 static void ib_umad_remove_one(struct ib_device *device)
@@ -1177,7 +1185,7 @@ static void ib_umad_remove_one(struct ib
 	for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i)
 		ib_umad_kill_port(&umad_dev->port[i]);
 
-	kref_put(&umad_dev->ref, ib_umad_release_dev);
+	kobject_put(&umad_dev->kobj);
 }
 
 static char *umad_devnode(struct device *dev, umode_t *mode)



  parent reply	other threads:[~2014-07-04 22:15 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-04 22:15 [PATCH 3.4 00/19] 3.4.97-stable review Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 01/19] Input: elantech - deal with clickpads reporting right button events Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 02/19] PCI: Add new ID for Intel GPU "spurious interrupt" quirk Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 03/19] PCI: Fix incorrect vgaarb conditional in WARN_ON() Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 04/19] recordmcount/MIPS: Fix possible incorrect mcount_loc table entries in modules Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 05/19] MIPS: MSC: Prevent out-of-bounds writes to MIPS SC ioremapd region Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 06/19] UBIFS: Remove incorrect assertion in shrink_tnc() Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 07/19] watchdog: sp805: Set watchdog_device->timeout from ->set_timeout() Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 08/19] IB/qib: Fix port in pkey change event Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 09/19] IB/ipath: Translate legacy diagpkt into newer extended diagpkt Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 10/19] IB/srp: Fix a sporadic crash triggered by cable pulling Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 11/19] IB/umad: Fix error handling Greg Kroah-Hartman
2014-07-04 22:15 ` Greg Kroah-Hartman [this message]
2014-07-04 22:15 ` [PATCH 3.4 13/19] nfsd4: fix FREE_STATEID lockowner leak Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 14/19] nfsd: getattr for FATTR4_WORD0_FILES_AVAIL needs the statfs buffer Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 15/19] powerpc/pseries: Fix overwritten PE state Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 16/19] powerpc: fix typo CONFIG_PMAC Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 17/19] powerpc: fix typo CONFIG_PPC_CPU Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 18/19] ptrace,x86: force IRET path after a ptrace_stop() Greg Kroah-Hartman
2014-07-04 22:15 ` [PATCH 3.4 19/19] tracing: Fix syscall_*regfunc() vs copy_process() race Greg Kroah-Hartman
2014-07-05  5:39 ` [PATCH 3.4 00/19] 3.4.97-stable review Guenter Roeck
2014-07-05  6:53   ` Satoru Takeuchi
2014-07-05 17:47     ` Greg Kroah-Hartman
2014-07-05 17:46   ` Greg Kroah-Hartman
2014-07-05 17:48     ` Greg Kroah-Hartman
2014-07-05 18:26       ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140704221436.990386492@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=bvanassche@acm.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=roland@purestorage.com \
    --cc=stable@vger.kernel.org \
    --cc=ydroneaud@opteya.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).