[Devel] [PATCH RHEL7 COMMIT] ploop: Fix partition refcounter leak

Vasily Averin vvs at virtuozzo.com
Thu Sep 23 18:15:28 MSK 2021


The commit is pushed to "branch-rh7-3.10.0-1160.41.1.vz7.183.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.41.1.vz7.183.4
------>
commit 2b8d9cf32c04e2bf3eab299234b76773f424db9e
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date:   Thu Sep 23 18:15:28 2021 +0300

    ploop: Fix partition refcounter leak
    
    ms commit b7d6c3033323 ("block: fix use-after-free on cached
    last_lookup partition") has changed the semantic of
    disk_map_sector_rcu() function: previously it only returned appropriate
    partition but after the patch it additionally gets a refcounter on that
    partition.
    
    RedHat has backported that patch in RHEL7 as
    https://access.redhat.com/labs/rhcb/RHEL-7.9/kernel-3.10.0-1160.31.1.el7/patches/blob/1050-block-fix-use-after-free-on-cached-last_lookup-parti.patch
    
    We use disk_map_sector_rcu() in ploop_make_request() for getting proper
    partition for correct i/o accounting and thus during the rebase of
    3.10.0-1160.25.1.vz7.180.12 onto 3.10.0-1160.31.1.el7
    (3.10.0-1160.31.1.vz7.181.1) we've got refcounters leak which led to:
    
     * leaking hd_struct-s for ploop devices partitions on Containers
       start/stop, suspend/resume, mount/umount, etc.
     * as a side effect we've got broken statistics for ploop partitions in
       50% cases (always zeroes are shown)
    
    Fix the leak by adding pair hd_struct_put() into ploop code.
    
    Fixes: 03edeead80d9 ("ploop: fix gendisk disk_stats to be seen on
    partition")
    
    https://jira.sw.ru/browse/PSBM-131919
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 block/partition-generic.c | 1 +
 drivers/block/ploop/dev.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/block/partition-generic.c b/block/partition-generic.c
index 164d364..dd3a185 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -253,6 +253,7 @@ void __delete_partition(struct hd_struct *part)
 
 	call_rcu(&part->rcu_head, delete_partition_rcu_cb);
 }
+EXPORT_SYMBOL(__delete_partition);
 
 void delete_partition(struct gendisk *disk, int partno)
 {
diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 9abce6a..06b7254 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -982,6 +982,7 @@ static void ploop_make_request(struct request_queue *q, struct bio *bio)
 	part = disk_map_sector_rcu(plo->disk, bio->bi_sector);
 	part_stat_inc(cpu, part, ios[rw]);
 	part_stat_add(cpu, part, sectors[rw], bio_sectors(bio));
+	hd_struct_put(part);
 	part_stat_unlock();
 
 	if (blk_queue_standby(plo->queue)) {


More information about the Devel mailing list