From: Greg Kroah-Hartman Date: Tue, 8 Oct 2024 10:44:04 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v6.6.55~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e7dbacfbf23715e21abeffcf91f2ba72aaac74e;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: vhost-scsi-null-ptr-dereference-in-vhost_scsi_get_req.patch --- diff --git a/queue-5.15/9p-add-missing-locking-around-taking-dentry-fid-list.patch b/queue-5.15/9p-add-missing-locking-around-taking-dentry-fid-list.patch index d3524b4acda..4109d6b82ab 100644 --- a/queue-5.15/9p-add-missing-locking-around-taking-dentry-fid-list.patch +++ b/queue-5.15/9p-add-missing-locking-around-taking-dentry-fid-list.patch @@ -44,14 +44,12 @@ Signed-off-by: Dominique Martinet Signed-off-by: Samasth Norway Ananda Signed-off-by: Greg Kroah-Hartman --- - fs/9p/vfs_dentry.c | 9 +++++++-- + fs/9p/vfs_dentry.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) -diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c -index c2736af97884f..afcf4711ac2a8 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c -@@ -52,12 +52,17 @@ static int v9fs_cached_dentry_delete(const struct dentry *dentry) +@@ -52,12 +52,17 @@ static int v9fs_cached_dentry_delete(con static void v9fs_dentry_release(struct dentry *dentry) { struct hlist_node *p, *n; @@ -71,7 +69,3 @@ index c2736af97884f..afcf4711ac2a8 100644 } static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags) --- -2.46.0 - - diff --git a/queue-5.15/series b/queue-5.15/series index eb612208b8a..d1d549463ef 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -586,3 +586,4 @@ acpi-battery-fix-possible-crash-when-unregistering-a.patch revert-arm64-dts-qcom-sm8250-switch-ufs-qmp-phy-to-new-style-of-bindings.patch ext4-fix-inode-tree-inconsistency-caused-by-enomem.patch 9p-add-missing-locking-around-taking-dentry-fid-list.patch +vhost-scsi-null-ptr-dereference-in-vhost_scsi_get_req.patch diff --git a/queue-5.15/vhost-scsi-null-ptr-dereference-in-vhost_scsi_get_req.patch b/queue-5.15/vhost-scsi-null-ptr-dereference-in-vhost_scsi_get_req.patch new file mode 100644 index 00000000000..6733324f563 --- /dev/null +++ b/queue-5.15/vhost-scsi-null-ptr-dereference-in-vhost_scsi_get_req.patch @@ -0,0 +1,115 @@ +From 221af82f606d928ccef19a16d35633c63026f1be Mon Sep 17 00:00:00 2001 +From: Haoran Zhang +Date: Tue, 1 Oct 2024 15:14:15 -0500 +Subject: vhost/scsi: null-ptr-dereference in vhost_scsi_get_req() + +From: Haoran Zhang + +commit 221af82f606d928ccef19a16d35633c63026f1be upstream. + +Since commit 3f8ca2e115e5 ("vhost/scsi: Extract common handling code +from control queue handler") a null pointer dereference bug can be +triggered when guest sends an SCSI AN request. + +In vhost_scsi_ctl_handle_vq(), `vc.target` is assigned with +`&v_req.tmf.lun[1]` within a switch-case block and is then passed to +vhost_scsi_get_req() which extracts `vc->req` and `tpg`. However, for +a `VIRTIO_SCSI_T_AN_*` request, tpg is not required, so `vc.target` is +set to NULL in this branch. Later, in vhost_scsi_get_req(), +`vc->target` is dereferenced without being checked, leading to a null +pointer dereference bug. This bug can be triggered from guest. + +When this bug occurs, the vhost_worker process is killed while holding +`vq->mutex` and the corresponding tpg will remain occupied +indefinitely. + +Below is the KASAN report: +Oops: general protection fault, probably for non-canonical address +0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN NOPTI +KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] +CPU: 1 PID: 840 Comm: poc Not tainted 6.10.0+ #1 +Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS +1.16.3-debian-1.16.3-2 04/01/2014 +RIP: 0010:vhost_scsi_get_req+0x165/0x3a0 +Code: 00 fc ff df 48 89 fa 48 c1 ea 03 80 3c 02 00 0f 85 2b 02 00 00 +48 b8 00 00 00 00 00 fc ff df 4d 8b 65 30 4c 89 e2 48 c1 ea 03 <0f> b6 +04 02 4c 89 e2 83 e2 07 38 d0 7f 08 84 c0 0f 85 be 01 00 00 +RSP: 0018:ffff888017affb50 EFLAGS: 00010246 +RAX: dffffc0000000000 RBX: ffff88801b000000 RCX: 0000000000000000 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff888017affcb8 +RBP: ffff888017affb80 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: ffff888017affc88 R14: ffff888017affd1c R15: ffff888017993000 +FS: 000055556e076500(0000) GS:ffff88806b100000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00000000200027c0 CR3: 0000000010ed0004 CR4: 0000000000370ef0 +Call Trace: + + ? show_regs+0x86/0xa0 + ? die_addr+0x4b/0xd0 + ? exc_general_protection+0x163/0x260 + ? asm_exc_general_protection+0x27/0x30 + ? vhost_scsi_get_req+0x165/0x3a0 + vhost_scsi_ctl_handle_vq+0x2a4/0xca0 + ? __pfx_vhost_scsi_ctl_handle_vq+0x10/0x10 + ? __switch_to+0x721/0xeb0 + ? __schedule+0xda5/0x5710 + ? __kasan_check_write+0x14/0x30 + ? _raw_spin_lock+0x82/0xf0 + vhost_scsi_ctl_handle_kick+0x52/0x90 + vhost_run_work_list+0x134/0x1b0 + vhost_task_fn+0x121/0x350 +... + +---[ end trace 0000000000000000 ]--- + +Let's add a check in vhost_scsi_get_req. + +Fixes: 3f8ca2e115e5 ("vhost/scsi: Extract common handling code from control queue handler") +Signed-off-by: Haoran Zhang +[whitespace fixes] +Signed-off-by: Mike Christie +Message-Id: +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/scsi.c | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +--- a/drivers/vhost/scsi.c ++++ b/drivers/vhost/scsi.c +@@ -899,20 +899,23 @@ vhost_scsi_get_req(struct vhost_virtqueu + /* virtio-scsi spec requires byte 0 of the lun to be 1 */ + vq_err(vq, "Illegal virtio-scsi lun: %u\n", *vc->lunp); + } else { +- struct vhost_scsi_tpg **vs_tpg, *tpg; ++ struct vhost_scsi_tpg **vs_tpg, *tpg = NULL; + +- vs_tpg = vhost_vq_get_backend(vq); /* validated at handler entry */ +- +- tpg = READ_ONCE(vs_tpg[*vc->target]); +- if (unlikely(!tpg)) { +- vq_err(vq, "Target 0x%x does not exist\n", *vc->target); +- } else { +- if (tpgp) +- *tpgp = tpg; +- ret = 0; ++ if (vc->target) { ++ /* validated at handler entry */ ++ vs_tpg = vhost_vq_get_backend(vq); ++ tpg = READ_ONCE(vs_tpg[*vc->target]); ++ if (unlikely(!tpg)) { ++ vq_err(vq, "Target 0x%x does not exist\n", *vc->target); ++ goto out; ++ } + } +- } + ++ if (tpgp) ++ *tpgp = tpg; ++ ret = 0; ++ } ++out: + return ret; + } +