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.osv.dev/v1/vulns/OESA-2026-3303
Upstream
Published
2026-08-07T02:45:24Z
Modified
2026-08-07T03:01:01.134415926Z
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 sndsocdapmstreamevent(), called from the closedelayedwork workqueue handler.

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

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

Add a flush in soccleanupcardresources() after sndcarddisconnectsync() (after which no new PCM closes can schedule further delayed work) and before socremovelinkdais() and socremovelinkcomponents() (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 vmops to dlfbops_mmap to prevent use-after-free

dlfbopsmmap() uses remappfnrange() to map vmalloc framebuffer pages to userspace but sets no vmops on the VMA. This means the kernel cannot track active mmaps. When dlfbreallocframebuffer() replaces the backing buffer via FBIOPUTVSCREENINFO, existing mmap PTEs are not invalidated. On USB disconnect, dlfbopsdestroy() 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 vmoperationsstruct with open/close callbacks that maintain an atomic mmapcount on struct dlfbdata. In dlfbreallocframebuffer(), check mmap_count and return -EBUSY if the buffer is currently mapped, preventing buffer replacement while userspace holds stale PTEs.

Tested with PoC using dummyhcd + rawgadget 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 _rdmablockiternext() 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()

pppol2tpioctl() read sock->sk->skuserdata directly without any locks or reference counting. If a controllable sleep was induced during copyfromuser() (e.g. via a userfaultfd page fault sleep), a concurrent socket close could trigger pppol2tpsessionclose() asynchronously. This frees the l2tpsession structure via the l2tpsessiondel_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 pppol2tpsocktosession(sk) on entry. This locks the session's refcount across the sleep. We structured the function to exit via standard err breaks, guaranteeing that l2tpsession_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 sockdoioctl()).(CVE-2026-53262)

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

fuse: re-lock request before replacing page cache folio

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

Fix this by calling lockrequest() before replacepagecachefolio(). This ensures the request is locked on the success path which will prevent the fuseioargs 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 replacepagecache_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 i2cgetadapter() 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 i2cgetadapter() 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: inflatefast+1431 Call Trace: zlibinflate __deflatedecompress cryptocompdecompress ipcompdecompress [xfrmipcomp] ipcompinput [xfrmipcomp] xfrminput

At the crash point, the compiler generated three loads from the same global GCOV counter (_gcov0.inflatefast+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 CFLAGSGCOV 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 KBUILDCFLAGS, then compares undefined symbols in the resulting object files. If prefer-atomic introduces new undefined references (such as __atomicfetchadd_8 on i386 or __aarch64ldadd8relax 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 CFLAGSGCOV block from its original position (before the arch Makefile include) to after the core KBUILDCFLAGS 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

aareplaceprofiles() walks ns->rawdatalist to dedup the incoming policy blob against entries already attached to existing profiles. Per the kernel-doc on struct aaloaddata, list membership does not hold a reference: profiles hold pcount, and when the last pcount drops, doploaddatarmfs() 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.

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

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

inside aareplaceprofiles(), 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 getunlesszero-style helper on a single counter, so the existing "if (tmp)" guard was meaningful. The split-refcount refactor introduced aagetprofileloaddata(), which has plain krefget() semantics, and the guard quietly became a no-op.

Introduce aagetprofileloaddatanot0(), matching the existing not0 convention used by aagetprofilenot0(), 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 refcountt 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 CONFIGKASAN, CONFIGKCSAN and CONFIGPROVE_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 iscsiencodetextoutput() appends to rspbuf

iscsiencodetextoutput() concatenates "key=value\0" records into login->rspbuf, an 8192-byte kzalloc(MAXKEYVALUEPAIRS) buffer allocated in iscsitallocloginsetup_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 iscsitargetcheckloginrequest() 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 iscsiaddnotunderstood_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 iscsiencodetextrecord() helper that uses snprintf() with a per-call bounds check against the remaining buffer, and threads a u32 textbufsize parameter through iscsiencodetextoutput(). Both call sites in iscsitargethandlecsgzero() (PHASESECURITY) and iscsitargethandlecsgone() (PHASEOPERATIONAL) pass MAXKEYVALUEPAIRS. On overflow the encoder logs the condition, calls iscsireleaseextraresponses() to drop queued records, and returns -1; both caller sites now emit ISCSISTATUSCLSINITIATORERR / ISCSILOGINSTATUSINITERR via iscsittxloginrsp() before returning, so the initiator sees an explicit failed-login response rather than a silent connection drop. (Prior to this patch only the PHASEOPERATIONAL caller did that; the PHASESECURITY 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 iscsithandletext_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).

textin is kzalloc()'d at ALIGN(payloadlength, 4). rxsize is then incremented by ISCSICRCLEN to make room for the received DataDigest in the iovec, but the same (now-bumped) rxsize is passed as the buffer length to iscsitcrcbuf():

   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);

iscsitcrcbuf() walks rxsize bytes of textin 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->textinptr 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->textinptr still points at the freed buffer. The next Text Request on the same ITT re-enters iscsitsetuptext_cmd(), which unconditionally does

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

freeing the same pointer a second time. Session teardown via iscsitreleasecmd() 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 iscsitsetuptextcmd() (next Text Request on the same ITT) and once more in iscsitreleasecmd() (session teardown). On distro kernels with CONFIGSLABFREELISTHARDENED=y (default) the double-free becomes a remote kernel BUG(); on non-hardened kernels it corrupts the slab freelist.

Fix by clearing cmd->textinptr 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 l2capecredconn_rsp

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

Calling l2capchanclone directly may still lead to l2capchandel so instead schedule l2capchantimeout 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 qedcxttables_alloc()

If one of the later PF or VF CID bitmap allocations fails, qedcidmapalloc() jumps to cidmapfail and frees the previously allocated CID bitmaps before returning an error. qedcxttablesalloc() then calls qedcxtmngrfree(), which invokes qedcidmapfree() 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 I2CSMBUSI2CBLOCKDATA case in stubxfer() 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 I2CSMBUSBLOCKMAX (32), which is the limit of the union i2csmbusdata.block buffer (34 bytes total). The driver is a development/test tool (CONFIGI2CSTUB=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 I2CSMBUS ioctl with I2CSMBUSI2CBLOCKDATA and data->block[0] > 32, causing stubxfer() to read or write past the end of the union i2csmbusdata.block buffer:

BUG: KASAN: stack-out-of-bounds in stubxfer (drivers/i2c/i2c-stub.c:223) Read of size 1 at addr ffff88800abcfd92 by task exploit/81 Call Trace: <TASK> stubxfer (drivers/i2c/i2c-stub.c:223) __i2csmbusxfer (drivers/i2c/i2c-core-smbus.c:593) i2c_smbusxfer (drivers/i2c/i2c-core-smbus.c:536) i2cdevioctlsmbus (drivers/i2c/i2c-dev.c:391) i2cdevioctl (drivers/i2c/i2c-dev.c:478) __x64sysioctl (fs/ioctl.c:583) dosyscall64 (arch/x86/entry/syscall64.c:94) entrySYSCALL64afterhwframe (arch/x86/entry/entry64.S:130) </TASK>

The bug exists because i2c-stub implements .smbusxfer directly, bypassing the I2CSMBUSBLOCKMAX validation in i2csmbusxferemulated(). The I2CSMBUSBLOCKDATA case in the same function correctly validates against I2CSMBUSBLOCKMAX, but the I2CSMBUSI2CBLOCK_DATA case does not.

Fix by rejecting transfers with data->block[0] == 0 or data->block[0] > I2CSMBUSBLOCKMAX with -EINVAL, consistent with both the I2CSMBUSBLOCKDATA case in the same function and the I2CSMBUSI2CBLOCKDATA validation in i2csmbusxfer_emulated().(CVE-2026-64191)

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

bpf: Reject BPFMAPTYPEINODESTORAGE creation if BPF LSM is uninitialized

When CONFIGBPFLSM=y is set, BPF inode storage maps (BPFMAPTYPEINODESTORAGE) 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 (bpflsmblobsizes.lbsinode) 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 BPFMAPTYPEINODESTORAGE map, bpfinode() evaluates inode->isecurity + 8. This erroneously aliases the struct rcuhead.func callback pointer at the beginning of the inode->isecurity blob. During subsequent map element cleanup or inode destruction, writing NULL to ownerstorage clears the queued RCU callback pointer. When rcudo_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 bpflsminitialized boolean flag marked with _roafterinit. Set this flag to true inside bpflsminit() when the LSM framework successfully registers the BPF LSM. Gate map allocation in inodestoragemapalloc() 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 (filterpredstring(), filterpredstrloc() and filterpredstrrelloc()) pass the field length to the regex match callbacks, and the length-aware matchers honour it.

regexmatchglob() was the exception: it ignored the length and called globmatch(), 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 globmatch(), reached via regexmatchglob() and filtermatchpreds() from the xfslookup tracepoint.

Add a length-bounded globmatchlen() and use it from regexmatchglob() 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 mutexunlock() is non-atomic") [2] 2b9d9e0a9ba0 ("locking/mutex: Clarify that mutexunlock(), 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

lgg15data is allocated with devm and holds a work item. The report handlers schedule that work straight from device input. lgg15event() and lgg15v2event() do it on the backlight cycle key, and lgg510ledsevent() does it too. The worker dereferences the lgg15data 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 lgg15data 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 lgg15raw_event().(CVE-2026-64362)

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

sched/rt: Have RTPUSHIPI 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 RTPUSHIPI 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 RTPUSHIPI solved the latency problem with PREEMPTRT but could cause a new issue with non PREEMPTRT. 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 RTPUSHIPI was created to help PREEMPTRT, make it default off if PREEMPTRT is not enabled.(CVE-2026-64374)

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

writeback: fix race between cgroupwritebackumount() and inodeswitchwbs()

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 : genericshutdownsuper+0xf0/0x100 lr : genericshutdownsuper+0xf0/0x100 Call trace: genericshutdownsuper+0xf0/0x100 killblocksuper+0x20/0x48 ext4killsb+0x28/0x60 deactivatelockedsuper+0x54/0x130 deactivatesuper+0x84/0xa0 cleanupmnt+0xa4/0x140 _cleanupmnt+0x18/0x28 taskworkrun+0x78/0xe0

donotifyresume+0x204/0x240

The root cause is a race between cgroupwritebackumount() and inodeswitchwbs()/cleanupofflinecgwb(). There is a window between inodepreparewbsswitch() returning true and the subsequent wbqueue_isw() call. Following is the process that triggers the issue:

  CPU A (umount)           |          CPU B (writeback)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inodeswitchwbs/cleanupofflinecgwb atomicinc(&iswnrinflight) inodepreparewbsswitch -> passes SBACTIVE check _iget(inode) genericshutdownsuper sb->sflags &= ~SBACTIVE cgroupwritebackumount(sb) smpmb() atomicread(&iswnrinflight) rcubarrier() -> no pending RCU callbacks flushworkqueue(iswwq) -> nothing queued, returns evictinodes(sb) -> Inode skipped as isw still holds a ref. sop->putsuper(sb) /* destroys percpu counters */ -> VFS: Busy inodes after unmount! wbqueueisw() queuework(iswwq, ...) /* later in work function */ inodeswitchwbsworkfn processinodeswitchwbs iput() -> evict percpucounterdec() // UAF!

Fix this by extending the RCU read-side critical section in inodeswitchwbs() and cleanupofflinecgwb() to cover from inodepreparewbsswitch() through wbqueueisw(). Since there is no sleep in this window, rcureadlock() can be used. Then add a synchronizercu() in cgroupwritebackumount() before the existing rcubarrier(), so that all in-flight switchers that have passed the SBACTIVE check have completed queuework() before flushworkqueue() is called.

The existing rcubarrier() is intentionally retained so this fix can be backported unchanged to stable kernels (5.10.y, 6.6.y, ...) that still queue switches via queuercuwork(). It is a no-op on current mainline (since commit e1b849cfa6b6 ("writeback: Avoid contention on wb->listlock when switching inodes")) 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

smb2querydir() stores a pointer to its stack-allocated private data in the ksmbdfile readdirdata. Concurrent QUERYDIRECTORY requests using the same file handle can overwrite this pointer while an iteratedir() 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, readdirdata setup and iteration, and response construction. This prevents another request from replacing readdirdata.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()

randomrecvdone() stores the device-reported used.len directly into vi->dataavail. copydata() then indexes vi->data[] using vi->dataidx (advanced by previous copydata() calls) and issues a memcpy() without re-validating either value against the posted buffer size sizeof(vi->data) (SMPCACHEBYTES bytes, typically 32 or 64).

A malicious or buggy virtio-rng backend can set used.len beyond sizeof(vi->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->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->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: __asanmemcpy+0x23/0x60 virtioread+0x394/0x5d0 hwrngfillfn+0xb2/0x470 kthread+0x2cc/0x3a0 Allocated by task 1: probecommon+0xa5/0x660 virtiodevprobe+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 ("net/9p: Fix buffer overflow in USB transport layer"), which hardened usb9pfsrxcomplete() against unchecked device-reported length in the USB 9p transport.

With the clamp at point of use and arrayindexnospec() in place, the same harness boots cleanly: copydata() returns zero for the bogus report, the device-supplied bytes after dataidx 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:

systimerdelete() exec() posixcputimerdel() // Observes old leader p = pidtask(pid, pidtype); dethread() switchleader(); releasetask(oldleader) exitsignal(oldleader) sighand = lock(oldleader, sighand); posixcputimers*exit(); sighand = locktasksighand(p) unhashtask(oldleader); sh = lock(p, sighand) oldleader->sighand = NULL; unlock(sighand); (p->sighand == NULL) unlock(sh) return NULL;

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

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

As systimerdelete() freed the underlying posix timer object runposixcpu_timers() or any timerqueue related add/delete operations on other timers will access the freed object's timerqueue node, which results in an UAF.

There is a similar problem vs. posixcputimerset(). For regular posix timers it just transiently returns -ESRCH to user space, but for the use case in docpunanosleep() it's the same UAF just that the kitimer is allocated on the stack.

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

While debating solutions Frederic pointed out another problem:

posixcputimerdel(tmr) exitsignal(p) posixcputimers*exit(p); unhashtask(p); p->sighand = NULL; sh = locktasksighand(p) sighand = p->sighand; if (!sighand) return NULL; lock(sighand);

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

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

Solve these issues by:

1) Changing the store in _exitsignal() to smpstorerelease().

2) Adding a smp_acquire__afterctrldep() into the !sighand path of locktasksighand().

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 posixcputimers*exit() and the ones in unhashtask().

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'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 smprmb() which pairs with the smpwmb() in write_seqlock() in _exitsignal(). That ensures that the stores in posixcputimers*_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 ("posix-cpu-timers: workaround to suppress the problems with mt exec") 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
0Unknown introduced version / All previous versions are affected
Fixed
5.10.0-327.0.0.228.oe2203sp4

Ecosystem specific

{
    "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"
    ],
    "src": [
        "kernel-5.10.0-327.0.0.228.oe2203sp4.src.rpm"
    ],
    "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"
    ]
}

Database specific

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