Received: by 2002:a05:6a10:6d25:0:0:0:0 with SMTP id gq37csp242297pxb; Sat, 11 Sep 2021 03:54:58 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxYEIbbqvvE5ycX4Zg/gFNVWpC9jQtmGxL0c1r+kIeOZZKuZvwUroO8eDp9gO0PaqXC+cun X-Received: by 2002:a50:ed02:: with SMTP id j2mr2691152eds.391.1631357698411; Sat, 11 Sep 2021 03:54:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631357698; cv=none; d=google.com; s=arc-20160816; b=ydZdQxIGJqSzDKA8X8lOBtEjfqvXg75xrJMuw2Q+3q67kA25xGBz+ILymFWdJ3nx3a 4z89WDS1KshqmAMbunDstc20ap10PrVzlHXjaU2Gn9IMqpUa0CdfvsynyQyi7JG9Acjl kO511dey3zPmivGu9H97JXbJppQUimgBuHv5MhhuYPsspOFXAYlJoZJlZiLsx+XcU9IV u76ZT9JFqT8trMDhF0HQT8yeSk8qhfw5cnIx5LQPR44cL0YQ5+INWvEXnVBBIENAI0N3 BhONPPj4yoPGqLjddZpGD1tkXDaAsFNQDgZkfbTbQAfgkgBZ6DY0dtFqgFJKQY9n7Fyx kVlA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=dlVmkx0428m+kDCJBQFjQKVaJzONR73qe+pG3I55goQ=; b=F+9docemeDfF+qJuFRENPx3kBjENdE4Mq3HIZcrpGsdC1QN0MC0yCzQVblWIgHx/5+ O8tuG92aiXuxqy0WhSo/MRCWmJBwXbM3t4EwxLZqjMNtCfjaTE81NkyKCvLJl6iS2R9i tzaYQNMI/yyq+Fb/nrnLsgklrv90MHU47oCfKH3DVBoExYT4PKPCENlO+VH/5n9v819o oBVLH3hhGtSiJ5ZM8NaxM2AUOX/nuQp6gxgjWtMR4EyDOfaFvrfMQEUh57AZ7zcTG26i GcXU1WB4DCBrbZNrINK9u0qAxzvMxa4I7gtc2L8tLP8DuTBBS0+dGKeGzWQ4Hix9e0U1 TjPg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s18si1965804eji.591.2021.09.11.03.54.34; Sat, 11 Sep 2021 03:54:58 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235685AbhIKKyZ (ORCPT + 99 others); Sat, 11 Sep 2021 06:54:25 -0400 Received: from szxga01-in.huawei.com ([45.249.212.187]:19030 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230131AbhIKKyY (ORCPT ); Sat, 11 Sep 2021 06:54:24 -0400 Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.54]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4H68cg2k6kzblqB; Sat, 11 Sep 2021 18:49:07 +0800 (CST) Received: from dggema764-chm.china.huawei.com (10.1.198.206) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2308.8; Sat, 11 Sep 2021 18:53:10 +0800 Received: from DESKTOP-8RFUVS3.china.huawei.com (10.174.185.179) by dggema764-chm.china.huawei.com (10.1.198.206) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.8; Sat, 11 Sep 2021 18:53:09 +0800 From: Zenghui Yu To: , , CC: , , , , , , , Zenghui Yu Subject: [PATCH v2] scsi: bsg: Fix device unregistration Date: Sat, 11 Sep 2021 18:53:06 +0800 Message-ID: <20210911105306.1511-1-yuzenghui@huawei.com> X-Mailer: git-send-email 2.23.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.174.185.179] X-ClientProxiedBy: dggems705-chm.china.huawei.com (10.3.19.182) To dggema764-chm.china.huawei.com (10.1.198.206) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We use device_initialize() to take refcount for the device but forget to put_device() on device teardown, which ends up leaking private data of the driver core, dev_name(), etc. This is reported by kmemleak at boot time if we compile kernel with DEBUG_TEST_DRIVER_REMOVE. Note that adding the missing put_device() is _not_ sufficient to fix device unregistration. As we don't provide the .release() method for device, which turned out to be typically wrong and will be complained loudly by the driver core. Fix both of them. Fixes: ead09dd3aed5 ("scsi: bsg: Simplify device registration") Signed-off-by: Zenghui Yu --- * From v1 [1]: - As pointed out by Johan, fix UAF and double-free on error path ... - ... so I didn't collect Christoph and Greg's R-b tags (but thanks for reviewing) [1] https://lore.kernel.org/r/20210909034608.1435-1-yuzenghui@huawei.com block/bsg.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/block/bsg.c b/block/bsg.c index 351095193788..882f56bff14f 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -165,13 +165,20 @@ static const struct file_operations bsg_fops = { .llseek = default_llseek, }; +static void bsg_device_release(struct device *dev) +{ + struct bsg_device *bd = container_of(dev, struct bsg_device, device); + + ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); + kfree(bd); +} + void bsg_unregister_queue(struct bsg_device *bd) { if (bd->queue->kobj.sd) sysfs_remove_link(&bd->queue->kobj, "bsg"); cdev_device_del(&bd->cdev, &bd->device); - ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); - kfree(bd); + put_device(&bd->device); } EXPORT_SYMBOL_GPL(bsg_unregister_queue); @@ -193,11 +200,13 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, if (ret < 0) { if (ret == -ENOSPC) dev_err(parent, "bsg: too many bsg devices\n"); - goto out_kfree; + kfree(bd); + return ERR_PTR(ret); } bd->device.devt = MKDEV(bsg_major, ret); bd->device.class = bsg_class; bd->device.parent = parent; + bd->device.release = bsg_device_release; dev_set_name(&bd->device, "%s", name); device_initialize(&bd->device); @@ -205,7 +214,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, bd->cdev.owner = THIS_MODULE; ret = cdev_device_add(&bd->cdev, &bd->device); if (ret) - goto out_ida_remove; + goto out_put_device; if (q->kobj.sd) { ret = sysfs_create_link(&q->kobj, &bd->device.kobj, "bsg"); @@ -217,10 +226,8 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, out_device_del: cdev_device_del(&bd->cdev, &bd->device); -out_ida_remove: - ida_simple_remove(&bsg_minor_ida, MINOR(bd->device.devt)); -out_kfree: - kfree(bd); +out_put_device: + put_device(&bd->device); return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(bsg_register_queue); -- 2.19.1