[PATCH OLK-5.10] xen/privcmd: fix double free via VMA splitting
From: Juergen Gross <jgross@suse.com> stable inclusion from stable-v5.10.254 commit dbf862ce9f009128ab86b234d91413a3e450beb4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/14442 CVE: CVE-2026-31787 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- commit 24daca4fc07f3ff8cd0e3f629cd982187f48436a upstream. privcmd_vm_ops defines .close (privcmd_close), but neither .may_split nor .open. When userspace does a partial munmap() on a privcmd mapping, the kernel splits the VMA via __split_vma(). Since may_split is NULL, the split is allowed. vm_area_dup() copies vm_private_data (a pages array allocated in alloc_empty_pages()) into the new VMA without any fixup, because there is no .open callback. Both VMAs now point to the same pages array. When the unmapped portion is closed, privcmd_close() calls: - xen_unmap_domain_gfn_range() - xen_free_unpopulated_pages() - kvfree(pages) The surviving VMA still holds the dangling pointer. When it is later destroyed, the same sequence runs again, which leads to a double free. Fix this issue by adding a .may_split callback denying the VMA split. This is XSA-487 / CVE-2026-31787 Fixes: d71f513985c2 ("xen: privcmd: support autotranslated physmap guests.") Reported-by: Atharva Vartak <atharva.a.vartak@gmail.com> Suggested-by: Atharva Vartak <atharva.a.vartak@gmail.com> Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Lin Ruifeng <linruifeng4@huawei.com> --- drivers/xen/privcmd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 3f198ded58b8..2aa40e58cb94 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -933,6 +933,12 @@ static void privcmd_close(struct vm_area_struct *vma) kfree(pages); } +static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr) +{ + /* Forbid splitting, avoids double free via privcmd_close(). */ + return -EINVAL; +} + static vm_fault_t privcmd_fault(struct vm_fault *vmf) { printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n", @@ -944,6 +950,7 @@ static vm_fault_t privcmd_fault(struct vm_fault *vmf) static const struct vm_operations_struct privcmd_vm_ops = { .close = privcmd_close, + .split = privcmd_may_split, .fault = privcmd_fault }; -- 2.43.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/22169 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/Z23... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/22169 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/Z23...
participants (2)
-
Lin Ruifeng -
patchwork bot