From 0f8e76c76951f2ac265fb06a30d043b1824e80b1 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 17 Feb 2026 13:03:32 -0500 Subject: [PATCH 1/6] eventpoll: don't decrement ep refcount while still holding the ep mutex jira VULN-162877 cve CVE-2025-38349 commit-author Linus Torvalds commit 8c2e52ebbe885c7eeaabd3b7ddcdc1246fc400d2 Jann Horn points out that epoll is decrementing the ep refcount and then doing a mutex_unlock(&ep->mtx); afterwards. That's very wrong, because it can lead to a use-after-free. That pattern is actually fine for the very last reference, because the code in question will delay the actual call to "ep_free(ep)" until after it has unlocked the mutex. But it's wrong for the much subtler "next to last" case when somebody *else* may also be dropping their reference and free the ep while we're still using the mutex. Note that this is true even if that other user is also using the same ep mutex: mutexes, unlike spinlocks, can not be used for object ownership, even if they guarantee mutual exclusion. A mutex "unlock" operation is not atomic, and as one user is still accessing the mutex as part of unlocking it, another user can come in and get the now released mutex and free the data structure while the first user is still cleaning up. See our mutex documentation in Documentation/locking/mutex-design.rst, in particular the section [1] about semantics: "mutex_unlock() may access the mutex structure even after it has internally released the lock already - so it's not safe for another context to acquire the mutex and assume that the mutex_unlock() context is not using the structure anymore" So if we drop our ep ref before the mutex unlock, but we weren't the last one, we may then unlock the mutex, another user comes in, drops _their_ reference and releases the 'ep' as it now has no users - all while the mutex_unlock() is still accessing it. Fix this by simply moving the ep refcount dropping to outside the mutex: the refcount itself is atomic, and doesn't need mutex protection (that's the whole _point_ of refcounts: unlike mutexes, they are inherently about object lifetimes). Reported-by: Jann Horn Link: https://docs.kernel.org/locking/mutex-design.html#semantics [1] Cc: Alexander Viro Cc: Christian Brauner Cc: Jan Kara Signed-off-by: Linus Torvalds (cherry picked from commit 8c2e52ebbe885c7eeaabd3b7ddcdc1246fc400d2) Signed-off-by: Jonathan Maple --- fs/eventpoll.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index f354667e22186..14e7663f5053f 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -772,7 +772,7 @@ static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force) call_rcu(&epi->rcu, epi_rcu_free); percpu_counter_dec(&ep->user->epoll_watches); - return ep_refcount_dec_and_test(ep); + return true; } /* @@ -780,14 +780,14 @@ static bool __ep_remove(struct eventpoll *ep, struct epitem *epi, bool force) */ static void ep_remove_safe(struct eventpoll *ep, struct epitem *epi) { - WARN_ON_ONCE(__ep_remove(ep, epi, false)); + if (__ep_remove(ep, epi, false)) + WARN_ON_ONCE(ep_refcount_dec_and_test(ep)); } static void ep_clear_and_put(struct eventpoll *ep) { struct rb_node *rbp, *next; struct epitem *epi; - bool dispose; /* We need to release all tasks waiting for these file */ if (waitqueue_active(&ep->poll_wait)) @@ -820,10 +820,8 @@ static void ep_clear_and_put(struct eventpoll *ep) cond_resched(); } - dispose = ep_refcount_dec_and_test(ep); mutex_unlock(&ep->mtx); - - if (dispose) + if (ep_refcount_dec_and_test(ep)) ep_free(ep); } @@ -1003,7 +1001,7 @@ void eventpoll_release_file(struct file *file) dispose = __ep_remove(ep, epi, true); mutex_unlock(&ep->mtx); - if (dispose) + if (dispose && ep_refcount_dec_and_test(ep)) ep_free(ep); goto again; } From cc17a83e55d6c34e01d8008331efe775a54c846e Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 17 Feb 2026 13:04:04 -0500 Subject: [PATCH 2/6] usb: core: config: Prevent OOB read in SS endpoint companion parsing jira VULN-163655 cve CVE-2025-39760 commit-author Xinyu Liu commit cf16f408364efd8a68f39011a3b073c83a03612d usb_parse_ss_endpoint_companion() checks descriptor type before length, enabling a potentially odd read outside of the buffer size. Fix this up by checking the size first before looking at any of the fields in the descriptor. Signed-off-by: Xinyu Liu Cc: stable Signed-off-by: Greg Kroah-Hartman (cherry picked from commit cf16f408364efd8a68f39011a3b073c83a03612d) Signed-off-by: Jonathan Maple --- drivers/usb/core/config.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 880d52c0949d4..9565d14d7c071 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -81,8 +81,14 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, */ desc = (struct usb_ss_ep_comp_descriptor *) buffer; - if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP || - size < USB_DT_SS_EP_COMP_SIZE) { + if (size < USB_DT_SS_EP_COMP_SIZE) { + dev_notice(ddev, + "invalid SuperSpeed endpoint companion descriptor " + "of length %d, skipping\n", size); + return; + } + + if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) { dev_notice(ddev, "No SuperSpeed endpoint companion for config %d " " interface %d altsetting %d ep %d: " "using minimum values\n", From 162477672580a2a94655c383524f5e852ead93dd Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 17 Feb 2026 13:04:19 -0500 Subject: [PATCH 3/6] ALSA: usb-audio: Fix potential overflow of PCM transfer buffer jira VULN-161129 cve CVE-2025-40269 commit-author Takashi Iwai commit 05a1fc5efdd8560f34a3af39c9cf1e1526cc3ddf The PCM stream data in USB-audio driver is transferred over USB URB packet buffers, and each packet size is determined dynamically. The packet sizes are limited by some factors such as wMaxPacketSize USB descriptor. OTOH, in the current code, the actually used packet sizes are determined only by the rate and the PPS, which may be bigger than the size limit above. This results in a buffer overflow, as reported by syzbot. Basically when the limit is smaller than the calculated packet size, it implies that something is wrong, most likely a weird USB descriptor. So the best option would be just to return an error at the parameter setup time before doing any further operations. This patch introduces such a sanity check, and returns -EINVAL when the packet size is greater than maxpacksize. The comparison with ep->packsize[1] alone should suffice since it's always equal or greater than ep->packsize[0]. Reported-by: syzbot+bfd77469c8966de076f7@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=bfd77469c8966de076f7 Link: https://lore.kernel.org/690b6b46.050a0220.3d0d33.0054.GAE@google.com Cc: Lizhi Xu Cc: Link: https://patch.msgid.link/20251109091211.12739-1-tiwai@suse.de Signed-off-by: Takashi Iwai (cherry picked from commit 05a1fc5efdd8560f34a3af39c9cf1e1526cc3ddf) Signed-off-by: Jonathan Maple --- sound/usb/endpoint.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 2e180be848e6a..d776f29bf012f 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -1393,6 +1393,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, ep->sample_rem = ep->cur_rate % ep->pps; ep->packsize[0] = ep->cur_rate / ep->pps; ep->packsize[1] = (ep->cur_rate + (ep->pps - 1)) / ep->pps; + if (ep->packsize[1] > ep->maxpacksize) { + usb_audio_dbg(chip, "Too small maxpacksize %u for rate %u / pps %u\n", + ep->maxpacksize, ep->cur_rate, ep->pps); + return -EINVAL; + } /* calculate the frequency in 16.16 format */ ep->freqm = ep->freqn; From d1d61a7f5658d5ca2e82e5d2091231b20008e231 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 17 Feb 2026 13:04:23 -0500 Subject: [PATCH 4/6] fs/proc: fix uaf in proc_readdir_de() jira VULN-169407 cve CVE-2025-40271 commit-author Wei Yang commit 895b4c0c79b092d732544011c3cecaf7322c36a1 Pde is erased from subdir rbtree through rb_erase(), but not set the node to EMPTY, which may result in uaf access. We should use RB_CLEAR_NODE() set the erased node to EMPTY, then pde_subdir_next() will return NULL to avoid uaf access. We found an uaf issue while using stress-ng testing, need to run testcase getdent and tun in the same time. The steps of the issue is as follows: 1) use getdent to traverse dir /proc/pid/net/dev_snmp6/, and current pde is tun3; 2) in the [time windows] unregister netdevice tun3 and tun2, and erase them from rbtree. erase tun3 first, and then erase tun2. the pde(tun2) will be released to slab; 3) continue to getdent process, then pde_subdir_next() will return pde(tun2) which is released, it will case uaf access. CPU 0 | CPU 1 ------------------------------------------------------------------------- traverse dir /proc/pid/net/dev_snmp6/ | unregister_netdevice(tun->dev) //tun3 tun2 sys_getdents64() | iterate_dir() | proc_readdir() | proc_readdir_de() | snmp6_unregister_dev() pde_get(de); | proc_remove() read_unlock(&proc_subdir_lock); | remove_proc_subtree() | write_lock(&proc_subdir_lock); [time window] | rb_erase(&root->subdir_node, &parent->subdir); | write_unlock(&proc_subdir_lock); read_lock(&proc_subdir_lock); | next = pde_subdir_next(de); | pde_put(de); | de = next; //UAF | rbtree of dev_snmp6 | pde(tun3) / \ NULL pde(tun2) Link: https://lkml.kernel.org/r/20251025024233.158363-1-albin_yang@163.com Signed-off-by: Wei Yang Cc: Al Viro Cc: Christian Brauner Cc: wangzijie Cc: Alexey Dobriyan Cc: Signed-off-by: Andrew Morton (cherry picked from commit 895b4c0c79b092d732544011c3cecaf7322c36a1) Signed-off-by: Jonathan Maple --- fs/proc/generic.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 1edf53be9bdb5..24ceced87cfe8 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -688,6 +688,12 @@ void pde_put(struct proc_dir_entry *pde) } } +static void pde_erase(struct proc_dir_entry *pde, struct proc_dir_entry *parent) +{ + rb_erase(&pde->subdir_node, &parent->subdir); + RB_CLEAR_NODE(&pde->subdir_node); +} + /* * Remove a /proc entry and free it if it's not currently in use. */ @@ -710,7 +716,7 @@ void remove_proc_entry(const char *name, struct proc_dir_entry *parent) WARN(1, "removing permanent /proc entry '%s'", de->name); de = NULL; } else { - rb_erase(&de->subdir_node, &parent->subdir); + pde_erase(de, parent); if (S_ISDIR(de->mode)) parent->nlink--; } @@ -754,7 +760,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) root->parent->name, root->name); return -EINVAL; } - rb_erase(&root->subdir_node, &parent->subdir); + pde_erase(root, parent); de = root; while (1) { @@ -766,7 +772,7 @@ int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) next->parent->name, next->name); return -EINVAL; } - rb_erase(&next->subdir_node, &de->subdir); + pde_erase(next, de); de = next; continue; } From 0a4724c2a5ceae1469415931a8cfe60935b4de77 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Tue, 17 Feb 2026 13:04:28 -0500 Subject: [PATCH 5/6] fbdev: Add bounds checking in bit_putcs to fix vmalloc-out-of-bounds jira VULN-161235 cve CVE-2025-40304 commit-author Albin Babu Varghese commit 3637d34b35b287ab830e66048841ace404382b67 Add bounds checking to prevent writes past framebuffer boundaries when rendering text near screen edges. Return early if the Y position is off-screen and clip image height to screen boundary. Break from the rendering loop if the X position is off-screen. When clipping image width to fit the screen, update the character count to match the clipped width to prevent buffer size mismatches. Without the character count update, bit_putcs_aligned and bit_putcs_unaligned receive mismatched parameters where the buffer is allocated for the clipped width but cnt reflects the original larger count, causing out-of-bounds writes. Reported-by: syzbot+48b0652a95834717f190@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=48b0652a95834717f190 Suggested-by: Helge Deller Tested-by: syzbot+48b0652a95834717f190@syzkaller.appspotmail.com Signed-off-by: Albin Babu Varghese Signed-off-by: Helge Deller (cherry picked from commit 3637d34b35b287ab830e66048841ace404382b67) Signed-off-by: Jonathan Maple --- drivers/video/fbdev/core/bitblit.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index 19b8a78e11434..525c1b4c60fc2 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -169,6 +169,11 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, image.height = vc->vc_font.height; image.depth = 1; + if (image.dy >= info->var.yres) + return; + + image.height = min(image.height, info->var.yres - image.dy); + if (attribute) { buf = kmalloc(cellsize, GFP_ATOMIC); if (!buf) @@ -182,6 +187,18 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info, cnt = count; image.width = vc->vc_font.width * cnt; + + if (image.dx >= info->var.xres) + break; + + if (image.dx + image.width > info->var.xres) { + image.width = info->var.xres - image.dx; + cnt = image.width / vc->vc_font.width; + if (cnt == 0) + break; + image.width = cnt * vc->vc_font.width; + } + pitch = DIV_ROUND_UP(image.width, 8) + scan_align; pitch &= ~scan_align; size = pitch * image.height + buf_align; From 76272c6a742c27999ec326e3b1065a5f42df322a Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Wed, 18 Feb 2026 18:07:13 -0500 Subject: [PATCH 6/6] github actions: add mutltiarch support --- ...nd-test-x86_64.yml => kernel-build-and-test-multiarch.yml} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename .github/workflows/{kernel-build-and-test-x86_64.yml => kernel-build-and-test-multiarch.yml} (63%) diff --git a/.github/workflows/kernel-build-and-test-x86_64.yml b/.github/workflows/kernel-build-and-test-multiarch.yml similarity index 63% rename from .github/workflows/kernel-build-and-test-x86_64.yml rename to .github/workflows/kernel-build-and-test-multiarch.yml index d53833992bae5..7726a4ec698eb 100644 --- a/.github/workflows/kernel-build-and-test-x86_64.yml +++ b/.github/workflows/kernel-build-and-test-multiarch.yml @@ -1,4 +1,4 @@ -name: Automated kernel build and test (x86_64) +name: Automated kernel build and test x86_64 and aarch64 on: push: @@ -7,5 +7,5 @@ on: jobs: build: - uses: ctrliq/kernel-src-tree/.github/workflows/kernel-build-and-test-x86_64.yml@main + uses: ctrliq/kernel-src-tree/.github/workflows/kernel-build-and-test-multiarch.yml@main secrets: inherit