Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp13934764pxu; Mon, 4 Jan 2021 08:20:35 -0800 (PST) X-Google-Smtp-Source: ABdhPJzY2vr+X5GBIPYwjw4ulSiR+Er7CaQbBhDVPF4bjqoyz9v3aRbQGr7EC+dR6fDrOeTMfXvy X-Received: by 2002:a50:9f4e:: with SMTP id b72mr72051706edf.200.1609777235473; Mon, 04 Jan 2021 08:20:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609777235; cv=none; d=google.com; s=arc-20160816; b=xldKeP2lT3EMJqEaJOL0gdB3x2J1To1VP9v9egcpxqzKg76QaAm7e6eU+U+X555453 XKT1s9c2t5VlOCGXxfMlPdnNIh8REJFEJoSpBvQkFdzNFIcNEVFsVxh+jgInqmJ09t8V kpgPSyANOWUzJDL/g/j4Z/cFPqp8qwu6RcOdZFa53XiBwtY0b/iTvOqDmQEaq3tFYWUp o6yBP1neDFxXQNI21leuAZQrBW2SYw5sC7+snHTpIptbOHPSoikTgErPWzV637mOfLSp 9xCpmZTyo9ndSnXPB8ul9RD5ArRlJcaI3lvEkeCrMak08m2ZxOtfTV0iShLTok1D891J LiUA== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=n80n4xrP36mJMDL0m4+QtKr/7QvNGx5vASwE/rCTghM=; b=LMRnFJRy+G6pO3Z/D3GC6vGEleTLakLjR9l5PtROdCtsKJTN0XzApGw8nQ6vvCiUTu nn6GAeYzHmnqRJmFxnYq2AAMpK7ebSXkQIPnv6O1wVVeao4ZGSD06+3cg0KDs99iNZED HD6WBRegaqbVFmyXOkO3dV8YJlrYkZCvQCsxE1J2CObfBMuy+A8vjyPzqdg9qWsklair tmW/ngqXuuj/NCl1IihTC4TckBhbZIC7YVXEGW8BtLE2GPACEC2esyf+Uhio0Ld4B72V FF3hLlVscOi3k1y8/CEDJCbWlOKfnmtCfuMZW9V+sKqtdvpwXwawBbR5jlhrAlbupLVk H2Kg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=W0nXoYcu; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id j24si29079314ejd.743.2021.01.04.08.20.11; Mon, 04 Jan 2021 08:20:35 -0800 (PST) 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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=W0nXoYcu; 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=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727846AbhADP7V (ORCPT + 99 others); Mon, 4 Jan 2021 10:59:21 -0500 Received: from mail.kernel.org ([198.145.29.99]:36472 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727695AbhADP7V (ORCPT ); Mon, 4 Jan 2021 10:59:21 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 9302F224D2; Mon, 4 Jan 2021 15:58:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609775893; bh=gntcKiKH6MKwyJ13aC9reLITQxIHhBnob8ZN6++dOwg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W0nXoYcuMkgyyVtUWNOf0wZI3+Il4MmPVGwnV78EKVfeKovZDwQrTvA3itx5jgA87 m59Zyw5P7eUPAghHT/2cEAN5LUEYxMBhH3A4uFQ5xZBTnQBSajD2zlXqIpez8grbuV bWd+m2hHbn/agO7/Dn8vo1yjJ+9JOwDGvWniwI14= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Naohiro Aota , Damien Le Moal , Christoph Hellwig , Johannes Thumshirn , Jens Axboe Subject: [PATCH 4.19 13/35] null_blk: Fix zone size initialization Date: Mon, 4 Jan 2021 16:57:16 +0100 Message-Id: <20210104155704.049016882@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210104155703.375788488@linuxfoundation.org> References: <20210104155703.375788488@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Damien Le Moal commit 0ebcdd702f49aeb0ad2e2d894f8c124a0acc6e23 upstream. For a null_blk device with zoned mode enabled is currently initialized with a number of zones equal to the device capacity divided by the zone size, without considering if the device capacity is a multiple of the zone size. If the zone size is not a divisor of the capacity, the zones end up not covering the entire capacity, potentially resulting is out of bounds accesses to the zone array. Fix this by adding one last smaller zone with a size equal to the remainder of the disk capacity divided by the zone size if the capacity is not a multiple of the zone size. For such smaller last zone, the zone capacity is also checked so that it does not exceed the smaller zone size. Reported-by: Naohiro Aota Fixes: ca4b2a011948 ("null_blk: add zone support") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal Reviewed-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/block/null_blk_zoned.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include "null_blk.h" -/* zone_size in MBs to sectors. */ -#define ZONE_SIZE_SHIFT 11 +#define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT) static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect) { @@ -12,7 +12,7 @@ static inline unsigned int null_zone_no( int null_zone_init(struct nullb_device *dev) { - sector_t dev_size = (sector_t)dev->size * 1024 * 1024; + sector_t dev_capacity_sects; sector_t sector = 0; unsigned int i; @@ -25,9 +25,12 @@ int null_zone_init(struct nullb_device * return -EINVAL; } - dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT; - dev->nr_zones = dev_size >> - (SECTOR_SHIFT + ilog2(dev->zone_size_sects)); + dev_capacity_sects = MB_TO_SECTS(dev->size); + dev->zone_size_sects = MB_TO_SECTS(dev->zone_size); + dev->nr_zones = dev_capacity_sects >> ilog2(dev->zone_size_sects); + if (dev_capacity_sects & (dev->zone_size_sects - 1)) + dev->nr_zones++; + dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct blk_zone), GFP_KERNEL | __GFP_ZERO); if (!dev->zones) @@ -37,7 +40,10 @@ int null_zone_init(struct nullb_device * struct blk_zone *zone = &dev->zones[i]; zone->start = zone->wp = sector; - zone->len = dev->zone_size_sects; + if (zone->start + dev->zone_size_sects > dev_capacity_sects) + zone->len = dev_capacity_sects - zone->start; + else + zone->len = dev->zone_size_sects; zone->type = BLK_ZONE_TYPE_SEQWRITE_REQ; zone->cond = BLK_ZONE_COND_EMPTY;