From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:50528 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933546AbdERK47 (ORCPT ); Thu, 18 May 2017 06:56:59 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jason Gunthorpe , Dan Williams , Logan Gunthorpe , Johannes Thumshirn Subject: [PATCH 4.10 74/93] device-dax: fix cdev leak Date: Thu, 18 May 2017 12:47:43 +0200 Message-Id: <20170518104746.082082062@linuxfoundation.org> In-Reply-To: <20170518104743.163522815@linuxfoundation.org> References: <20170518104743.163522815@linuxfoundation.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: stable-owner@vger.kernel.org List-ID: 4.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dan Williams commit ed01e50acdd3e4a640cf9ebd28a7e810c3ceca97 upstream. If device_add() fails, cleanup the cdev. Otherwise, we leak a kobj_map() with a stale device number. As Jason points out, there is a small possibility that userspace has opened and mapped the device in the time between cdev_add() and the device_add() failure. We need a new kill_dax_dev() helper to invalidate any established mappings. Fixes: ba09c01d2fa8 ("dax: convert to the cdev api") Reported-by: Jason Gunthorpe Signed-off-by: Dan Williams Signed-off-by: Logan Gunthorpe Reviewed-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/dax/dax.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- a/drivers/dax/dax.c +++ b/drivers/dax/dax.c @@ -646,13 +646,10 @@ static void dax_dev_release(struct devic kfree(dax_dev); } -static void unregister_dax_dev(void *dev) +static void kill_dax_dev(struct dax_dev *dax_dev) { - struct dax_dev *dax_dev = to_dax_dev(dev); struct cdev *cdev = &dax_dev->cdev; - dev_dbg(dev, "%s\n", __func__); - /* * Note, rcu is not protecting the liveness of dax_dev, rcu is * ensuring that any fault handlers that might have seen @@ -664,6 +661,15 @@ static void unregister_dax_dev(void *dev synchronize_srcu(&dax_srcu); unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1); cdev_del(cdev); +} + +static void unregister_dax_dev(void *dev) +{ + struct dax_dev *dax_dev = to_dax_dev(dev); + + dev_dbg(dev, "%s\n", __func__); + + kill_dax_dev(dax_dev); device_unregister(dev); } @@ -740,6 +746,7 @@ struct dax_dev *devm_create_dax_dev(stru dev_set_name(dev, "dax%d.%d", dax_region->id, dax_dev->id); rc = device_add(dev); if (rc) { + kill_dax_dev(dax_dev); put_device(dev); return ERR_PTR(rc); }