From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36FB147FAF0; Thu, 20 Aug 2026 17:45:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787247910; cv=none; b=ZiTmQFRKULkkzqiE5Zevs7xPrPK7Wnpu+KxNKYs1r4/yaMk3NLPMJ2O/PuY5ufGuLLix3BSc8tnljXVJsLpOuiDUByVUllR+eWOOfCWAfK91k4PJfI98fj2sfbfngv456nCxDSHWaPcWjx1xkx9pyqrCZdegJetAmK63i+Ip0lY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787247910; c=relaxed/simple; bh=kJL1wNVQ4U1pPbdyKWeIsT2scxFDXjz3mA4naDyUir4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IHM0v0NHpDx/lwPxne2Yk/7WHYqldtu/QIlos5vDFRpyCtrlgP9vsqZVSdJryRU0BlRC/DFkrL9tn7kXspx2VKSguTvZTikYh4DkrH/Wqpe1gKE5S1B149JX1ys6PXckidTspgb4jsm/fi00C7jT/Gwzl113yncK2nNCrntJ/f0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=CWLeIhYw; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="CWLeIhYw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 508FB1F00A3D; Thu, 20 Aug 2026 17:45:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1787247908; bh=02t3a6aVsHgckbpKpTddEldOq/Ml57+Co3H9DXE7gHY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=CWLeIhYwBdMeJ2nUK6a5ULlK1w/gprP6hQHkRgmN4bGOZrIG2YEx4yIaMAuneUhYA PiuAuia3ZgDtESoKp0omKEo7E771FrbmaYKdeNB3QtOGYozBSJNMarbhaSKxDX3pCE apyY85+H3ldoKCxj9qAawmH5Akoz+WYUsbAXcgUA= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Cornelia Huck , Matthew Rosato , Eric Farman , Christian Borntraeger Subject: [PATCH 6.1 044/303] s390/vfio_ccw: Ensure index for read/write regions are within range Date: Thu, 20 Aug 2026 16:53:00 +0200 Message-ID: <20260820145254.498601635@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260820145253.200766705@linuxfoundation.org> References: <20260820145253.200766705@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Eric Farman commit 9f5f9a78fedc45bc29d6a0a64e3a3472361afae5 upstream. The introduction of the capability chain rightly clamped the region indexes to the range of the capabilities itself, but neglected to do so for the existing read/write regions which should also be enforced. Fixes: db8e5d17ac03 ("vfio-ccw: add capabilities chain") Cc: stable@vger.kernel.org Cc: Cornelia Huck Reviewed-by: Matthew Rosato Signed-off-by: Eric Farman Signed-off-by: Christian Borntraeger Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/vfio_ccw_async.c | 16 ++++++++++++++++ drivers/s390/cio/vfio_ccw_chp.c | 15 +++++++++++++++ drivers/s390/cio/vfio_ccw_ops.c | 7 +++---- 3 files changed, 34 insertions(+), 4 deletions(-) --- a/drivers/s390/cio/vfio_ccw_async.c +++ b/drivers/s390/cio/vfio_ccw_async.c @@ -8,6 +8,7 @@ */ #include +#include #include "vfio_ccw_private.h" @@ -24,11 +25,20 @@ static ssize_t vfio_ccw_async_region_rea return -EINVAL; mutex_lock(&private->io_mutex); + + if (i >= private->num_regions) { + ret = -EINVAL; + goto out_unlock; + } + + i = array_index_nospec(i, private->num_regions); region = private->region[i].data; if (copy_to_user(buf, (void *)region + pos, count)) ret = -EFAULT; else ret = count; + +out_unlock: mutex_unlock(&private->io_mutex); return ret; } @@ -48,6 +58,12 @@ static ssize_t vfio_ccw_async_region_wri if (!mutex_trylock(&private->io_mutex)) return -EAGAIN; + if (i >= private->num_regions) { + ret = -EINVAL; + goto out_unlock; + } + + i = array_index_nospec(i, private->num_regions); region = private->region[i].data; if (copy_from_user((void *)region + pos, buf, count)) { ret = -EFAULT; --- a/drivers/s390/cio/vfio_ccw_chp.c +++ b/drivers/s390/cio/vfio_ccw_chp.c @@ -9,6 +9,7 @@ */ #include +#include #include #include "vfio_ccw_private.h" @@ -25,6 +26,13 @@ static ssize_t vfio_ccw_schib_region_rea return -EINVAL; mutex_lock(&private->io_mutex); + + if (i >= private->num_regions) { + ret = -EINVAL; + goto out; + } + + i = array_index_nospec(i, private->num_regions); region = private->region[i].data; if (cio_update_schib(private->sch)) { @@ -96,6 +104,12 @@ static ssize_t vfio_ccw_crw_region_read( list_del(&crw->next); mutex_lock(&private->io_mutex); + if (i >= private->num_regions) { + ret = -EINVAL; + goto out; + } + + i = array_index_nospec(i, private->num_regions); region = private->region[i].data; if (crw) @@ -108,6 +122,7 @@ static ssize_t vfio_ccw_crw_region_read( region->crw = 0; +out: mutex_unlock(&private->io_mutex); kfree(crw); --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -203,6 +203,7 @@ static ssize_t vfio_ccw_mdev_read(struct return vfio_ccw_mdev_read_io_region(private, buf, count, ppos); default: index -= VFIO_CCW_NUM_REGIONS; + index = array_index_nospec(index, private->num_regions); return private->region[index].ops->read(private, buf, count, ppos); } @@ -255,6 +256,7 @@ static ssize_t vfio_ccw_mdev_write(struc return vfio_ccw_mdev_write_io_region(private, buf, count, ppos); default: index -= VFIO_CCW_NUM_REGIONS; + index = array_index_nospec(index, private->num_regions); return private->region[index].ops->write(private, buf, count, ppos); } @@ -297,11 +299,8 @@ static int vfio_ccw_mdev_get_region_info VFIO_CCW_NUM_REGIONS + private->num_regions) return -EINVAL; - info->index = array_index_nospec(info->index, - VFIO_CCW_NUM_REGIONS + - private->num_regions); - i = info->index - VFIO_CCW_NUM_REGIONS; + i = array_index_nospec(i, private->num_regions); info->offset = VFIO_CCW_INDEX_TO_OFFSET(info->index); info->size = private->region[i].size;