OESA-2026-3303

Source
https://www.openeuler.org/en/security/security-bulletins/detail/?id=openEuler-SA-2026-3303
Import Source
https://repo.openeuler.org/security/data/osv/OESA-2026-3303.json
JSON Data
https://api.test.osv.dev/v1/vulns/OESA-2026-3303
Upstream
  • CVE-2026-63827
  • CVE-2026-64378
Published
2026-08-07T02:45:24Z
Modified
2026-08-07T03:00:11Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
Summary
kernel security update
Details

The Linux Kernel, the operating system core itself.

Security Fix(es):

In the Linux kernel, the following vulnerability has been resolved:

comedi: me4000: Fix potential overrun of firmware buffer

me4000_xilinx_download() loads the firmware that was requested by request_firmware(). It is possible for it to overrun the source buffer because it blindly trusts the file format. It reads a data stream length from the first 4 bytes into variable file_length and reads the data stream contents of length file_length from offset 16 onwards.

Add a test to ensure that the supplied firmware is long enough to contain the header and the data stream. On failure, log an error and return -EINVAL.

Note: The firmware loading was totally broken before commit ac584af59945 ("staging: comedi: me4000: fix firmware downloading"), but that is the most sensible target for this fix.(CVE-2026-31747)

In the Linux kernel, the following vulnerability has been resolved:

ASoC: soc-core: flush delayed work before removing DAIs and widgets

When a sound card is unbound while a PCM stream is open, a use-after-free can occur in snd_soc_dapm_stream_event(), called from the close_delayed_work workqueue handler.

During unbind, snd_soc_unbind_card() flushes delayed work and then calls soc_cleanup_card_resources(). Inside cleanup, snd_card_disconnect_sync() releases all PCM file descriptors, and the resulting PCM close path can call snd_soc_dapm_stream_stop() which schedules new delayed work with a pmdown_time timer delay. Since this happens after the flush in snd_soc_unbind_card(), the new work is not caught. soc_remove_link_components() then frees DAPM widgets before this work fires, leading to the use-after-free.

The existing flush in soc_free_pcm_runtime() also cannot help as it runs after soc_remove_link_components() has already freed the widgets.

Add a flush in soc_cleanup_card_resources() after snd_card_disconnect_sync() (after which no new PCM closes can schedule further delayed work) and before soc_remove_link_dais() and soc_remove_link_components() (which tear down the structures the delayed work accesses).(CVE-2026-43459)

In the Linux kernel, the following vulnerability has been resolved:

fbdev: udlfb: add vm_ops to dlfb_ops_mmap to prevent use-after-free

dlfb_ops_mmap() uses remap_pfn_range() to map vmalloc framebuffer pages to userspace but sets no vm_ops on the VMA. This means the kernel cannot track active mmaps. When dlfb_realloc_framebuffer() replaces the backing buffer via FBIOPUT_VSCREENINFO, existing mmap PTEs are not invalidated. On USB disconnect, dlfb_ops_destroy() calls vfree() on the old pages while userspace PTEs still reference them, resulting in a use-after-free: the process retains read/write access to freed kernel pages.

Add vm_operations_struct with open/close callbacks that maintain an atomic mmap_count on struct dlfb_data. In dlfb_realloc_framebuffer(), check mmap_count and return -EBUSY if the buffer is currently mapped, preventing buffer replacement while userspace holds stale PTEs.

Tested with PoC using dummy_hcd + raw_gadget USB device emulation.(CVE-2026-43497)

In the Linux kernel, the following vulnerability has been resolved:

RDMA/umem: Fix truncation for block sizes >= 4G

When the iommu is used the linearization of the mapping can give a single block that is very large split across multiple SG entries.

When __rdma_block_iter_next() reassembles the split SG entries it is overflowing the 32 bit stack values and computed the wrong DMA addresses for blocks after the truncation.

Use the right types to hold DMA addresses.(CVE-2026-53133)

In the Linux kernel, the following vulnerability has been resolved:

l2tp: pppol2tp: hold reference to session in pppol2tp_ioctl()

pppol2tp_ioctl() read sock->sk->sk_user_data directly without any locks or reference counting. If a controllable sleep was induced during copy_from_user() (e.g. via a userfaultfd page fault sleep), a concurrent socket close could trigger pppol2tp_session_close() asynchronously. This frees the l2tp_session structure via the l2tp_session_del_work workqueue. Upon resuming, the ioctl thread dereferences the stale session pointer, resulting in a Use-After-Free (UAF).

Fix this by securely fetching the session reference using the RCU-safe, refcounted helper pppol2tp_sock_to_session(sk) on entry. This locks the session's refcount across the sleep. We structured the function to exit via standard err breaks, guaranteeing that l2tp_session_put() is cleanly called on all return paths to drop the reference.

To preserve existing behavior we validate the session and its magic signature only for the specific L2TP commands that require it. This ensures that generic/unknown ioctls called on an unconnected socket still return -ENOIOCTLCMD and correctly fall back to generic handlers (e.g. in sock_do_ioctl()).(CVE-2026-53262)

In the Linux kernel, the following vulnerability has been resolved:

fuse: re-lock request before replacing page cache folio

fuse_try_move_folio() unlocks the request on entry but does not re-lock it on the success path. This means fuse_chan_abort() can end the request and free the fuse_io_args (eg fuse_readpages_end()) while the subsequent copy chain logic after fuse_try_move_folio() accesses the fuse_io_args, leading to use-after-free issues.

Fix this by calling lock_request() before replace_page_cache_folio(). This ensures the request is locked on the success path which will prevent the fuse_io_args from being freed while the later copying logic runs, and also ensures that the ap->folios[i]->mapping is never null since ap->folios[i] will always point to the newfolio after replace_page_cache_folio().(CVE-2026-53388)

In the Linux kernel, the following vulnerability has been resolved:

i2c: core: fix adapter registration race

Adapters can be looked up based on their id using i2c_get_adapter() which takes a reference to the embedded struct device.

Make sure that the adapter (including its struct device) has been initialised before adding it to the IDR to avoid accessing uninitialised data which could, for example, lead to NULL-pointer dereferences or use-after-free.

Note that the i2c-dev chardev, which is registered from a bus notifier, currently uses i2c_get_adapter() so the adapter needs to be added to the IDR before registration.(CVE-2026-53400)

In the Linux kernel, the following vulnerability has been resolved:

gcov: use atomic counter updates to fix concurrent access crashes

GCC's GCOV instrumentation can merge global branch counters with loop induction variables as an optimization. In inflate_fast(), the inner copy loops get transformed so that the GCOV counter value is loaded multiple times to compute the loop base address, start index, and end bound. Since GCOV counters are global (not per-CPU), concurrent execution on different CPUs causes the counter to change between loads, producing inconsistent values and out-of-bounds memory writes.

The crash manifests during IPComp (IP Payload Compression) processing when inflate_fast() runs concurrently on multiple CPUs:

BUG: unable to handle page fault for address: ffffd0a3c0902ffa RIP: inflate_fast+1431 Call Trace: zlib_inflate __deflate_decompress crypto_comp_decompress ipcomp_decompress [xfrm_ipcomp] ipcomp_input [xfrm_ipcomp] xfrm_input

At the crash point, the compiler generated three loads from the same global GCOV counter (__gcov0.inflate_fast+216) to compute base, start, and end for an indexed loop. Another CPU modified the counter between loads, making the values inconsistent - the write went 3.4 MB past a 65 KB buffer.

Add -fprofile-update=prefer-atomic to CFLAGS_GCOV at the global level in the top-level Makefile, guarded by a try-run compile test. The test compiles a minimal program with and without -fprofile-update=prefer-atomic using the full KBUILD_CFLAGS, then compares undefined symbols in the resulting object files. If prefer-atomic introduces new undefined references (such as __atomic_fetch_add_8 on i386 or __aarch64_ldadd8_relax on arm64 with outline-atomics), the flag is not added -- the kernel does not link against libatomic.

On architectures where GCC inlines 64-bit atomic counter updates (x86_64, s390, ...) the test passes and the flag is enabled, preventing the compiler from merging counters with loop induction variables and fixing the observed concurrent-access crash.

On architectures where the flag would introduce libatomic dependencies, it is silently omitted and behaviour is no worse than before this patch.

Move the CFLAGS_GCOV block from its original position (before the arch Makefile include) to after the core KBUILD_CFLAGS assignments but before the scripts/Makefile.gcc-plugins include. This placement ensures the try-run test sees arch-specific flags (-m32, -march=, -mno-outline-atomics) while avoiding GCC plugin flags (-fplugin=) that would break the test on clean builds when plugin shared objects do not yet exist.(CVE-2026-63825)

In the Linux kernel, the following vulnerability has been resolved:

apparmor: fix use-after-free in rawdata dedup loop

aa_replace_profiles() walks ns->rawdata_list to dedup the incoming policy blob against entries already attached to existing profiles. Per the kernel-doc on struct aa_loaddata, list membership does not hold a reference: profiles hold pcount, and when the last pcount drops, do_ploaddata_rmfs() is queued on a workqueue that takes ns->lock and removes the entry. Between dropping the last pcount and the workqueue running, an entry remains on the list with pcount == 0.

aa_get_profile_loaddata() is an unconditional kref_get() on pcount, so when the dedup loop hits such an entry, refcount hardening reports

refcount_t: addition on 0; use-after-free.

inside aa_replace_profiles(), and the poisoned counter then trips "saturated" and "underflow" warnings on the subsequent uses of the same loaddata.

Before commit a0b7091c4de4 ("apparmor: fix race on rawdata dereference") the dedup path used a get_unless_zero-style helper on a single counter, so the existing "if (tmp)" guard was meaningful. The split-refcount refactor introduced aa_get_profile_loaddata(), which has plain kref_get() semantics, and the guard quietly became a no-op.

Introduce aa_get_profile_loaddata_not0(), matching the existing _not0 convention used by aa_get_profile_not0(), and use it for the rawdata_list dedup lookup so dying entries are skipped.

Reproduced on x86_64 with v7.1-rc5 in QEMU+KVM running Ubuntu 24.04 + stress-ng 0.17.06:

stress-ng --apparmor 1 --klog-check --timeout 60s

Without this patch the three refcount_t warnings fire within a few seconds. With it the same 60 s run is clean. Coverage is a smoke-test only; a longer soak with CONFIG_KASAN, CONFIG_KCSAN and CONFIG_PROVE_LOCKING would be welcome from anyone with the cycles.(CVE-2026-63827)

In the Linux kernel, the following vulnerability has been resolved:

scsi: target: iscsi: Bound iscsi_encode_text_output() appends to rsp_buf

iscsi_encode_text_output() concatenates "key=value\0" records into login->rsp_buf, an 8192-byte kzalloc(MAX_KEY_VALUE_PAIRS) buffer allocated in iscsit_alloc_login_setup_buffer(). The three sprintf() call sites in this function (lines 1398, 1411, 1424 in v7.1-rc2) never check the remaining buffer capacity:

*length += sprintf(output_buf, "%s=%s", er->key, er->value);
*length += 1;
output_buf = textbuf + *length;

The 8192-byte ceiling at iscsi_target_check_login_request() bounds the input Login PDU payload, but a single PDU can carry up to 2048 minimal four-byte "a=b\0" pairs, each unknown key expanding to a 16-byte "a=NotUnderstood\0" output record via iscsi_add_notunderstood_response(). 2048 * 16 = 32 KiB of output into an 8 KiB buffer, producing a ~24 KiB heap overrun in the kmalloc-8k slab.

The fix introduces a static iscsi_encode_text_record() helper that uses snprintf() with a per-call bounds check against the remaining buffer, and threads a u32 textbuf_size parameter through iscsi_encode_text_output(). Both call sites in iscsi_target_handle_csg_zero() (PHASE_SECURITY) and iscsi_target_handle_csg_one() (PHASE_OPERATIONAL) pass MAX_KEY_VALUE_PAIRS. On overflow the encoder logs the condition, calls iscsi_release_extra_responses() to drop queued records, and returns -1; both caller sites now emit ISCSI_STATUS_CLS_INITIATOR_ERR / ISCSI_LOGIN_STATUS_INIT_ERR via iscsit_tx_login_rsp() before returning, so the initiator sees an explicit failed-login response rather than a silent connection drop. (Prior to this patch only the PHASE_OPERATIONAL caller did that; the PHASE_SECURITY caller is converted to the same shape.)(CVE-2026-63887)

In the Linux kernel, the following vulnerability has been resolved:

scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd()

Two latent bugs in the Text-phase handler, both present since the original LIO integration in commit e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1"):

  1. DataDigest CRC buffer overread (4 bytes past text_in).

    text_in is kzalloc()'d at ALIGN(payload_length, 4). rx_size is then incremented by ISCSI_CRC_LEN to make room for the received DataDigest in the iovec, but the same (now-bumped) rx_size is passed as the buffer length to iscsit_crc_buf():

    if (conn->conn_ops->DataDigest) {
            ...
            rx_size += ISCSI_CRC_LEN;
    }
    ...
    if (conn->conn_ops->DataDigest) {
            data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);
    

    iscsit_crc_buf() walks rx_size bytes of text_in with crc32c(), so when DataDigest is negotiated it reads 4 bytes past the end of the text_in allocation. KASAN reproduces this directly on the unpatched mainline tree as slab-out-of-bounds in crc32c() called from the Text PDU path. The OOB bytes feed crc32c() and are then compared against the initiator-supplied checksum, so the value does not flow back to the attacker, but the kernel does read past the buffer on every Text PDU with DataDigest=CRC32C.

    Fix by passing the actual padded payload length (ALIGN(payload_length, 4)) that was used for the kzalloc().

  2. Stale cmd->text_in_ptr re-free (double-free) on ERL>0 bad DataDigest drop.

    On DataDigest mismatch with ErrorRecoveryLevel > 0 the handler silently drops the PDU and lets the initiator plug the CmdSN gap:

            kfree(text_in);
            return 0;
    

    cmd->text_in_ptr still points at the freed buffer. The next Text Request on the same ITT re-enters iscsit_setup_text_cmd(), which unconditionally does

    kfree(cmd->text_in_ptr);
    cmd->text_in_ptr = NULL;
    

    freeing the same pointer a second time. Session teardown via iscsit_release_cmd() has the same shape and hits the same double-free if the connection is dropped before a second Text Request arrives.

    On an unmodified mainline tree the bug-1 CRC overread fires first on the initial valid Text Request and perturbs the subsequent state, so #4 was isolated by building a kernel with only the bug-1 hunk of this patch applied plus temporary printk() observability around the three relevant kfree() sites. The observability prints are not part of this patch. On that build, a three-PDU Text Request sequence after login produces two back-to-back splats:

    BUG: KASAN: double-free in iscsit_setup_text_cmd+0x??
    BUG: KASAN: double-free in iscsit_release_cmd+0x??
    

    showing the same pointer freed in the ERL>0 drop path and again in iscsit_setup_text_cmd() (next Text Request on the same ITT) and once more in iscsit_release_cmd() (session teardown). On distro kernels with CONFIG_SLAB_FREELIST_HARDENED=y (default) the double-free becomes a remote kernel BUG(); on non-hardened kernels it corrupts the slab freelist.

    Fix by clearing cmd->text_in_ptr after the kfree() in the ERL>0 drop path. With both hunks applied #4 is directly observable on the stock tree without observability printks; fixing bug-1 alone would mask #4 less, not more, so the hunks are submitted together.

Both fixes are one-liners. The Text PDU state machine is unchanged and the wire protocol is unaffected.(CVE-2026-63888)

In the Linux kernel, the following vulnerability has been resolved:

USB: serial: cypress_m8: fix memory corruption with small endpoint

Make sure that the interrupt-out endpoint max packet size is at least eight bytes to avoid user-controlled slab corruption or NULL-pointer dereference should a malicious device report a smaller size.(CVE-2026-63956)

In the Linux kernel, the following vulnerability has been resolved:

Bluetooth: L2CAP: Fix possible crash on l2cap_ecred_conn_rsp

If dcid is received for an already-assigned destination CID the spec requires that both channels to be discarded, but calling l2cap_chan_del may invalidate the tmp cursor created by list_for_each_entry_safe and in fact it is the wrong procedure as the chan->dcid may be assigned previously it really needs to be disconnected.

Calling l2cap_chan_clone directly may still lead to l2cap_chan_del so instead schedule l2cap_chan_timeout with delay 0 to close the channel asynchronously.(CVE-2026-63975)

In the Linux kernel, the following vulnerability has been resolved:

qed: fix double free in qed_cxt_tables_alloc()

If one of the later PF or VF CID bitmap allocations fails, qed_cid_map_alloc() jumps to cid_map_fail and frees the previously allocated CID bitmaps before returning an error. qed_cxt_tables_alloc() then calls qed_cxt_mngr_free(), which invokes qed_cid_map_free() again.

Fix this by setting each CID bitmap pointer to NULL after bitmap_free() to avoid double free.

The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc3.

Runtime reproduction was not attempted because exercising the failing allocation path requires device-specific setup.(CVE-2026-64118)

In the Linux kernel, the following vulnerability has been resolved:

spi: qup: fix error pointer deref after DMA setup failure

The driver falls back to PIO mode if DMA setup fails during probe.

Make sure to the clear the DMA channel pointers on setup failure to avoid dereferencing an error pointer (or attempting to release a channel a second time) on later probe errors or driver unbind.

This issue was flagged by Sashiko when reviewing a devres allocation conversion patch.(CVE-2026-64170)

In the Linux kernel, the following vulnerability has been resolved:

i2c: stub: Reject I2C block transfers with invalid length

The I2C_SMBUS_I2C_BLOCK_DATA case in stub_xfer() uses data->block[0] as the transfer length. The existing check only clamps it to avoid overrunning the chip->words[256] register array, but does not validate it against I2C_SMBUS_BLOCK_MAX (32), which is the limit of the union i2c_smbus_data.block buffer (34 bytes total). The driver is a development/test tool (CONFIG_I2C_STUB=m, not built by default) that must be loaded with a chip_addr= parameter.

A local user with access to /dev/i2c-* can issue an I2C_SMBUS ioctl with I2C_SMBUS_I2C_BLOCK_DATA and data->block[0] > 32, causing stub_xfer() to read or write past the end of the union i2c_smbus_data.block buffer:

BUG: KASAN: stack-out-of-bounds in stub_xfer (drivers/i2c/i2c-stub.c:223) Read of size 1 at addr ffff88800abcfd92 by task exploit/81 Call Trace: <TASK> stub_xfer (drivers/i2c/i2c-stub.c:223) __i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:593) i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:536) i2cdev_ioctl_smbus (drivers/i2c/i2c-dev.c:391) i2cdev_ioctl (drivers/i2c/i2c-dev.c:478) __x64_sys_ioctl (fs/ioctl.c:583) do_syscall_64 (arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) </TASK>

The bug exists because i2c-stub implements .smbus_xfer directly, bypassing the I2C_SMBUS_BLOCK_MAX validation in i2c_smbus_xfer_emulated(). The I2C_SMBUS_BLOCK_DATA case in the same function correctly validates against I2C_SMBUS_BLOCK_MAX, but the I2C_SMBUS_I2C_BLOCK_DATA case does not.

Fix by rejecting transfers with data->block[0] == 0 or data->block[0] > I2C_SMBUS_BLOCK_MAX with -EINVAL, consistent with both the I2C_SMBUS_BLOCK_DATA case in the same function and the I2C_SMBUS_I2C_BLOCK_DATA validation in i2c_smbus_xfer_emulated().(CVE-2026-64191)

In the Linux kernel, the following vulnerability has been resolved:

bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized

When CONFIG_BPF_LSM=y is set, BPF inode storage maps (BPF_MAP_TYPE_INODE_STORAGE) are compiled into the kernel. However, if the BPF LSM is not explicitly enabled at boot time (e.g. omitted from the "lsm=" boot parameter), lsm_prepare() is never executed for the BPF LSM.

Consequently, the BPF inode security blob offset (bpf_lsm_blob_sizes.lbs_inode) is never initialized and remains at its default compiled size of 8 bytes instead of being updated to a valid offset past the reserved struct rcu_head (typically 16 bytes or more).

When a privileged user creates and updates a BPF_MAP_TYPE_INODE_STORAGE map, bpf_inode() evaluates inode->i_security + 8. This erroneously aliases the struct rcu_head.func callback pointer at the beginning of the inode->i_security blob. During subsequent map element cleanup or inode destruction, writing NULL to owner_storage clears the queued RCU callback pointer. When rcu_do_batch() later executes the queued callback, it attempts an instruction fetch at address 0x0, triggering an immediate kernel panic.

Fix this by introducing a global bpf_lsm_initialized boolean flag marked with __ro_after_init. Set this flag to true inside bpf_lsm_init() when the LSM framework successfully registers the BPF LSM. Gate map allocation in inode_storage_map_alloc() on this flag, returning -EOPNOTSUPP if the BPF LSM is in turn uninitialized.

This fail-fast approach prevents userspace from allocating inode storage maps when the supporting BPF LSM infrastructure is absent, avoiding zombie map states.(CVE-2026-64192)

In the Linux kernel, the following vulnerability has been resolved:

tracing: Prevent out-of-bounds read in glob matching

String event fields are not necessarily NUL-terminated, so the filter predicate functions (filter_pred_string(), filter_pred_strloc() and filter_pred_strrelloc()) pass the field length to the regex match callbacks, and the length-aware matchers honour it.

regex_match_glob() was the exception: it ignored the length and called glob_match(), which scans the string until it hits a NUL byte. Some string fields are not NUL-terminated. One example is the dynamic char array of the xfs_* namespace tracepoints, which is copied without a trailing NUL. For such a field, glob matching reads past the end of the event field, causing a KASAN slab-out-of-bounds read in glob_match(), reached via regex_match_glob() and filter_match_preds() from the xfs_lookup tracepoint.

Add a length-bounded glob_match_len() and use it from regex_match_glob() so glob matching always stops at the field boundary. The matching loop is factored into a shared helper so glob_match() keeps its behaviour.(CVE-2026-64299)

In the Linux kernel, the following vulnerability has been resolved:

USB: iowarrior: fix use-after-free on disconnect race

mutex_unlock() may access the mutex structure after releasing the lock and therefore cannot be used to manage lifetime of objects directly (unlike spinlocks and refcounts). [1][2]

Use a kref to release the driver data to avoid use-after-free in mutex_unlock() when release() races with disconnect().

[1] a51749ab34d9 ("locking/mutex: Document that mutex_unlock() is non-atomic") [2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutex_unlock(), and most other sleeping locks, can still use the lock object after it's unlocked")(CVE-2026-64341)

In the Linux kernel, the following vulnerability has been resolved:

HID: lg-g15: cancel pending work on remove to fix a use-after-free

lg_g15_data is allocated with devm and holds a work item. The report handlers schedule that work straight from device input. lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key, and lg_g510_leds_event() does it too. The worker dereferences the lg_g15_data back through container_of.

The driver had no remove callback and never cancelled the work. So if a report scheduled the work and the keyboard was then unplugged, devres freed lg_g15_data while the work was still pending or running, and the worker touched freed memory. This is a use-after-free. It is reachable as a race on device unplug.

Add a remove callback that cancels the work before devres frees the state. g15->work is only initialized for the models that schedule it (G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the cancel on g15->work.func to avoid cancelling a work that was never set up. The g15 NULL test mirrors the one already in lg_g15_raw_event().(CVE-2026-64362)

In the Linux kernel, the following vulnerability has been resolved:

sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT

RT migration is done aggressively. When a CPU schedules out a high priority RT task for a lower priority task, it will look to see if there's any RT tasks that are waiting to run on another CPU that is of higher priority than the task this CPU is about to run. If it finds one, it will pull that task over to the CPU and allow it to run there instead.

Normally, this pulling is done by looking at the RT overloaded mask (rto) which contains all the CPUs in the scheduler domain with RT tasks that are waiting to run due to a higher priority RT task currently running on their CPU. The CPU that is about to schedule a lower priority task will grab the rq lock of the overloaded CPU and move the RT task from that CPU's runqueue to the local one and schedule the higher priority RT task.

This caused issues when a lot of CPUs would schedule a lower priority task at the same time. They would all try to grab the same runqueue lock of the CPU with the overloaded RT tasks. Only the first CPU that got in will get that task. All the others would wait until they got the runqueue lock and see there's nothing to pull and do nothing. On systems with lots of CPUs, this caused a large latency (up to 500us) which is beyond what PREEMPT_RT is to allow.

The solution to that was to create an RT_PUSH_IPI logic. When any CPU wanted to pull a task, instead of grabbing the runqueue lock of the overloaded CPU, it would start by sending an IPI to the overloaded CPU, and that IPI handler would have the CPU with the waiting RT task do a push instead. Then that handler would send an IPI to the next CPU with overloaded RT tasks, and so on. Note, after the first CPU starts this process, if another CPU wanted to do a pull, it would see that the process has already begun and would only increment a counter to have the IPIs continue again.

The RT_PUSH_IPI solved the latency problem with PREEMPT_RT but could cause a new issue with non PREEMPT_RT. Namely, softirqs run in a threaded context on PREEMPT_RT but they can run in an interrupt context in non-RT.

If an IPI lands on a CPU that has just woken up multiple RT tasks and the current CPU is running a non RT or a low priority RT task, instead of doing a push, it would simply do a schedule on that CPU. But if a softirq was also executing on this CPU, the schedule would need to wait until the softirq finished. Until then, the CPU would still be considered overloaded as there are RT tasks still waiting to run on it.

A live lock occurred on a workload that was doing heavy networking traffic on a large machine where the softirqs would run 500us out of 750us. And it would also be waking up RT tasks, causing the RT pull logic to be constantly executed.

When a softirq triggered on a CPU with RT tasks queued but not running yet, and the other CPUs would see this CPU as being overloaded, they would send an IPI over to it. The CPU would notice that the waiting RT tasks are of higher priority than the currently running task and simply schedule that CPU instead. But because the softirq was executing, before it could schedule, it would receive another IPI to do the same. The amount of IPIs would slow down the currently running softirq so much that before it could return back to task context, it would execute another softirq never allowing the CPU to schedule. This live locked that CPU.

As RT_PUSH_IPI was created to help PREEMPT_RT, make it default off if PREEMPT_RT is not enabled.(CVE-2026-64374)

In the Linux kernel, the following vulnerability has been resolved:

writeback: fix race between cgroup_writeback_umount() and inode_switch_wbs()

When a container exits, the following BUG_ON() is occasionally triggered:

================================================================== VFS: Busy inodes after unmount of sdb (ext4) ------------[ cut here ]------------ kernel BUG at fs/super.c:695! CPU: 3 PID: 6 Comm: containerd-shim Tainted: G OE K 6.6 #1 pstate: 63400009 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--) pc : generic_shutdown_super+0xf0/0x100 lr : generic_shutdown_super+0xf0/0x100 Call trace: generic_shutdown_super+0xf0/0x100 kill_block_super+0x20/0x48 ext4_kill_sb+0x28/0x60 deactivate_locked_super+0x54/0x130 deactivate_super+0x84/0xa0 cleanup_mnt+0xa4/0x140 __cleanup_mnt+0x18/0x28 task_work_run+0x78/0xe0 do_notify_resume+0x204/0x240

The root cause is a race between cgroup_writeback_umount() and inode_switch_wbs()/cleanup_offline_cgwb(). There is a window between inode_prepare_wbs_switch() returning true and the subsequent wb_queue_isw() call. Following is the process that triggers the issue:

  CPU A (umount)           |          CPU B (writeback)
                                 inode_switch_wbs/cleanup_offline_cgwb
                                  atomic_inc(&amp;isw_nr_in_flight)
                                  inode_prepare_wbs_switch
                                   -&gt; passes SB_ACTIVE check
                                   __iget(inode)
 generic_shutdown_super
  sb-&gt;s_flags &amp;= ~SB_ACTIVE
  cgroup_writeback_umount(sb)
   smp_mb()
   atomic_read(&amp;isw_nr_in_flight)
   rcu_barrier()
    -&gt; no pending RCU callbacks
   flush_workqueue(isw_wq)
    -&gt; nothing queued, returns
  evict_inodes(sb)
   -&gt; Inode skipped as isw still holds a ref.
  sop-&gt;put_super(sb)
   /* destroys percpu counters */
  -&gt; VFS: Busy inodes after unmount!
                                  wb_queue_isw()
                                   queue_work(isw_wq, ...)
                                  /* later in work function */
                                  inode_switch_wbs_work_fn
                                   process_inode_switch_wbs
                                    iput() -&gt; evict
                                     percpu_counter_dec() // UAF!

Fix this by extending the RCU read-side critical section in
inode_switch_wbs() and cleanup_offline_cgwb() to cover from
inode_prepare_wbs_switch() through wb_queue_isw().  Since there is
no sleep in this window, rcu_read_lock() can be used.  Then add a
synchronize_rcu() in cgroup_writeback_umount() before the existing
rcu_barrier(), so that all in-flight switchers that have passed the
SB_ACTIVE check have completed queue_work() before flush_workqueue()
is called.

The existing rcu_barrier() is intentionally retained so this fix can
be backported unchanged to stable kernels (5.10.y, 6.6.y, ...) that
still queue switches via queue_rcu_work(). It is a no-op on current
mainline (since commit e1b849cfa6b6 (&quot;writeback: Avoid contention on
wb-&gt;list_lock when switching inodes&quot;)) and is removed in a follow-up
patch.(CVE-2026-64378)

In the Linux kernel, the following vulnerability has been resolved:

ksmbd: serialize QUERY_DIRECTORY requests per file

smb2_query_dir() stores a pointer to its stack-allocated private data in
the ksmbd_file readdir_data. Concurrent QUERY_DIRECTORY requests using the
same file handle can overwrite this pointer while an iterate_dir() callback
is still using it, resulting in a stack use-after-free.

Add a per-file mutex and hold it while accessing the shared directory
enumeration state. The lock covers scan restart, dot entry state,
readdir_data setup and iteration, and response construction. This prevents
another request from replacing readdir_data.private before the current
request has finished using it and also serializes the shared file position.(CVE-2026-64397)

In the Linux kernel, the following vulnerability has been resolved:

hwrng: virtio: clamp device-reported used.len at copy_data()

random_recv_done() stores the device-reported used.len directly into
vi-&gt;data_avail.  copy_data() then indexes vi-&gt;data[] using
vi-&gt;data_idx (advanced by previous copy_data() calls) and issues a
memcpy() without re-validating either value against the posted
buffer size sizeof(vi-&gt;data) (SMP_CACHE_BYTES bytes, typically 32
or 64).

A malicious or buggy virtio-rng backend can set used.len beyond
sizeof(vi-&gt;data), steering the memcpy() past the end of the inline
array into adjacent kmalloc-1k slab bytes.  hwrng_fillfn() mixes
those bytes into the guest RNG, and guest root can also observe
them directly via /dev/hwrng.

Concrete impact is inside the guest:

 - Memory-safety / hardening: any virtio-rng backend that
   over-reports used.len causes the driver to read past vi-&gt;data
   into unrelated slab contents.  hwrng_fillfn() is a kernel thread
   that runs as soon as the device is probed; no guest userspace
   interaction is required to first-trigger the OOB.

 - Cross-boundary leak (confidential-compute threat model): a
   malicious hypervisor cooperating with a malicious or compromised
   guest root userspace can use /dev/hwrng as a leak channel for
   guest-kernel heap data.  The host sets a large used.len, guest
   root reads /dev/hwrng, and the returned bytes contain guest
   kernel slab contents that were adjacent to vi-&gt;data.  In
   practice, confidential-compute guests (SEV-SNP, TDX) usually
   disable virtio-rng entirely, so this path is narrow, but the
   fix is still worth carrying because the underlying
   memory-safety bug contaminates the guest RNG on any host.

KASAN confirms the OOB on a 7.1-rc4 guest whose virtio-rng backend
has been patched to report used.len = 0x10000:

  BUG: KASAN: slab-out-of-bounds in virtio_read+0x394/0x5d0
  Read of size 64 at addr ffff88800ae0ba20 by task hwrng/52
  Call Trace:
   __asan_memcpy+0x23/0x60
   virtio_read+0x394/0x5d0
   hwrng_fillfn+0xb2/0x470
   kthread+0x2cc/0x3a0
  Allocated by task 1:
   probe_common+0xa5/0x660
   virtio_dev_probe+0x549/0xbc0
  The buggy address belongs to the object at ffff88800ae0b800
   which belongs to the cache kmalloc-1k of size 1024
  The buggy address is located 0 bytes to the right of
   allocated 544-byte region [ffff88800ae0b800, ffff88800ae0ba20)

Same class of bug as commit c04db81cd028 (&quot;net/9p: Fix buffer
overflow in USB transport layer&quot;), which hardened
usb9pfs_rx_complete() against unchecked device-reported length in
the USB 9p transport.

With the clamp at point of use and array_index_nospec() in place,
the same harness boots cleanly: copy_data() returns zero for the
bogus report, the device-supplied bytes after data_idx are
discarded, and the driver issues a fresh request.(CVE-2026-64456)

In the Linux kernel, the following vulnerability has been resolved:

iio: event: Fix event FIFO reset race

`iio_event_getfd()` creates the event file descriptor with
`anon_inode_getfd()`, which allocates a new fd, creates the anonymous
file and installs it in the process fd table before returning to the
caller.

The IIO code resets the event FIFO after `anon_inode_getfd()` has returned,
but before `IIO_GET_EVENT_FD_IOCTL` has copied the fd number to userspace.
But since fd tables are shared between threads, another thread can guess
the newly allocated fd number and issue a `read()` on it as soon as the fd
has been installed.

This means the `kfifo_to_user()` in `iio_event_chrdev_read()` can run in
parallel with the `kfifo_reset_out()` in `iio_event_getfd()`.

The kfifo documentation says that `kfifo_reset_out()` is only safe when it
is called from the reader thread and there is only one concurrent reader.
Otherwise it is dangerous and must be handled in the same way as
`kfifo_reset()`.

If that happens, `kfifo_to_user()` can advance the FIFO `out` index based
on state from before the reset, after the reset has already moved the `out`
index to the current `in` index. That can leave the FIFO with an `out`
index past the `in` index. A later `read()` can then see an underflowed
FIFO length and copy more data than the event FIFO buffer contains. This
can result in an out-of-bounds read and leak adjacent kernel memory to
userspace.

Move the FIFO reset before `anon_inode_getfd()`. At that point the event fd is
marked busy, but the new fd has not been installed yet, so userspace cannot
access it while the FIFO is reset.(CVE-2026-64496)

In the Linux kernel, the following vulnerability has been resolved:

posix-cpu-timers: Prevent UAF caused by non-leader exec() race

Wongi and Jungwoo decoded and reported a non-leader exec() related race
which can result in an UAF:

 sys_timer_delete()			exec()
   posix_cpu_timer_del()
   // Observes old leader
   p = pid_task(pid, pid_type);		de_thread()
   					  switch_leader();
					  release_task(old_leader)
					    __exit_signal(old_leader)
					      sighand = lock(old_leader, sighand);
					      posix_cpu_timers*_exit();
   sighand = lock_task_sighand(p)	      unhash_task(old_leader);
     sh = lock(p, sighand)	    	      old_leader-&gt;sighand = NULL;
					      unlock(sighand);
     (p-&gt;sighand == NULL)
	unlock(sh)
	return NULL;

   // Returns without action
   if(!sighand)
      return 0;
   free_posix_timer();

This is &quot;harmless&quot; unless the deleted timer was armed and enqueued in
p-&gt;signal because on exec() a TGID targeted timer is inherited.

As sys_timer_delete() freed the underlying posix timer object
run_posix_cpu_timers() or any timerqueue related add/delete operations on
other timers will access the freed object&apos;s timerqueue node, which results
in an UAF.

There is a similar problem vs. posix_cpu_timer_set(). For regular posix
timers it just transiently returns -ESRCH to user space, but for the use
case in do_cpu_nanosleep() it&apos;s the same UAF just that the k_itimer is
allocated on the stack.

Also posix_cpu_timer_rearm() fails to rearm the timer, which means it stops
to expire.

While debating solutions Frederic pointed out another problem:

   posix_cpu_timer_del(tmr)
					__exit_signal(p)
					  posix_cpu_timers*_exit(p);
					  unhash_task(p);
					  p-&gt;sighand = NULL;
     sh = lock_task_sighand(p)
        sighand = p-&gt;sighand;
	if (!sighand)
	    return NULL;
	lock(sighand);

     if (!sh)
	WARN_ON_ONCE(timer_queued(tmr));

On weakly ordered architectures it is not guaranteed that
posix_cpu_timer_del() will observe the stores in posix_cpu_timers*_exit()
when p-&gt;sighand is observed as NULL, which means the WARN() can be a false
positive.

Solve these issues by:

  1) Changing the store in __exit_signal() to smp_store_release().

  2) Adding a smp_acquire__after_ctrl_dep() into the !sighand path
     of lock_task_sighand().

  3) Creating a helper function for looking up the task and locking sighand
     which does not return when sighand == NULL. Instead it retries the
     task lookup and only if that fails it gives up.

  4) Using that helper in the three affected functions.

#1/#2 ensures that the reader side which observes sighand == NULL also
observes all preceeding stores, i.e. the stores in posix_cpu_timers*_exit()
and the ones in unhash_task().

#3 ensures that the above described non-leader exec() situation is handled
gracefully. When the task lookup returns the old leader, but sighand ==
NULL then it retries. In the non-leader exec() case the subsequent task
lookup will observe the new leader due to #1/#2. In normal exit() scenarios
the subsequent lookup fails.

When the task lookup fails, the function also checks whether the timer is
still enqueued and issues a warning if that&apos;s the case. Unfortunately there
is nothing which can be done about it, but as the task is already not
longer visible the timer should not be accessed anymore. This check also
requires memory ordering, which is not provided when the first lookup
fails. To achieve that the check is preceeded by a smp_rmb() which pairs
with the smp_wmb() in write_seqlock() in __exit_signal(). That ensures that
the stores in posix_cpu_timers*_exit() are visible.

The history of the non-leader exec() issue goes back to the early days of
posix CPU timers, which stored a pointer to the group leader task in the
timer. That obviously fails when a non-leader exec() switches the leader.
commit e0a70217107e (&quot;posix-cpu-timers: workaround to suppress the problems
with mt exec&quot;) added a temporary workaround for that in 2010 which surv
---truncated---(CVE-2026-64560)
Database specific
{
    "severity": "Critical"
}
References

Affected packages

openEuler:22.03-LTS-SP4 / kernel

Package

Name
kernel
Purl
pkg:rpm/openEuler/kernel&distro=openEuler-22.03-LTS-SP4

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
5.10.0-327.0.0.228.oe2203sp4

Ecosystem specific

{
    "aarch64": [
        "bpftool-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "bpftool-debuginfo-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-debuginfo-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-debugsource-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-devel-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-headers-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-source-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-tools-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-tools-debuginfo-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "kernel-tools-devel-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "perf-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "perf-debuginfo-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "python3-perf-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm",
        "python3-perf-debuginfo-5.10.0-327.0.0.228.oe2203sp4.aarch64.rpm"
    ],
    "src": [
        "kernel-5.10.0-327.0.0.228.oe2203sp4.src.rpm"
    ],
    "x86_64": [
        "bpftool-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "bpftool-debuginfo-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-debuginfo-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-debugsource-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-devel-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-headers-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-source-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-tools-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-tools-debuginfo-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "kernel-tools-devel-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "perf-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "perf-debuginfo-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "python3-perf-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm",
        "python3-perf-debuginfo-5.10.0-327.0.0.228.oe2203sp4.x86_64.rpm"
    ]
}

Database specific

source
"https://repo.openeuler.org/security/data/osv/OESA-2026-3303.json"