Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp9416507pxu; Mon, 28 Dec 2020 15:47:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJxGDJFqyOWwAwYH7Tp2Jkch/dHXrHgYDoFGo8wTKHh0IDDBvLIp8hZIvEo2zwf/5Ps3VRXg X-Received: by 2002:a50:ac86:: with SMTP id x6mr44073245edc.197.1609199269713; Mon, 28 Dec 2020 15:47:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609199269; cv=none; d=google.com; s=arc-20160816; b=C4oUEVr18yd+OFx9wjWmUs7ALwQ7K2DhIow2kM6mmxoZOeGSmiw2pZDelNMaE8eakA GXbO2JmoohkdsEQWSvpn19umbOL6jryigLObAEovv214ax1bAqXgdO2WtyJzrYhgDGNs hg9bPCDLfYbx+tLAOKoRCOYhxHIQ6xSzkG8csOqyvV+bHPS66igaFnUtTvX6xKwsg6ZV E9zR8+YAI+HDX5R+3NvUA0Bi1ajuKxnFgkNNtUtwWnyPILW93mfR4fATK+DORp73J2tv Aun84kI/wXAVq5w3AFoBgZWfxmTMb9b5QsoAt7folB9nFgQ3Zaw6ryklDSGL1KveQvLJ w8XA== 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=+VIM+NtHktVXT/6cYO9o+dCa9hNTRuwGYvmanBS8dBI=; b=TVQJFCnwK93XcipPaqL59+x7FJSWD3TjTi1DgDUVE7eM97fL1aJ+C2ZMIvWRp/jwyj 57HklGpsDiW/Nw77enX2iRgHqY76Subbz3RF/7z/3iA+XhbU9eclGrnvRzjvbGgXdo+k /VJd3jTzNge+LObuDgSS34FUtgUZwC/NbPPkcGTpDyNP5RNfm/uoriuTZvpGsMlEdoXy eIY5+GehpD9UsUIGtoj4Y0GO0nI7IAEzYpRtxg2H+OEoaFjTX3AJ8Aedff3w1aP27ujU c8tTzCBLC+llBWikMMBRTM1L+1Hu2AHiccHvGz/LLFi1qpQ7Drh5LwuUy+/lXYFcYL2Z qngQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=fFduu8qX; 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 v14si21009930edr.397.2020.12.28.15.47.27; Mon, 28 Dec 2020 15:47:49 -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=fFduu8qX; 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 S2392159AbgL1Of4 (ORCPT + 99 others); Mon, 28 Dec 2020 09:35:56 -0500 Received: from mail.kernel.org ([198.145.29.99]:40476 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2504943AbgL1OdQ (ORCPT ); Mon, 28 Dec 2020 09:33:16 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5BD082053B; Mon, 28 Dec 2020 14:33:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609165980; bh=Rwv01PGWWLZf6hc+t2V07kshtlZbgIQx3NHqh79qWLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fFduu8qXwV1blkYClGvYkYkCxmMcoTitFnLCrV6ddg2L97z2IbHXIUzzmP9deaLzf XsdqR5A2Cc/fyaNm/CcKAIGYy2IENik6+HjnKSB/n7rB9VXcldyoptWTuCEEmaK4hT BZ/QRIjCk+00NJOnYjZB0DZZKjA+j2WBqaWCdU+A= 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 5.10 716/717] null_blk: Fix zone size initialization Date: Mon, 28 Dec 2020 13:51:54 +0100 Message-Id: <20201228125055.302296396@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201228125020.963311703@linuxfoundation.org> References: <20201228125020.963311703@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 | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -6,8 +6,7 @@ #define CREATE_TRACE_POINTS #include "null_blk_trace.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) { @@ -16,7 +15,7 @@ static inline unsigned int null_zone_no( int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q) { - sector_t dev_size = (sector_t)dev->size * 1024 * 1024; + sector_t dev_capacity_sects, zone_capacity_sects; sector_t sector = 0; unsigned int i; @@ -38,9 +37,13 @@ int null_init_zoned_dev(struct nullb_dev return -EINVAL; } - dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT; - dev->nr_zones = dev_size >> - (SECTOR_SHIFT + ilog2(dev->zone_size_sects)); + zone_capacity_sects = MB_TO_SECTS(dev->zone_capacity); + 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) @@ -101,8 +104,12 @@ int null_init_zoned_dev(struct nullb_dev struct blk_zone *zone = &dev->zones[i]; zone->start = zone->wp = sector; - zone->len = dev->zone_size_sects; - zone->capacity = dev->zone_capacity << ZONE_SIZE_SHIFT; + 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->capacity = + min_t(sector_t, zone->len, zone_capacity_sects); zone->type = BLK_ZONE_TYPE_SEQWRITE_REQ; zone->cond = BLK_ZONE_COND_EMPTY;