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 2F95C44AB68; Tue, 21 Jul 2026 21:24:29 +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=1784669070; cv=none; b=c1CnHBw9vZJS+AZEivLnPySoK4pqpBVM2joeHJhJDZJe4YEL3NlBuUBG9tiJYeEcApHR9WF6s2wCEX1BSKS8/EIhPmVSh5ec7m281pe1hK7J1ZycTkk9kxRukhEAzBgCfTKiYkPsf0h/2bdY7wwLrfQhgcczPUHHc9P4uBzEzsk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784669070; c=relaxed/simple; bh=H31dCqBmpb7HL9ea6x7Cb9vofiYDBgEVQUq7zlMjSxQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=oHcKcVqFI4Y/5m5mJXb6voMy8rh0NJ0uEaCSNthHzBFL18T88QzqIe5t9aaDud5xt8uPwgqoisTwvHdTapdqEvnlllPyyu19X5mr5SXeSdP9UeI6nhwY+L2mWRqPMmpiOKDywn26hvhfHtGCyojVB/6ZpnM2ZqF1toa+5cRUHvc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=peQ4VaFf; 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="peQ4VaFf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9522D1F000E9; Tue, 21 Jul 2026 21:24:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1784669069; bh=0/q/JGerBB0k1ngtk73Wd8qCf948ghdkpAWEp2aheoU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=peQ4VaFfBfgS/9zhN5Hu43xmehTK+tzpfYzGiR4ZGHGGMFwI6KAg15jCmxOs4LPox NZoxe7Yx5/xuEvKcljVyOwzBvD9E8mvak2uSfwZ6RcQpfgf2Pv3TybEWVZjZHNzNlX GenXb0xKRCB+BZreTCC1vsQU2yvIhC0HRidbDbRs= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, =?UTF-8?q?Eugenio=20P=C3=A9rez?= , "Michael S. Tsirkin" , Qihang Tang , Sasha Levin Subject: [PATCH 6.1 0414/1067] vhost/vdpa: validate virtqueue index in mmap and fault paths Date: Tue, 21 Jul 2026 17:16:55 +0200 Message-ID: <20260721152433.887296941@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260721152424.521567757@linuxfoundation.org> References: <20260721152424.521567757@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-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Qihang Tang [ Upstream commit 929e4f044621c8cc30b612fb74e1410bef09e41b ] vhost_vdpa_mmap() and vhost_vdpa_fault() use vma->vm_pgoff as a virtqueue index for get_vq_notification(), but they do not validate that the index is smaller than v->nvqs. The ioctl path already performs both a bounds check and array_index_nospec(), but the mmap/fault path only checks that the index fits in u16. This allows an out-of-range queue index to reach driver-specific get_vq_notification() callbacks. Fix this by extracting a unified vhost_vdpa_get_vq_notification() helper that validates the queue index against v->nvqs and applies array_index_nospec() before calling the driver callback. Both the mmap and fault paths use this helper, and the bounds checking is consolidated into a single location. >>From source inspection, the most defensible impact is out-of-bounds access in the callback path, potentially leading to invalid PFN remaps and crash/DoS. Fixes: ddd89d0a059d ("vhost_vdpa: support doorbell mapping via mmap") Acked-by: Eugenio PĂ©rez Acked-by: Michael S. Tsirkin Signed-off-by: Qihang Tang Signed-off-by: Michael S. Tsirkin Message-ID: <20260508075821.92656-1-q.h.hack.winter@gmail.com> Signed-off-by: Sasha Levin --- drivers/vhost/vdpa.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 59587f9880d3c7..7684c16e9e07a2 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -1295,16 +1295,32 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep) } #ifdef CONFIG_MMU -static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf) +static int +vhost_vdpa_get_vq_notification(struct vhost_vdpa *v, unsigned long index, + struct vdpa_notification_area *notify) { - struct vhost_vdpa *v = vmf->vma->vm_file->private_data; struct vdpa_device *vdpa = v->vdpa; const struct vdpa_config_ops *ops = vdpa->config; + + if (index > 65535 || index >= v->nvqs) + return -EINVAL; + + index = array_index_nospec(index, v->nvqs); + + *notify = ops->get_vq_notification(vdpa, index); + + return 0; +} + +static vm_fault_t vhost_vdpa_fault(struct vm_fault *vmf) +{ + struct vhost_vdpa *v = vmf->vma->vm_file->private_data; struct vdpa_notification_area notify; struct vm_area_struct *vma = vmf->vma; - u16 index = vma->vm_pgoff; + unsigned long index = vma->vm_pgoff; - notify = ops->get_vq_notification(vdpa, index); + if (vhost_vdpa_get_vq_notification(v, index, ¬ify)) + return VM_FAULT_SIGBUS; return vmf_insert_pfn(vma, vmf->address & PAGE_MASK, PFN_DOWN(notify.addr)); } @@ -1327,8 +1343,6 @@ static int vhost_vdpa_mmap(struct file *file, struct vm_area_struct *vma) return -EINVAL; if (vma->vm_flags & VM_READ) return -EINVAL; - if (index > 65535) - return -EINVAL; if (!ops->get_vq_notification) return -ENOTSUPP; @@ -1336,7 +1350,8 @@ static int vhost_vdpa_mmap(struct file *file, struct vm_area_struct *vma) * support the doorbell which sits on the page boundary and * does not share the page with other registers. */ - notify = ops->get_vq_notification(vdpa, index); + if (vhost_vdpa_get_vq_notification(v, index, ¬ify)) + return -EINVAL; if (notify.addr & (PAGE_SIZE - 1)) return -EINVAL; if (vma->vm_end - vma->vm_start != notify.size) -- 2.53.0