From ffc93111d446837a3a1e562250643dcc23e2e9db Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Mon, 30 Aug 2021 10:06:39 +0800 Subject: [PATCH 1/5] net: 6pack: fix slab-out-of-bounds in decode_data commit:ab388ef13b4e127325130ef7b59232080f5637e4 CVE:CVE-2021-42008 Signed-off-by: wanxiaoqing ----------------------------------------------------------- stable inclusion from linux-4.19.205 commit 4e370cc081a78ee23528311ca58fd98a06768ec7 -------------------------------- [ Upstream commit 19d1532a187669ce86d5a2696eb7275310070793 ] Syzbot reported slab-out-of bounds write in decode_data(). The problem was in missing validation checks. Syzbot's reproducer generated malicious input, which caused decode_data() to be called a lot in sixpack_decode(). Since rx_count_cooked is only 400 bytes and noone reported before, that 400 bytes is not enough, let's just check if input is malicious and complain about buffer overrun. Fail log: ================================================================== BUG: KASAN: slab-out-of-bounds in drivers/net/hamradio/6pack.c:843 Write of size 1 at addr ffff888087c5544e by task kworker/u4:0/7 CPU: 0 PID: 7 Comm: kworker/u4:0 Not tainted 5.6.0-rc3-syzkaller #0 ... Workqueue: events_unbound flush_to_ldisc Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x197/0x210 lib/dump_stack.c:118 print_address_description.constprop.0.cold+0xd4/0x30b mm/kasan/report.c:374 __kasan_report.cold+0x1b/0x32 mm/kasan/report.c:506 kasan_report+0x12/0x20 mm/kasan/common.c:641 __asan_report_store1_noabort+0x17/0x20 mm/kasan/generic_report.c:137 decode_data.part.0+0x23b/0x270 drivers/net/hamradio/6pack.c:843 decode_data drivers/net/hamradio/6pack.c:965 [inline] sixpack_decode drivers/net/hamradio/6pack.c:968 [inline] Reported-and-tested-by: syzbot+fc8cd9a673d4577fb2e4@syzkaller.appspotmail.com Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Pavel Skripkin Reviewed-by: Dan Carpenter Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Signed-off-by: Yang Yingliang Signed-off-by: wanxiaoqing --- drivers/net/hamradio/6pack.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 8c636c493227..1001e9a2edd4 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -859,6 +859,12 @@ static void decode_data(struct sixpack *sp, unsigned char inbyte) return; } + if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) { + pr_err("6pack: cooked buffer overrun, data loss\n"); + sp->rx_count = 0; + return; + } + buf = sp->raw_buf; sp->cooked_buf[sp->rx_count_cooked++] = buf[0] | ((buf[1] << 2) & 0xc0); -- Gitee From 25f946352ce1b4810d40f25416f1a8a4a7b5977d Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Sat, 1 Jan 2022 01:21:37 +0800 Subject: [PATCH 2/5] usb: gadget: don't release an existing dev->buf commit:5478ca1538cfa348d2d6e7bb1a187de56bde8c43 CVE:CVE-2022-24958 Signed-off-by: wanxiaoqing ----------------------------------------------------------- mainline inclusion from mainline-v5.17-rc1 commit 89f3594d0de58e8a57d92d497dea9fee3d4b9cda category: bugfix issue: #I4U9Y8 CVE: CVE-2022-24958 Signed-off-by: Yu Changchun ------------------------------------------------- dev->buf does not need to be released if it already exists before executing dev_config. Acked-by: Alan Stern Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20211231172138.7993-2-hbh25y@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Yu Changchun Signed-off-by: wanxiaoqing --- drivers/usb/gadget/legacy/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 25d417ad9000..18ba56120d18 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1814,8 +1814,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) spin_lock_irq (&dev->lock); value = -EINVAL; if (dev->buf) { + spin_unlock_irq(&dev->lock); kfree(kbuf); - goto fail; + return value; } dev->buf = kbuf; -- Gitee From 4b637bd9e6d505dd412df65f9cf105704a952431 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Sat, 1 Jan 2022 01:21:38 +0800 Subject: [PATCH 3/5] usb: gadget: clear related members when goto fail commit:4bd60afa9e708934b85d98478532761f43ec650b CVE:CVE-2022-24958 Signed-off-by: wanxiaoqing ----------------------------------------------------------- mainline inclusion from mainline-v5.17-rc1 commit 501e38a5531efbd77d5c73c0ba838a889bfc1d74 category: bugfix issue: #I4U9Y8 CVE: CVE-2022-24958 Signed-off-by: Yu Changchun ------------------------------------------------- dev->config and dev->hs_config and dev->dev need to be cleaned if dev_config fails to avoid UAF. Acked-by: Alan Stern Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20211231172138.7993-3-hbh25y@gmail.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Yu Changchun Signed-off-by: wanxiaoqing --- drivers/usb/gadget/legacy/inode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 18ba56120d18..31ac2e8fd4c3 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1863,8 +1863,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) value = usb_gadget_probe_driver(&gadgetfs_driver); if (value != 0) { - kfree (dev->buf); - dev->buf = NULL; + spin_lock_irq(&dev->lock); + goto fail; } else { /* at this point "good" hardware has for the first time * let the USB the host see us. alternatively, if users @@ -1881,6 +1881,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return value; fail: + dev->config = NULL; + dev->hs_config = NULL; + dev->dev = NULL; spin_unlock_irq (&dev->lock); pr_debug ("%s: %s fail %zd, %p\n", shortname, __func__, value, dev); kfree (dev->buf); -- Gitee From 9b918c885baaf6b73b28ed0514c5ca138070e182 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Tue, 19 Apr 2022 17:06:29 +0800 Subject: [PATCH 4/5] xen/grant-table: add gnttab_try_end_foreign_access() commit:399559c29cf4281d578c7a9393c3d634e84e7806 CVE:CVE-2022-23036 Signed-off-by: wanxiaoqing ----------------------------------------------------------- commit f6f6cd53db934548c458910a64bfa0a12a6c84b1 Signed-off-by: Fang Minjuan -------------------------------- stable inclusion from stable-v5.10.105 commit 3d81e85f30a8f712c3e4f2a507553d9063a20ed6 bugzilla: 186480 https://gitee.com/src-openeuler/kernel/issues/I50WBV CVE: CVE-2022-23036, CVE-2022-23038 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=3d81e85f30a8f712c3e4f2a507553d9063a20ed6 -------------------------------- Commit 6b1775f26a2da2b05a6dc8ec2b5d14e9a4701a1a upstream. Add a new grant table function gnttab_try_end_foreign_access(), which will remove and free a grant if it is not in use. Its main use case is to either free a grant if it is no longer in use, or to take some other action if it is still in use. This other action can be an error exit, or (e.g. in the case of blkfront persistent grant feature) some special handling. This is CVE-2022-23036, CVE-2022-23038 / part of XSA-396. Reported-by: Demi Marie Obenour Signed-off-by: Juergen Gross Reviewed-by: Jan Beulich Signed-off-by: Greg Kroah-Hartman Signed-off-by: Chen Jun Signed-off-by: Zheng Zengkai Reviewed-by: Xiu Jianfeng Signed-off-by: Zheng Zengkai Signed-off-by: wanxiaoqing --- drivers/xen/grant-table.c | 14 ++++++++++++-- include/xen/grant_table.h | 12 ++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 97341fa75458..9524806eb4b9 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -436,11 +436,21 @@ static void gnttab_add_deferred(grant_ref_t ref, bool readonly, what, ref, page ? page_to_pfn(page) : -1); } +int gnttab_try_end_foreign_access(grant_ref_t ref) +{ + int ret = _gnttab_end_foreign_access_ref(ref, 0); + + if (ret) + put_free_entry(ref); + + return ret; +} +EXPORT_SYMBOL_GPL(gnttab_try_end_foreign_access); + void gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page) { - if (gnttab_end_foreign_access_ref(ref, readonly)) { - put_free_entry(ref); + if (gnttab_try_end_foreign_access(ref)) { if (page != 0) put_page(virt_to_page(page)); } else diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index a9978350b45b..7628ab25f686 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h @@ -97,10 +97,22 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly); * access has been ended, free the given page too. Access will be ended * immediately iff the grant entry is not in use, otherwise it will happen * some time later. page may be 0, in which case no freeing will occur. + * Note that the granted page might still be accessed (read or write) by the + * other side after gnttab_end_foreign_access() returns, so even if page was + * specified as 0 it is not allowed to just reuse the page for other + * purposes immediately. */ void gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page); +/* + * End access through the given grant reference, iff the grant entry is + * no longer in use. In case of success ending foreign access, the + * grant reference is deallocated. + * Return 1 if the grant entry was freed, 0 if it is still in use. + */ +int gnttab_try_end_foreign_access(grant_ref_t ref); + int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn); unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref); -- Gitee From 723fca45cf9cc799ab513c4d49e0d9f2349f9537 Mon Sep 17 00:00:00 2001 From: Juergen Gross Date: Tue, 19 Apr 2022 17:06:28 +0800 Subject: [PATCH 5/5] xen/xenbus: don't let xenbus_grant_ring() remove grants in error case commit:263a967d50894d7c8b6635057e48195901a4f69d CVE:CVE-2022-23036 Signed-off-by: wanxiaoqing ----------------------------------------------------------- commit b2c42e19310c983eeaa4b118b645d906f8117ef1 Signed-off-by: Fang Minjuan -------------------------------- stable inclusion from stable-v5.10.105 commit 5c600371b8fd02cbbb0eb83a9f664e3f0b75c28e bugzilla: 186480 https://gitee.com/src-openeuler/kernel/issues/I50WA6 CVE: CVE-2022-23040 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=5c600371b8fd02cbbb0eb83a9f664e3f0b75c28e -------------------------------- Commit 3777ea7bac3113005b7180e6b9dadf16d19a5827 upstream. Letting xenbus_grant_ring() tear down grants in the error case is problematic, as the other side could already have used these grants. Calling gnttab_end_foreign_access_ref() without checking success is resulting in an unclear situation for any caller of xenbus_grant_ring() as in the error case the memory pages of the ring page might be partially mapped. Freeing them would risk unwanted foreign access to them, while not freeing them would leak memory. In order to remove the need to undo any gnttab_grant_foreign_access() calls, use gnttab_alloc_grant_references() to make sure no further error can occur in the loop granting access to the ring pages. It should be noted that this way of handling removes leaking of grant entries in the error case, too. This is CVE-2022-23040 / part of XSA-396. Reported-by: Demi Marie Obenour Signed-off-by: Juergen Gross Reviewed-by: Jan Beulich Signed-off-by: Greg Kroah-Hartman Signed-off-by: Chen Jun Signed-off-by: Zheng Zengkai Reviewed-by: Xiu Jianfeng Signed-off-by: Zheng Zengkai Signed-off-by: wanxiaoqing --- drivers/xen/xenbus/xenbus_client.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index e35bb6b87449..6dde323dabd4 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -368,7 +368,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, unsigned int nr_pages, grant_ref_t *grefs) { int err; - int i, j; + unsigned int i; + grant_ref_t gref_head; + + err = gnttab_alloc_grant_references(nr_pages, &gref_head); + if (err) { + xenbus_dev_fatal(dev, err, "granting access to ring page"); + return err; + } for (i = 0; i < nr_pages; i++) { unsigned long gfn; @@ -378,23 +385,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr, else gfn = virt_to_gfn(vaddr); - err = gnttab_grant_foreign_access(dev->otherend_id, gfn, 0); - if (err < 0) { - xenbus_dev_fatal(dev, err, - "granting access to ring page"); - goto fail; - } - grefs[i] = err; + grefs[i] = gnttab_claim_grant_reference(&gref_head); + gnttab_grant_foreign_access_ref(grefs[i], dev->otherend_id, + gfn, 0); vaddr = vaddr + XEN_PAGE_SIZE; } return 0; - -fail: - for (j = 0; j < i; j++) - gnttab_end_foreign_access_ref(grefs[j], 0); - return err; } EXPORT_SYMBOL_GPL(xenbus_grant_ring); -- Gitee