Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp13928104pxu; Mon, 4 Jan 2021 08:11:12 -0800 (PST) X-Google-Smtp-Source: ABdhPJwJMsVWwuatUyjKI0sRgu7r1D0RJqp2wl+DLLJK9qPuUtkkMR7ofRte/l9ROBITnE2/AsWu X-Received: by 2002:a05:6402:1ad1:: with SMTP id ba17mr69921976edb.51.1609776672725; Mon, 04 Jan 2021 08:11:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1609776672; cv=none; d=google.com; s=arc-20160816; b=aM1tceUfrkQZYdE/4jWPlP+pkYVAV2bqMLjGu5be3CXR+CN4fyRi6oHKT1+Iwxxapi 5tIfZ2OEB07cKLKDURDtBGo2ZjJO0GtZsEatatRvfiY9165RVnhpe16WflEHrT0KAZzH XRIeu4OwhbJsYPJAtJNSTGOl3/NKOLOs66dW8TmFEynd7fiVMihphMv0ko1Gq0aZijiv 4ZTuf99CyVuAqHY1eCPrqLs0F4yw/ptO3NrSefle9Zl2XySXvBZo4H2qmMhbMBVcZV/0 18IRDUo3briO/dSkooXJZBbS1nIk5h4c6cHDpuXBY9A5Pdsosp8g4iJ/5/PtSae3Wdeu Ppjw== 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=tKRhBTYl5PhnQ8K2grWWE7gV36enes86SwLDElPDp90=; b=Le/uYnrL7/78K262AUJfyQ66+cROWlip9epyeiK5+rWrdyZyOhN4snEA0sEpZzkaIp FPeyyh+FQGdZV4O+UdQyJvWqhsPPKMdUqJLGLLSSW61NdWuEjvL7n6qpr8BHkz6lbCoX f3zPuOMsKqWxjz/x7nl29dqMgXdmCOa/MsnOIJwliZGOPwv2PXeag04dwn+ZE+12XFIn wE/242IKrcNWfMCaNQA89dhj9X6WsVkWCc0NA1H/kbuRg8SjjTR6H3W5+1vC7CSLWgZK A4w/gw3gRR/F/csxTOUwOvuFj8GYpqFlyLCdyE/epjrHiXNha7kfw3zSGtw9JUL6PPqw mwjQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=I4J15YzC; 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 i6si31704834ejs.659.2021.01.04.08.10.49; Mon, 04 Jan 2021 08:11:12 -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=I4J15YzC; 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 S1728657AbhADQBq (ORCPT + 99 others); Mon, 4 Jan 2021 11:01:46 -0500 Received: from mail.kernel.org ([198.145.29.99]:38936 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728632AbhADQBl (ORCPT ); Mon, 4 Jan 2021 11:01:41 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 15F3422509; Mon, 4 Jan 2021 16:00:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1609776060; bh=UJRdoaY3or4JUrm1zrUdcYYaAw3oxoJavuX/W0MLPfk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I4J15YzCKwsEz8rHooEjLOpLtsNZ/yYSuuzCQRqhBKHkmUxhBliuAzlcKOZyivTAQ I1jGwFujZP9PxJxl/X7Yg5byRz6D/i2S5JmYQikcpvqW8JQ6jHQ+H4ocDEXspf/l7+ YSaKhPFiozZCRDWxgdgbz1MIngbqSNp5k9GnVUQg= 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.4 21/47] null_blk: Fix zone size initialization Date: Mon, 4 Jan 2021 16:57:20 +0100 Message-Id: <20210104155706.765238053@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210104155705.740576914@linuxfoundation.org> References: <20210104155705.740576914@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 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -2,8 +2,7 @@ #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 +11,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 +24,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) @@ -55,7 +57,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;