Export limit exceeded: 24446 CVEs match your query. Please refine your search to export 10,000 CVEs or fewer.
Search
Search Results (24446 CVEs found)
| CVE | Vendors | Products | Updated | CVSS v3.1 |
|---|---|---|---|---|
| CVE-2026-90043 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: zram: fix slot lock bit position on big-endian 64-bit The slot lock is a bit operation on the whole __lock word, which flags and ac_time alias as two u32s. On little-endian the lock bit lands in the position ZRAM_ENTRY_LOCK reserves in flags, so the aliasing works out. On 64-bit big-endian it lands in ac_time instead: with ZRAM_TRACK_ENTRY_ACTIME enabled, storing the access time from mark_slot_accessed() or slot_free() wipes out the held lock bit, letting another CPU take the same slot lock; an access time value with that bit set makes the slot look locked forever. Shift the lock bit into the flags half of the word on big-endian 64-bit. | ||||
| CVE-2026-90044 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: usb: gadget: f_fs: Fix Use-After-Free in AIO error path In ffs_epfile_write_iter() and ffs_epfile_read_iter(), when ffs_epfile_io() fails with an error other than -EIOCBQUEUED, the io_data structure (`p`) is freed. However, for AIO operations, the kiocb cancel function was already armed and kiocb->private was set to `p`. If a concurrent cancel operation (such as sys_io_cancel()) executes after ffs_epfile_io() fails but before the function frees `p`, a Use-After-Free can occur when the cancellation handler accesses the freed pointer. To securely fix this race condition, we must properly un-arm the cancellation. Invoking `kiocb->ki_complete()` does exactly this by acquiring `ctx->ctx_lock` and safely removing the kiocb from the active sequence. In doing so, it ensures that a parallel io_cancel can no longer discover the kiocb, effectively closing the race window. We then return -EIOCBQUEUED to notify the VFS layer that the kiocb has been consumed and it should avoid attempting to complete the request again or triggering subsequent completion handlers. | ||||
| CVE-2026-90046 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: mm/page_alloc: don't spin_trylock() in NMI on UP Patch series "mm/page_alloc: fixes for free_pages_nolock() on RT/UP". Pre-existing bugs found by Sashiko during review of this other series: https://lore.kernel.org/all/20260703-alloc-trylock-v5-0-c87b714e19d3@google.com/ I have not reproduced these bugs, and I suspect there is no real-world user that is affected by them. This patch (of 2): As noted in can_spin_trylock(), using this is unsafe in this context. commit 620b46ed6ae17 ("mm/page_alloc: return NULL early from alloc_frozen_pages_nolock() in NMI on UP") fixed this on the alloc side but missed the free side. Impact: If BPF programs using these features in NMI (probably tracing) are present on non-SMP builds this might crash the kernel and is probably exploitable by local attackers for privilege escalation. | ||||
| CVE-2026-90047 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: drm/xe: Don't hand out the flat CCS storage as usable VRAM get_flat_ccs_offset() reads the base of the flat CCS storage from the hardware, scales it by the number of enabled L3 nodes, and rounds the result up to 128K. Everything below that offset is then handed to the VRAM allocator as usable memory. Rounding a limit that means "usable memory ends here" upwards publishes whatever lies between the real base and the rounded one as free memory, and that memory belongs to the compression hardware. The scaled value has no reason to be 128K aligned, and on a Battlemage G21 with 16 GiB it is not: flat CCS base: raw 0x3fafff800, rounded 0x3fb000000 so the last 2 KiB of page 0x3fafff000 is CCS storage, in the allocator's pool. Whatever is allocated there gets that tail overwritten by the compression hardware, which needs no page-table entry, no buffer object and no GPU submission to do it, and does it before userspace exists. On this machine a Mesa VM's level-3 page table landed on that page on every cold boot. It lost the entry covering the compositor's batch-buffer heap, so the compositor's first submission faulted fetching its batch and gdm restarted it forever: a black screen on an otherwise working machine. Restarting gdm cleared it because the next VM's page tables were allocated somewhere else. Round down instead, to the page size the allocator works in. On this machine that excludes exactly one page. Reading the reserved page afterwards shows what had been writing it: [369] 0xcccc000000000000 [371] 0xcc77000000000000 [373] 0xcccc000000000000 [375] 0xcc77000000000000 compression metadata, two bytes per sixteen, sitting where the driver used to hand out memory. The assertion that should have caught this compares the offset against GSMBASE - ccs_size for equality. That value is 128K aligned, so it agrees with the rounded-up offset precisely when the base is not aligned - the check cannot fail in the case it exists to catch, and is compiled out unless CONFIG_DRM_XE_DEBUG is set. Replace it with one that can fail: CCS storage must not run into GSM. [ And this was a debug session from hell, enormously helped by an AI doing much of the grunt-work. I'd like to call it my tireless helper, but the AI several times stated flat out that this was impossible and unsolvable and that we should just write a report about it. I suspect those things have been trained by people who may not be quite as stubborn as I am. But while the AI was ready to give up several times, it did keep adding debug code and analyzing it faithfully when I pushed. So credit where credit is due and I let the AI write the commit message above. This is basically a one-liner fixing a bogus "round_up()" to a "round_down()", but there were 24 patches adding more and more debug information to this, and 18 kernel boot to finally narrow it down to this. - Linus ] | ||||
| CVE-2026-89993 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: dmaengine: dw-edma: Initialize IRQ data before requesting IRQs dw_edma_irq_request() passes struct dw_edma_irq to request_irq() before dw_edma_channel_setup() fills the back pointer. A shared interrupt can therefore enter the handler with dw_irq->dw still NULL, leading to a NULL pointer dereference. Set the back pointer before installing each handler. | ||||
| CVE-2026-89995 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 8.8 High |
| In the Linux kernel, the following vulnerability has been resolved: dma-direct: return struct page from dma_direct_alloc_from_pool() Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper") changed dma_direct_alloc_from_pool() to return the CPU address from dma_alloc_from_pool(). That fits dma_direct_alloc(), but dma_direct_alloc_pages() also uses the helper and expects a struct page *. Fix this by making dma_direct_alloc_from_pool() return the struct page * again, and pass the CPU address back through an out-parameter for the dma_direct_alloc() caller. | ||||
| CVE-2026-89999 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 8.1 High |
| In the Linux kernel, the following vulnerability has been resolved: HID: wacom: validate report length in wacom_intuos_pro2_bt_irq wacom_intuos_pro2_bt_irq() receives the wire report length in `len` but never consults it before parsing. After the report-id gate it unconditionally calls wacom_intuos_pro2_bt_pen() and then, selected by features.type, a fixed chain of sub-parsers, none of which receive `len`: wacom_intuos_pro2_bt_pen(wacom); if (type == INTUOSP2_BT || type == INTUOSP2S_BT) { wacom_intuos_pro2_bt_touch(wacom); wacom_intuos_pro2_bt_pad(wacom); wacom_intuos_pro2_bt_battery(wacom); } else { wacom_intuos_gen3_bt_pad(wacom); wacom_intuos_gen3_bt_battery(wacom); } Each sub-parser dereferences wacom->data at fixed offsets. The furthest byte touched on each branch is: INTUOSP2_BT / INTUOSP2S_BT: wacom_intuos_pro2_bt_pad() reads data[285] (the touchring byte), so the report must be at least 286 bytes; INTUOSHT3_BT ("gen3"): wacom_intuos_gen3_bt_battery() reads data[45], so the report must be at least 46 bytes. features.type is selected from the VID/PID id_table entry and wacom_setup_device_quirks() force-registers the pen/pad/touch inputs for that type independent of the report descriptor, so a malicious or malfunctioning paired/spoofed Bluetooth peripheral can advertise that VID/PID and send an undersized report that still satisfies the data[0] == 0x80/0x81 gate. The driver then reads past the received report and forwards the bytes to userspace via evdev (MSC_SERIAL / ABS_MISC / ABS_WHEEL on the pen and pad input nodes), an out-of-bounds read with a concrete userspace read-back channel, and a true out-of-bounds read on transports whose backing buffer is sized to the (small) report descriptor rather than a fixed-size staging buffer. This is the same class of bug commit 2f1763f62909 ("HID: wacom: fix out-of-bounds read in wacom_intuos_bt_irq") already hardened in the sibling wacom_intuos_bt_irq(), which guards each report id against its minimum length before parsing. Guard wacom_intuos_pro2_bt_irq() the same way: before parsing, reject reports shorter than the furthest offset the selected branch actually dereferences, warn, and bail out. Because the whole pen/touch/pad/ battery chain runs unconditionally per branch, a single up-front check against the maximum offset (286 bytes for INTUOSP2_BT/INTUOSP2S_BT, 46 bytes for the gen3 branch) bounds every sub-parser. Returning 0 on a short report also skips those calls for the same malformed report, which is the safe, conservative behavior. | ||||
| CVE-2026-90001 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: HID: bpf: serialize device reference release in struct_ops destroy path __hid_bpf_ops_destroy_device() and hid_bpf_unreg() can race on the same registration reference, double-putting struct hid_device and freeing it while hid_destroy_device() still uses it. Serialize the remove/NULL decision under hdev->bpf.prog_list_lock so exactly one path releases each registration reference: unreg re-checks ops->hdev under the lock and returns without putting when the destroy path already cleared it; all put_device() calls happen after the lock is dropped, which is safe because a concurrent unreg then observes ops->hdev == NULL under the lock. Background: each successful attach (hid_bpf_ops_reg) acquires one device reference (hid_get_device()). Two paths can release it: - device destruction: hid_destroy_device() -> hid_bpf_destroy_device() -> __hid_bpf_ops_destroy_device(), which walks hdev->bpf.prog_list under rcu_read_lock() and drops one reference per attached program; - BPF link release: bpf map delete (no BPF_F_LINK) synchronously calls st_ops->unreg() -> hid_bpf_unreg(), which drops the reference for its own registration. The coordination handshake (e->hdev = NULL on the destroy side vs "if (!hdev) return" on the unreg side) is a TOCTOU check: the two paths run under different lock domains (rcu_read_lock vs prog_list_lock), so a concurrent unreg can read ops->hdev as non-NULL, block on prog_list_lock, and then proceed while the destroy traversal executes - both paths then drop the same reference. The refcount reaches zero legitimately (each decrement is individually valid), so no refcount_t saturation fires: the device is simply freed while the transport is still inside hid_destroy_device(), and subsequent teardown touches freed memory. The fix serializes the remove/NULL decision under prog_list_lock on both sides and moves the destroy-side puts outside the lock. With the lock held, plain reads/writes of ops->hdev are sufficient; no READ_ONCE/WRITE_ONCE are added, keeping the patch minimal. Unlocked-read safety: the unlocked read of ops->hdev at the top of hid_bpf_unreg() cannot touch a freed device, because the unreg path itself still holds this registration's reference (released only by its own hid_put_device() after the lock is dropped), and a destroy traversal that already cleared ops->hdev makes the lock-internal re-check return early without any put. At most one of the two paths releases each registration reference. | ||||
| CVE-2026-90014 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: tracing: Have show_event_filters/triggers files take trace array ref The newly added files show_event_filters and show_event_triggers that show all filters or triggers that are set within the trace array do not take a reference for the trace array it is showing. Without taking a reference, the trace_array may be freed via "rmdir" while a task is reading one of theses files. Those files iterate all the events within an instance (trace_array) and nothing prevents that instance from being freed while its data is being read. This causes a use-after-free crash. Have the open of both those files take the trace_array reference via the trace_array_get() that prevents the trace_array from being freed while the files are opened. | ||||
| CVE-2026-90020 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: USB: gadget: fix NULL pointer dereference in gadget_dev_ioctl() gadget_dev_ioctl() reads dev->gadget before acquiring dev->lock, but dev->state is checked after acquiring the lock. Therefore a concurrent bind can change the device state between these operations, which can leave ioctl with a stale NULL gadget pointer and causing a NULL pointer dereference at gadget->ops->ioctl. Read dev->gadget while holding dev->lock so that the gadget pointer and device state are sampled consistently. | ||||
| CVE-2026-89946 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: ASoC: cs35l33: drain threaded IRQ before runtime suspend cs35l33_runtime_suspend() currently switches the codec into regcache_cache_only(true) and powers it down without first quiescing the threaded IRQ registered by devm_request_threaded_irq(). That leaves a window where cs35l33_irq_thread() can still run after suspend has closed off live register access. A running system can reach this during runtime PM while the driver still has critical fault IRQs unmasked. If the threaded handler runs in that window, it reads volatile INT_STATUS_1/2 after cache_only has been enabled, ignores the regmap_read() failures, and can still drive the AMP_SHORT_RLS, CAL_ERR_RLS, OTE_RLS, and OTW_RLS release paths. Use disable_irq() before entering cache_only/power-off so any in-flight threaded handler is drained and no new IRQ thread can run during the suspended state. Re-enable the IRQ only after runtime_resume() has restored live register access with regcache_sync(). Since probe only warns if devm_request_threaded_irq() fails, track whether the IRQ was actually installed before disabling or re-enabling it. | ||||
| CVE-2026-90034 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: usb: image: mdc800: change kmalloc() to kzalloc() Change the kmalloc() calls in usb_mdc800_init() for irq_urb_buffer and download_urb_buffer to kzalloc(), avoiding potential stack leaks if a shorter message is received in mdc800_usb_irq() and mdc800_usb_download_notify() | ||||
| CVE-2026-90035 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: drm/amd/display: fix division by zero in get_estimated_bw() get_estimated_bw() divides by link->dpia_bw_alloc_config.bw_granularity, which is zeroed by reset_bw_alloc_struct() and only populated once DP_TUNNELING_BW_ALLOC_CAP_CHANGED has been handled. link_dp_dpia_handle_bw_alloc_status(), the DPCD interrupt handler, calls get_estimated_bw() whenever DP_TUNNELING_ESTIMATED_BW_CHANGED is set, independently of whether DP_TUNNELING_BW_ALLOC_CAP_CHANGED has ever fired for that link. A connected USB4/DPIA tunneling device that reports an estimated-bandwidth change before ever reporting a capability change drives a division by zero in this IRQ path. link_dpia_send_bw_alloc_request() already guards the same bw_granularity division; add the identical guard here rather than introducing a new pattern. (cherry picked from commit f2a961457c33dc34223aad5c9e8971de34a4eed3) | ||||
| CVE-2026-90037 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 9.8 Critical |
| In the Linux kernel, the following vulnerability has been resolved: NFSD: Prevent client use-after-free during close_lru reaping An nfs4_openowner left on nn->close_lru after its final CLOSE keeps its last closed stateid in oo_last_closed_stid, holding only a raw pointer to its nfs4_client. The laundromat reaps timed-out entries, drops nn->client_lock, and calls nfs4_put_stid(), which dereferences the client through cl_lock. Nothing pins the client across that window, so a concurrent force_expire_client() can free it and nfs4_put_stid() reads freed memory. __destroy_client() hits the same race, walking clp->cl_openowners without cl_lock. Pin the client with cl_rpc_users before dropping client_lock, and skip clients already expiring. __destroy_client() then cleans up its own close_lru entries through release_last_closed_stateid(), so teardown no longer races the laundromat. | ||||
| CVE-2026-90039 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: NFSD: Guard admin state-revocation walks with NFSD_NET_UP Writing to /proc/fs/nfsd/unlock_filesystem, or sending the NFSD_CMD_UNLOCK_FILESYSTEM or NFSD_CMD_UNLOCK_EXPORT netlink command, walks the NFSv4 client hash tables to revoke open state and cancel async COPY operations. All three handlers gate that walk on nn->nfsd_serv, but a listener added via portlist or netlink listener_set sets nn->nfsd_serv before any nfsd thread starts. nfsd_startup_net() has not yet allocated nn->conf_id_hashtbl, so the walkers dereference a NULL table. A local administrator with CAP_SYS_ADMIN can crash the kernel this way without ever starting the server. nn->nfsd_serv is set when the service is created, which precedes table allocation. NFSD_NET_UP instead brackets the window where the tables are live: set at the end of nfsd_startup_net() and cleared in nfsd_shutdown_net() after they are freed, both under nfsd_mutex. Gating the three unlock paths on NFSD_NET_UP fixes the startup-time NULL dereference while preserving the earlier post-shutdown use-after-free fix. | ||||
| CVE-2026-90045 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: USB: gadget: ffs: fix mm lifetime handling io_data stores a pointer to the submitting task's mm_struct, but does not currently hold a reference to it while async requests are pending. This can result in a use-after-free if the task exits before completion handling finishes. Take a reference with mmgrab() when queuing the read request and release it with mmdrop() on request completion. | ||||
| CVE-2026-89958 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: s390/vfio-ap: Fix dereference matrix_mdev->kvm without checking for NULL The ap_driver structure has two fields which are function pointers to callbacks: * .on_config_changed: called at the start of the AP bus scan function to notify the device driver that the host AP configuration has changed and the associated AP devices will be added or removed accordingly. This gives the implementor a chance to evaluate the configuration changes and respond to them before the associated devices are added or removed. * .on_scan_complete: Called at the end of the AP bus scan function to notify the device driver that the host AP configuration has changed and the AP devices have been added or removed accordingly. This gives the implementor the opportunity to respond to the changes after the associated devices are added or removed. These two callbacks are implemented in the vfio_ap device driver via the vfio_ap_on_cfg_changed and vfio_ap_on_scan_complete functions respectively. Within the call stack of these two callback functions the matrix_mdev->kvm->lock mutex is taken without checking whether matrix_mdev->kvm is NULL or not. If matrix_mdev->kvm has never been set, trying to take the lock will trigger a NULL pointer dereference. This patch adds checks for matrix_mdev->kvm == NULL before taking the matrix_mdev->kvm->lock mutex. Note that the matrix_mdev->kvm->lock mutex taken in the vfio_ap_mdev_hot_plug_config function is moved to the calling function along with the matrix_dev->mdevs_lock which is needed there to access the fields of the matrix_mdev. It makes little sense to make the change the check for matrix_mdev->kvm there before taking the kvm->lock mutex only to have to move it out via another patch, so it is done in this patch. It is important to make note of the following: 1. The matrix_dev->guests_lock is acquired at the start of both callback functions. This ensures that matrix_mdev will not be removed via the vfio_ap_mdev_remove function because it too takes matrix_dev_guests_lock before removing the object; so, matrix_mdev will be available for the duration of the callback functions. 2. The matrix_dev->mdevs_lock mutex must be taken in order to access fields within the matrix_mdev structure 3. matrix_mdev->kvm->lock mutex must be taken before the matrix_dev->mdevs_lock to prevent a lockdep splat. 4: The kvm->lock must be held while plugging the guest's AP configuration into its SIE state description via the vfio_ap_mdev_update_guest_apcb function. 5. The vfio_ap_mdev_update_guest_apcb checks matrix_mdev->kvm to verify it is not NULL before doing the hot plug of the guest's AP configuration. | ||||
| CVE-2026-89960 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 8.8 High |
| In the Linux kernel, the following vulnerability has been resolved: s390/vfio-ap: fix stale pqap_hook pointer on error in vfio_ap_mdev_set_kvm() In vfio_ap_mdev_set_kvm(), kvm->arch.crypto.pqap_hook is set to &matrix_mdev->pqap_hook before the update locks are acquired and the mdev list is checked for a conflicting assignment. If another mdev is already attached to the same KVM instance, the function returns -EPERM without restoring the hook pointer, leaving kvm->arch.crypto.pqap_hook pointing at the failing matrix_mdev instead of the mdev that legitimately owns the KVM. Since matrix_mdev->kvm is never set on this error path, vfio_ap_mdev_unset_kvm() will not clean up the hook when matrix_mdev is later closed. If matrix_mdev is subsequently freed, any PQAP instruction executed by the guest will dereference the stale pointer through pqap_hook_rwsem, resulting in a use-after-free. Since kvm->arch.crypto.pqap_hook is only set in the vfio_ap_mdev_set_kvm() function and is cleared in the vfio_ap_mdev_unset_kvm() function, a check for 'kvm->arch.crypto.pqap_hook != NULL' is all that is needed to determine whether it belongs to another mdev. This will alleviate the need to iterate the matrix_dev->mdev_list list to see if the kvm object is assigned to another mdev.This was introduced in v3 to alleviate the need to take the mdevs_lock while iterating the list; however, this did not prevent a potential race condition. The pqap_hook_rwsem(write) is now performed inside get_update_locks_for_kvm(), which is updated to acquire pqap_hook_rwsem(write) between kvm->lock and mdevs_lock. This ordering is consistent with the PQAP intercept path, which acquires pqap_hook_rwsem in read mode while srcu is held under vcpu->mutex, establishing the dependency: kvm->lock -> vcpu->mutex -> srcu -> pqap_hook_rwsem(read). The pqap_hook_rwsem is now released inside the release_update_locks_for_kvm(), which is updated to release pqap_hook_rwsem(write) between mdevs_lock and kvm->lock. Additionally, kvm_put_kvm() in vfio_ap_mdev_unset_kvm() is moved after release_update_locks_for_kvm(). Previously it was called while kvm->lock was held; if it were ever the last reference, kvm_destroy_vm() would run under kvm->lock, which would deadlock. | ||||
| CVE-2026-89961 | 1 Linux | 1 Linux Kernel | 2026-09-18 | 7.8 High |
| In the Linux kernel, the following vulnerability has been resolved: powerpc/mm: fix wrong addr_pfn tracking in compound vmemmap population vmemmap_populate_compound_pages() uses addr_pfn to determine the PFN offset within a compound page and to decide whether the current vmemmap slot should be populated as a head page mapping or should reuse a tail page mapping. However, addr_pfn is advanced manually in parallel with addr. The loop itself progresses in vmemmap address space, so each PAGE_SIZE step in addr covers PAGE_SIZE / sizeof(struct page) struct page slots. Since addr_pfn is compared against nr_pages in data-PFN units, it should advance by the same number of PFNs. The existing manual increments do not match that and therefore do not reliably track the PFN corresponding to the current addr. As a result, pfn_offset can be computed from the wrong PFN and the code can make the head/tail decision for the wrong compound-page position. Fix this by deriving addr_pfn directly from the current vmemmap address instead of carrying it as loop state. | ||||
| CVE-2026-89962 | 1 Linux | 1 Linux Kernel | 2026-09-18 | N/A |
| In the Linux kernel, the following vulnerability has been resolved: powerpc/kexec_file: Prevent kexec range truncation Sashiko AI review pointed out the following issue. The __merge_memory_ranges() function incorrectly handles overlapping memory ranges when merging them. Although sort_memory_ranges() sorts all ranges by their start address in ascending order beforehand, the merge logic remains defective in two ways: 1. It compares the current range's start against the previous element (i-1) instead of the running target index (idx) 2. It unconditionally overwrites 'ranges[idx].end' with 'ranges[i].end'. This logic flaw leads to critical memory truncation when a larger memory range completely subsumes subsequent smaller ranges. For example, consider a sorted input array with three ranges: Range A (idx=0): [0x1000 - 0x9000] Range B (i=1): [0x2000 - 0x5000] (completely inside Range A) Range C (i=2): [0x6000 - 0x8000] (completely inside Range A) 1. When i=1 (Range B): ranges[1].start (0x2000) <= ranges[0].end + 1 (0x9001) is TRUE. The code executes: ranges[0].end = ranges[1].end, which erroneously shrinks Range A's end from 0x9000 down to 0x5000. 2. When i=2 (Range C): ranges[2].start (0x6000) <= ranges[1].end + 1 (0x5001) is FALSE. The code falls into the else block, creating a broken new range. As a result, valid memory fragments [0x5001 - 0x5fff] and [0x8001 - 0x9000] are completely lost from the kexec exclude lists, potentially allowing the crash kernel to overwrite active memory, causing data corruption or crashes. Fix this by ensuring the start of the current range is compared against the end of the active merged range (idx), and use max() to safely prevent the outer boundary from being truncated. | ||||