diff --git a/SOURCES/1198-netfilter-nf-tables-release-flowtable-after-rcu-grace-period.patch b/SOURCES/1198-netfilter-nf-tables-release-flowtable-after-rcu-grace-period.patch new file mode 100644 index 000000000..d8bd60438 --- /dev/null +++ b/SOURCES/1198-netfilter-nf-tables-release-flowtable-after-rcu-grace-period.patch @@ -0,0 +1,41 @@ +From d73f4b53aaaea4c95f245e491aa5eeb8a21874ce Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Tue, 17 Mar 2026 20:00:26 +0100 +Subject: [PATCH] netfilter: nf_tables: release flowtable after rcu grace + period on error + +Call synchronize_rcu() after unregistering the hooks from error path, +since a hook that already refers to this flowtable can be already +registered, exposing this flowtable to packet path and nfnetlink_hook +control plane. + +This error path is rare, it should only happen by reaching the maximum +number hooks or by failing to set up to hardware offload, just call +synchronize_rcu(). + +There is a check for already used device hooks by different flowtable +that could result in EEXIST at this late stage. The hook parser can be +updated to perform this check earlier to this error path really becomes +rarely exercised. + +Uncovered by KASAN reported as use-after-free from nfnetlink_hook path +when dumping hooks. + +Fixes: 3b49e2e94e6e ("netfilter: nf_tables: add flow table netlink frontend") +Reported-by: Yiming Qian +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal + + +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 3193d8c..9b55eaa 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -8411,6 +8411,7 @@ static int nf_tables_newflowtable(struct sk_buff *skb, + return 0; + + err_flowtable_hooks: ++ synchronize_rcu(); + nft_trans_destroy(trans); + err_flowtable_trans: + nft_flowtable_hooks_destroy(&flowtable->hook_list); diff --git a/SOURCES/1199-revert-mm-pcp-increase-pcp-free-count-threshold-to-trigger-f.patch b/SOURCES/1199-revert-mm-pcp-increase-pcp-free-count-threshold-to-trigger-f.patch new file mode 100644 index 000000000..ba60fde86 --- /dev/null +++ b/SOURCES/1199-revert-mm-pcp-increase-pcp-free-count-threshold-to-trigger-f.patch @@ -0,0 +1,19 @@ +From: AlmaLinux backport +Subject: [PATCH] Revert "mm: pcp: increase pcp->free_count threshold to trigger free_high" +# Revert of e1beaf0b7811188ccf1cf6df3fe6bf95c186873a + mm: pcp: increase pcp->free_count threshold to trigger free_high + + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 4e8615398f07..b0edd4934a16 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -2476,7 +2476,7 @@ static void free_unref_page_commit(struct zone *zone, struct per_cpu_pages *pcp, + * stops will be drained from vmstat refresh context. + */ + if (order && order <= PAGE_ALLOC_COSTLY_ORDER) { +- free_high = (pcp->free_count >= (batch + pcp->high_min / 2) && ++ free_high = (pcp->free_count >= batch && + (pcp->flags & PCPF_PREV_FREE_HIGH_ORDER) && + (!(pcp->flags & PCPF_FREE_HIGH_BATCH) || + pcp->count >= batch)); diff --git a/SOURCES/1200-ice-fix-missing-tx-timestamps-interrupts-on-e825-devices.patch b/SOURCES/1200-ice-fix-missing-tx-timestamps-interrupts-on-e825-devices.patch new file mode 100644 index 000000000..f8df58930 --- /dev/null +++ b/SOURCES/1200-ice-fix-missing-tx-timestamps-interrupts-on-e825-devices.patch @@ -0,0 +1,66 @@ +From 99854c167cfc113ad863832b1601c4ca1a639cfe Mon Sep 17 00:00:00 2001 +From: Grzegorz Nitka +Date: Thu, 27 Nov 2025 10:25:58 +0100 +Subject: [PATCH] ice: fix missing TX timestamps interrupts on E825 devices + +Modify PTP (Precision Time Protocol) configuration on link down flow. +Previously, PHY_REG_TX_OFFSET_READY register was cleared in such case. +This register is used to determine if the timestamp is valid or not on +the hardware side. +However, there is a possibility that there is still the packet in the +HW queue which originally was supposed to be timestamped but the link +is already down and given register is cleared. +This potentially might lead to the situation in which that 'delayed' +packet's timestamp is treated as invalid one when the link is up +again. +This in turn leads to the situation in which the driver is not able to +effectively clean timestamp memory and interrupt configuration. +From the hardware perspective, that 'old' interrupt was not handled +properly and even if new timestamp packets are processed, no new +interrupts is generated. As a result, providing timestamps to the user +applications (like ptp4l) is not possible. +The solution for this problem is implemented at the driver level rather +than the firmware, and maintains the tx_ready bit high, even during +link down events. This avoids entering a potential inconsistent state +between the driver and the timestamp hardware. + +Testing hints: +- run PTP traffic at higher rate (like 16 PTP messages per second) +- observe ptp4l behaviour at the client side in the following + conditions: + a) trigger link toggle events. It needs to be physiscal + link down/up events + b) link speed change +In all above cases, PTP processing at ptp4l application should resume +always. In failure case, the following permanent error message in ptp4l +log was observed: +controller-0 ptp4l: err [6175.116] ptp4l-legacy timed out while polling + for tx timestamp + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Reviewed-by: Aleksandr Loktionov +Signed-off-by: Grzegorz Nitka +Tested-by: Sunitha Mekala (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index 4c8d20f2d2c0..0b7c2a13ab04 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -1347,9 +1347,12 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup) + /* Do not reconfigure E810 or E830 PHY */ + return; + case ICE_MAC_GENERIC: +- case ICE_MAC_GENERIC_3K_E825: + ice_ptp_port_phy_restart(ptp_port); + return; ++ case ICE_MAC_GENERIC_3K_E825: ++ if (linkup) ++ ice_ptp_port_phy_restart(ptp_port); ++ return; + default: + dev_warn(ice_pf_to_dev(pf), "%s: Unknown PHY type\n", __func__); + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1201-ice-fix-ptp-timestamping-broken-by-synce-code-on-e825c.patch b/SOURCES/1201-ice-fix-ptp-timestamping-broken-by-synce-code-on-e825c.patch new file mode 100644 index 000000000..1dc874348 --- /dev/null +++ b/SOURCES/1201-ice-fix-ptp-timestamping-broken-by-synce-code-on-e825c.patch @@ -0,0 +1,88 @@ +From bf6dbadb72b997721e9b67348652926c076878d1 Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Fri, 27 Mar 2026 08:46:58 +0100 +Subject: [PATCH] ice: fix PTP timestamping broken by SyncE code on E825C + +The E825C SyncE support added in commit ad1df4f2d591 ("ice: dpll: +Support E825-C SyncE and dynamic pin discovery") introduced a SyncE +reconfiguration block in ice_ptp_link_change() that prevents +ice_ptp_port_phy_restart() from being called in several error paths. +Without the PHY restart, PTP timestamps stop working after any link +change event. + +There are three ways the PHY restart gets blocked: + +1. When DPLL initialization fails (e.g. missing ACPI firmware node + properties), ICE_FLAG_DPLL is not set and the function returns early + before reaching the PHY restart. + +2. When ice_tspll_bypass_mux_active_e825c() fails to read the CGU + register, WARN_ON_ONCE fires and the function returns early. + +3. When ice_tspll_cfg_synce_ethdiv_e825c() fails to configure the + clock divider for an active pin, same early return. + +SyncE and PTP are independent features. SyncE reconfiguration failures +must not prevent the PTP PHY restart that is essential for timestamp +recovery after link changes. + +Fix by making the entire SyncE block conditional on ICE_FLAG_DPLL +without an early return, and replacing the WARN_ON_ONCE + return error +handling inside the loop with dev_err_once + break. The function always +proceeds to ice_ptp_port_phy_restart() regardless of SyncE errors. + +Fixes: ad1df4f2d591 ("ice: dpll: Support E825-C SyncE and dynamic pin discovery") +Signed-off-by: Petr Oros +Reviewed-by: Grzegorz Nitka +Reviewed-by: Aleksandr Loktionov +Tested-by: Sunitha Mekala (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index a3c5f0a5e09b..6cb0cf7a9891 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -1296,12 +1296,10 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup) + if (pf->hw.reset_ongoing) + return; + +- if (hw->mac_type == ICE_MAC_GENERIC_3K_E825) { ++ if (hw->mac_type == ICE_MAC_GENERIC_3K_E825 && ++ test_bit(ICE_FLAG_DPLL, pf->flags)) { + int pin, err; + +- if (!test_bit(ICE_FLAG_DPLL, pf->flags)) +- return; +- + mutex_lock(&pf->dplls.lock); + for (pin = 0; pin < ICE_SYNCE_CLK_NUM; pin++) { + enum ice_synce_clk clk_pin; +@@ -1314,15 +1312,19 @@ void ice_ptp_link_change(struct ice_pf *pf, bool linkup) + port_num, + &active, + clk_pin); +- if (WARN_ON_ONCE(err)) { +- mutex_unlock(&pf->dplls.lock); +- return; ++ if (err) { ++ dev_err_once(ice_pf_to_dev(pf), ++ "Failed to read SyncE bypass mux for pin %d, err %d\n", ++ pin, err); ++ break; + } + + err = ice_tspll_cfg_synce_ethdiv_e825c(hw, clk_pin); +- if (active && WARN_ON_ONCE(err)) { +- mutex_unlock(&pf->dplls.lock); +- return; ++ if (active && err) { ++ dev_err_once(ice_pf_to_dev(pf), ++ "Failed to configure SyncE ETH divider for pin %d, err %d\n", ++ pin, err); ++ break; + } + } + mutex_unlock(&pf->dplls.lock); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1202-i2c-i801-revert-i2c-i801-replace-acpi-lock-with-i2c-bus-lock.patch b/SOURCES/1202-i2c-i801-revert-i2c-i801-replace-acpi-lock-with-i2c-bus-lock.patch new file mode 100644 index 000000000..e6982615b --- /dev/null +++ b/SOURCES/1202-i2c-i801-revert-i2c-i801-replace-acpi-lock-with-i2c-bus-lock.patch @@ -0,0 +1,168 @@ +From b1dd99bdb35ac4c66c8d7ac288d963b2ad952b5b Mon Sep 17 00:00:00 2001 +From: David Arcari +Date: Mon, 9 Mar 2026 07:47:07 -0400 +Subject: [PATCH] i2c: i801: Revert "i2c: i801: replace acpi_lock with I2C bus + lock" + +JIRA: https://issues.redhat.com/browse/RHEL-153431 +Conflicts: RHEL pm routines differ from upstream + +commit cfc69c2e6c699c96949f7b0455195b0bfb7dc715 +Author: Charles Haithcock +Date: Fri Feb 27 18:41:15 2026 -0700 + + i2c: i801: Revert "i2c: i801: replace acpi_lock with I2C bus lock" + + This reverts commit f707d6b9e7c18f669adfdb443906d46cfbaaa0c1. + + Under rare circumstances, multiple udev threads can collect i801 device + info on boot and walk i801_acpi_io_handler somewhat concurrently. The + first will note the area is reserved by acpi to prevent further touches. + This ultimately causes the area to be deregistered. The second will + enter i801_acpi_io_handler after the area is unregistered but before a + check can be made that the area is unregistered. i2c_lock_bus relies on + the now unregistered area containing lock_ops to lock the bus. The end + result is a kernel panic on boot with the following backtrace; + + [ 14.971872] ioatdma 0000:09:00.2: enabling device (0100 -> 0102) + [ 14.971873] BUG: kernel NULL pointer dereference, address: 0000000000000000 + [ 14.971880] #PF: supervisor read access in kernel mode + [ 14.971884] #PF: error_code(0x0000) - not-present page + [ 14.971887] PGD 0 P4D 0 + [ 14.971894] Oops: 0000 [#1] PREEMPT SMP PTI + [ 14.971900] CPU: 5 PID: 956 Comm: systemd-udevd Not tainted 5.14.0-611.5.1.el9_7.x86_64 #1 + [ 14.971905] Hardware name: XXXXXXXXXXXXXXXXXXXXXXX BIOS 1.20.10.SV91 01/30/2023 + [ 14.971908] RIP: 0010:i801_acpi_io_handler+0x2d/0xb0 [i2c_i801] + [ 14.971929] Code: 00 00 49 8b 40 20 41 57 41 56 4d 8b b8 30 04 00 00 49 89 ce 41 55 41 89 d5 41 54 49 89 f4 be 02 00 00 00 55 4c 89 c5 53 89 fb <48> 8b 00 4c 89 c7 e8 18 61 54 e9 80 bd 80 04 00 00 00 75 09 4c 3b + [ 14.971933] RSP: 0018:ffffbaa841483838 EFLAGS: 00010282 + [ 14.971938] RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff9685e01ba568 + [ 14.971941] RDX: 0000000000000008 RSI: 0000000000000002 RDI: 0000000000000000 + [ 14.971944] RBP: ffff9685ca22f028 R08: ffff9685ca22f028 R09: ffff9685ca22f028 + [ 14.971948] R10: 000000000000000b R11: 0000000000000580 R12: 0000000000000580 + [ 14.971951] R13: 0000000000000008 R14: ffff9685e01ba568 R15: ffff9685c222f000 + [ 14.971954] FS: 00007f8287c0ab40(0000) GS:ffff96a47f940000(0000) knlGS:0000000000000000 + [ 14.971959] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + [ 14.971963] CR2: 0000000000000000 CR3: 0000000168090001 CR4: 00000000003706f0 + [ 14.971966] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + [ 14.971968] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + [ 14.971972] Call Trace: + [ 14.971977] + [ 14.971981] ? show_trace_log_lvl+0x1c4/0x2df + [ 14.971994] ? show_trace_log_lvl+0x1c4/0x2df + [ 14.972003] ? acpi_ev_address_space_dispatch+0x16e/0x3c0 + [ 14.972014] ? __die_body.cold+0x8/0xd + [ 14.972021] ? page_fault_oops+0x132/0x170 + [ 14.972028] ? exc_page_fault+0x61/0x150 + [ 14.972036] ? asm_exc_page_fault+0x22/0x30 + [ 14.972045] ? i801_acpi_io_handler+0x2d/0xb0 [i2c_i801] + [ 14.972061] acpi_ev_address_space_dispatch+0x16e/0x3c0 + [ 14.972069] ? __pfx_i801_acpi_io_handler+0x10/0x10 [i2c_i801] + [ 14.972085] acpi_ex_access_region+0x5b/0xd0 + [ 14.972093] acpi_ex_field_datum_io+0x73/0x2e0 + [ 14.972100] acpi_ex_read_data_from_field+0x8e/0x230 + [ 14.972106] acpi_ex_resolve_node_to_value+0x23d/0x310 + [ 14.972114] acpi_ds_evaluate_name_path+0xad/0x110 + [ 14.972121] acpi_ds_exec_end_op+0x321/0x510 + [ 14.972127] acpi_ps_parse_loop+0xf7/0x680 + [ 14.972136] acpi_ps_parse_aml+0x17a/0x3d0 + [ 14.972143] acpi_ps_execute_method+0x137/0x270 + [ 14.972150] acpi_ns_evaluate+0x1f4/0x2e0 + [ 14.972158] acpi_evaluate_object+0x134/0x2f0 + [ 14.972164] acpi_evaluate_integer+0x50/0xe0 + [ 14.972173] ? vsnprintf+0x24b/0x570 + [ 14.972181] acpi_ac_get_state.part.0+0x23/0x70 + [ 14.972189] get_ac_property+0x4e/0x60 + [ 14.972195] power_supply_show_property+0x90/0x1f0 + [ 14.972205] add_prop_uevent+0x29/0x90 + [ 14.972213] power_supply_uevent+0x109/0x1d0 + [ 14.972222] dev_uevent+0x10e/0x2f0 + [ 14.972228] uevent_show+0x8e/0x100 + [ 14.972236] dev_attr_show+0x19/0x40 + [ 14.972246] sysfs_kf_seq_show+0x9b/0x100 + [ 14.972253] seq_read_iter+0x120/0x4b0 + [ 14.972262] ? selinux_file_permission+0x106/0x150 + [ 14.972273] vfs_read+0x24f/0x3a0 + [ 14.972284] ksys_read+0x5f/0xe0 + [ 14.972291] do_syscall_64+0x5f/0xe0 + ... + + The kernel panic is mitigated by setting limiting the count of udev + children to 1. Revert to using the acpi_lock to continue protecting + marking the area as owned by firmware without relying on a lock in + a potentially unmapped region of memory. + + Fixes: f707d6b9e7c1 ("i2c: i801: replace acpi_lock with I2C bus lock") + Signed-off-by: Charles Haithcock + [wsa: added Fixes-tag and updated comment stating the importance of the lock] + Signed-off-by: Wolfram Sang + +(cherry picked from commit cfc69c2e6c699c96949f7b0455195b0bfb7dc715) +Assisted-by: Patchpal +Signed-off-by: David Arcari + +diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c +index 171d29d2770e..b6a32c7c4a50 100644 +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -303,9 +303,10 @@ struct i801_priv { + + /* + * If set to true the host controller registers are reserved for +- * ACPI AML use. ++ * ACPI AML use. Needs extra protection by acpi_lock. + */ + bool acpi_reserved; ++ struct mutex acpi_lock; + }; + + #define FEATURE_SMBUS_PEC BIT(0) +@@ -893,8 +894,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, + int hwpec, ret; + struct i801_priv *priv = i2c_get_adapdata(adap); + +- if (priv->acpi_reserved) ++ mutex_lock(&priv->acpi_lock); ++ if (priv->acpi_reserved) { ++ mutex_unlock(&priv->acpi_lock); + return -EBUSY; ++ } + + pm_runtime_get_sync(&priv->pci_dev->dev); + +@@ -935,6 +939,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, + + pm_runtime_mark_last_busy(&priv->pci_dev->dev); + pm_runtime_put_autosuspend(&priv->pci_dev->dev); ++ mutex_unlock(&priv->acpi_lock); + return ret; + } + +@@ -1462,7 +1467,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits, + * further access from the driver itself. This device is now owned + * by the system firmware. + */ +- i2c_lock_bus(&priv->adapter, I2C_LOCK_SEGMENT); ++ mutex_lock(&priv->acpi_lock); + + if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) { + priv->acpi_reserved = true; +@@ -1482,7 +1487,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits, + else + status = acpi_os_write_port(address, (u32)*value, bits); + +- i2c_unlock_bus(&priv->adapter, I2C_LOCK_SEGMENT); ++ mutex_unlock(&priv->acpi_lock); + + return status; + } +@@ -1542,6 +1547,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) + priv->adapter.dev.parent = &dev->dev; + acpi_use_parent_companion(&priv->adapter.dev); + priv->adapter.retries = 3; ++ mutex_init(&priv->acpi_lock); + + priv->pci_dev = dev; + priv->features = id->driver_data; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1203-ima-don-t-clear-ima-digsig-flag-when-setting-or-removing-non.patch b/SOURCES/1203-ima-don-t-clear-ima-digsig-flag-when-setting-or-removing-non.patch new file mode 100644 index 000000000..90ef9f1b3 --- /dev/null +++ b/SOURCES/1203-ima-don-t-clear-ima-digsig-flag-when-setting-or-removing-non.patch @@ -0,0 +1,158 @@ +From 8c73bd1f496786efe542e894103b8abcc65c98a3 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Tue, 21 Apr 2026 09:53:43 +0000 +Subject: [PATCH] ima: don't clear IMA_DIGSIG flag when setting or removing + non-IMA xattr + +JIRA: https://redhat.atlassian.net/browse/RHEL-169733 +CVE: CVE-2025-68183 + +commit 88b4cbcf6b041ae0f2fc8a34554a5b6a83a2b7cd +Author: Coiby Xu +Date: Mon Sep 15 13:55:23 2025 +0800 + + ima: don't clear IMA_DIGSIG flag when setting or removing non-IMA xattr + + Currently when both IMA and EVM are in fix mode, the IMA signature will + be reset to IMA hash if a program first stores IMA signature in + security.ima and then writes/removes some other security xattr for the + file. + + For example, on Fedora, after booting the kernel with "ima_appraise=fix + evm=fix ima_policy=appraise_tcb" and installing rpm-plugin-ima, + installing/reinstalling a package will not make good reference IMA + signature generated. Instead IMA hash is generated, + + # getfattr -m - -d -e hex /usr/bin/bash + # file: usr/bin/bash + security.ima=0x0404... + + This happens because when setting security.selinux, the IMA_DIGSIG flag + that had been set early was cleared. As a result, IMA hash is generated + when the file is closed. + + Similarly, IMA signature can be cleared on file close after removing + security xattr like security.evm or setting/removing ACL. + + Prevent replacing the IMA file signature with a file hash, by preventing + the IMA_DIGSIG flag from being reset. + + Here's a minimal C reproducer which sets security.selinux as the last + step which can also replaced by removing security.evm or setting ACL, + + #include + #include + #include + #include + #include + #include + + int main() { + const char* file_path = "/usr/sbin/test_binary"; + const char* hex_string = "030204d33204490066306402304"; + int length = strlen(hex_string); + char* ima_attr_value; + int fd; + + fd = open(file_path, O_WRONLY|O_CREAT|O_EXCL, 0644); + if (fd == -1) { + perror("Error opening file"); + return 1; + } + + ima_attr_value = (char*)malloc(length / 2 ); + for (int i = 0, j = 0; i < length; i += 2, j++) { + sscanf(hex_string + i, "%2hhx", &ima_attr_value[j]); + } + + if (fsetxattr(fd, "security.ima", ima_attr_value, length/2, 0) == -1) { + perror("Error setting extended attribute"); + close(fd); + return 1; + } + + const char* selinux_value= "system_u:object_r:bin_t:s0"; + if (fsetxattr(fd, "security.selinux", selinux_value, strlen(selinux_value), 0) == -1) { + perror("Error setting extended attribute"); + close(fd); + return 1; + } + + close(fd); + + return 0; + } + + Signed-off-by: Coiby Xu + Signed-off-by: Mimi Zohar + +Signed-off-by: CKI Backport Bot + +diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c +index 4d88e03381b7..146268b88506 100644 +--- a/security/integrity/ima/ima_appraise.c ++++ b/security/integrity/ima/ima_appraise.c +@@ -560,6 +560,15 @@ static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name, + return 0; + } + ++/* ++ * ima_reset_appraise_flags - reset ima_iint_cache flags ++ * ++ * @digsig: whether to clear/set IMA_DIGSIG flag, tristate values ++ * 0: clear IMA_DIGSIG ++ * 1: set IMA_DIGSIG ++ * -1: don't change IMA_DIGSIG ++ * ++ */ + static void ima_reset_appraise_flags(struct inode *inode, int digsig) + { + struct integrity_iint_cache *iint; +@@ -572,9 +581,9 @@ static void ima_reset_appraise_flags(struct inode *inode, int digsig) + return; + iint->measured_pcrs = 0; + set_bit(IMA_CHANGE_XATTR, &iint->atomic_flags); +- if (digsig) ++ if (digsig == 1) + set_bit(IMA_DIGSIG, &iint->atomic_flags); +- else ++ else if (digsig == 0) + clear_bit(IMA_DIGSIG, &iint->atomic_flags); + } + +@@ -653,6 +662,8 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, + digsig = (xvalue->type == EVM_IMA_XATTR_DIGSIG); + } else if (!strcmp(xattr_name, XATTR_NAME_EVM) && xattr_value_len > 0) { + digsig = (xvalue->type == EVM_XATTR_PORTABLE_DIGSIG); ++ } else { ++ digsig = -1; + } + if (result == 1 || evm_revalidate_status(xattr_name)) { + result = validate_hash_algo(dentry, xvalue, xattr_value_len); +@@ -668,18 +679,20 @@ int ima_inode_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, + const char *acl_name, struct posix_acl *kacl) + { + if (evm_revalidate_status(acl_name)) +- ima_reset_appraise_flags(d_backing_inode(dentry), 0); ++ ima_reset_appraise_flags(d_backing_inode(dentry), -1); + + return 0; + } + + int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name) + { +- int result; ++ int result, digsig = -1; + + result = ima_protect_xattr(dentry, xattr_name, NULL, 0); + if (result == 1 || evm_revalidate_status(xattr_name)) { +- ima_reset_appraise_flags(d_backing_inode(dentry), 0); ++ if (!strcmp(xattr_name, XATTR_NAME_IMA)) ++ digsig = 0; ++ ima_reset_appraise_flags(d_backing_inode(dentry), digsig); + if (result == 1) + result = 0; + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1204-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch b/SOURCES/1204-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch new file mode 100644 index 000000000..bc8361aad --- /dev/null +++ b/SOURCES/1204-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch @@ -0,0 +1,66 @@ +From fb6ad4c7fd0157cbec8e80b5c2b2dde88074ae50 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Mon, 20 Apr 2026 15:22:22 +0000 +Subject: [PATCH] crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +JIRA: https://redhat.atlassian.net/browse/RHEL-169569 +CVE: CVE-2025-68724 + +commit df0845cf447ae1556c3440b8b155de0926cbaa56 +Author: Thorsten Blum +Date: Mon Oct 13 13:40:10 2025 +0200 + + crypto: asymmetric_keys - prevent overflow in asymmetric_key_generate_id + + Use check_add_overflow() to guard against potential integer overflows + when adding the binary blob lengths and the size of an asymmetric_key_id + structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a + possible buffer overflow when copying data from potentially malicious + X.509 certificate fields that can be arbitrarily large, such as ASN.1 + INTEGER serial numbers, issuer names, etc. + + Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") + Signed-off-by: Thorsten Blum + Reviewed-by: Lukas Wunner + Signed-off-by: Herbert Xu + +Signed-off-by: CKI Backport Bot + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index ad8af3d70ac0..2e3fa520d6eb 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -138,12 +139,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1205-netfilter-nf-conntrack-h323-check-for-zero-length-in-decodeq.patch b/SOURCES/1205-netfilter-nf-conntrack-h323-check-for-zero-length-in-decodeq.patch new file mode 100644 index 000000000..eef18f407 --- /dev/null +++ b/SOURCES/1205-netfilter-nf-conntrack-h323-check-for-zero-length-in-decodeq.patch @@ -0,0 +1,51 @@ +From 1aa4308d3a0b90f0bc449955df468b5adab7f2b0 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 25 Mar 2026 08:48:42 +0100 +Subject: [PATCH] netfilter: nf_conntrack_h323: check for zero length in + DecodeQ931() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +JIRA: https://issues.redhat.com/browse/RHEL-152685 +Upstream Status: commit f173d0f4c0f6 + +commit f173d0f4c0f689173f8cdac79991043a4a89bf66 +Author: Jenny Guanni Qu +Date: Thu Mar 12 14:49:50 2026 +0000 + + netfilter: nf_conntrack_h323: check for zero length in DecodeQ931() + + In DecodeQ931(), the UserUserIE code path reads a 16-bit length from + the packet, then decrements it by 1 to skip the protocol discriminator + byte before passing it to DecodeH323_UserInformation(). If the encoded + length is 0, the decrement wraps to -1, which is then passed as a + large value to the decoder, leading to an out-of-bounds read. + + Add a check to ensure len is positive after the decrement. + + Fixes: 5e35941d9901 ("[NETFILTER]: Add H.323 conntrack/NAT helper") + Reported-by: Klaudia Kloc + Reported-by: Dawid Moczadło + Tested-by: Jenny Guanni Qu + Signed-off-by: Jenny Guanni Qu + Signed-off-by: Florian Westphal + +Signed-off-by: Florian Westphal + +diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c +index c972e9488e16..7b1497ed97d2 100644 +--- a/net/netfilter/nf_conntrack_h323_asn1.c ++++ b/net/netfilter/nf_conntrack_h323_asn1.c +@@ -924,6 +924,8 @@ int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931) + break; + p++; + len--; ++ if (len <= 0) ++ break; + return DecodeH323_UserInformation(buf, p, len, + &q931->UUIE); + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1206-iommu-sva-add-kernel-page-table-iotlb-flush-notification.patch b/SOURCES/1206-iommu-sva-add-kernel-page-table-iotlb-flush-notification.patch new file mode 100644 index 000000000..47e6448bb --- /dev/null +++ b/SOURCES/1206-iommu-sva-add-kernel-page-table-iotlb-flush-notification.patch @@ -0,0 +1,255 @@ +From 7a48597b69032ea60c54f1ffd5083248ef2b7572 Mon Sep 17 00:00:00 2001 +From: Jerry Snitselaar +Date: Mon, 30 Mar 2026 02:41:55 +0000 +Subject: [PATCH] iommu/sva: add kernel page table IOTLB flush notification + +JIRA: https://issues.redhat.com/browse/RHEL-148781 +Upstream-Status: RHEL only +CVE: CVE-2025-71089 + +When IOMMU SVA is active, the IOMMU shares the CPU's page tables and +caches intermediate page table walk results. When kernel page table +directory pages are freed and reallocated, the IOMMU's cache retains +stale references, allowing DMA translations through arbitrary data +interpreted as page table entries. + +The upstream fix (merged in v6.19 via mm.git) introduces ptdesc-based +deferred kernel page table freeing, which is not feasible to backport +to RHEL9 due to the absence of the required mm infrastructure. + +Instead, add SVA mm tracking so that iommu_sva_invalidate_kva_range() +can iterate all mm_structs with active SVA bindings and trigger +PASID-global IOTLB flushes via +mmu_notifier_arch_invalidate_secondary_tlbs(). IOMMU drivers already +register arch_invalidate_secondary_tlbs callbacks that perform the +flush. The fast path (no SVA active) is a single atomic_read(). + +The mm tracking is hooked into iommu_sva_bind_device() and +iommu_sva_unbind_device(), covering all SVA consumers through +the generic SVA layer. + +The tracked mm list uses RCU-protected iteration on the read side, +allowing iommu_sva_invalidate_kva_range() to iterate without holding +a spinlock across hardware IOTLB flush busy-waits. Writers (bind/ +unbind) use a spinlock for mutual exclusion with list_add_rcu() and +list_del_rcu(), and kfree_rcu() defers freeing until after a grace +period. + +mmput_async() is used instead of mmput() because the flush path can +be called under rcu_read_lock() or from contexts where sleeping is +not permitted (e.g., CPA path under cpa_lock spinlock). + +iommu_sva_track_mm() returns -ENOMEM on allocation failure, causing +the SVA bind to fail cleanly rather than silently skipping IOTLB +flush tracking. + +Assisted-by: Claude:claude-opus-4-6 +Signed-off-by: Jerry Snitselaar + +diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c +index 1a51cfd82808..f2267d22af1f 100644 +--- a/drivers/iommu/iommu-sva.c ++++ b/drivers/iommu/iommu-sva.c +@@ -6,12 +6,21 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + + #include "iommu-priv.h" + + static DEFINE_MUTEX(iommu_sva_lock); + static struct iommu_domain *iommu_sva_domain_alloc(struct device *dev, + struct mm_struct *mm); ++static int iommu_sva_track_mm(struct mm_struct *mm); ++static void iommu_sva_untrack_mm(struct mm_struct *mm); + + /* Allocate a PASID for the mm within range (inclusive) */ + static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct device *dev) +@@ -136,10 +145,20 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm + + out: + refcount_set(&handle->users, 1); ++ ret = iommu_sva_track_mm(mm); ++ if (ret) ++ goto out_unwind; + mutex_unlock(&iommu_sva_lock); + handle->dev = dev; + return handle; + ++out_unwind: ++ iommu_detach_device_pasid(domain, dev, iommu_mm->pasid); ++ if (--domain->users == 0) { ++ list_del(&domain->next); ++ iommu_domain_free(domain); ++ } ++ goto out_free_handle; + out_free_domain: + iommu_domain_free(domain); + out_free_handle: +@@ -170,6 +189,7 @@ void iommu_sva_unbind_device(struct iommu_sva *handle) + return; + } + ++ iommu_sva_untrack_mm(domain->mm); + iommu_detach_device_pasid(domain, dev, iommu_mm->pasid); + if (--domain->users == 0) { + list_del(&domain->next); +@@ -312,3 +332,127 @@ static struct iommu_domain *iommu_sva_domain_alloc(struct device *dev, + + return domain; + } ++ ++/* ++ * Track mm_structs with active SVA bindings so we can flush IOMMU ++ * cached translations when kernel page table pages are freed. ++ */ ++struct sva_mm { ++ struct mm_struct *mm; ++ struct list_head list; ++ struct rcu_head rcu; ++ int refcount; ++}; ++ ++static DEFINE_SPINLOCK(sva_mm_lock); ++static LIST_HEAD(sva_mm_list); ++static atomic_t sva_mm_count = ATOMIC_INIT(0); ++ ++/** ++ * iommu_sva_track_mm - Start tracking an mm for kernel PT change notification ++ * @mm: the mm_struct to track ++ * ++ * Called when SVA is bound for this mm. If the mm is already tracked, ++ * increments the refcount. Otherwise allocates a new tracking entry. ++ * ++ * Returns 0 on success, -ENOMEM on allocation failure. ++ */ ++static int iommu_sva_track_mm(struct mm_struct *mm) ++{ ++ struct sva_mm *smm; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sva_mm_lock, flags); ++ list_for_each_entry(smm, &sva_mm_list, list) { ++ if (smm->mm == mm) { ++ smm->refcount++; ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ return 0; ++ } ++ } ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ ++ smm = kzalloc(sizeof(*smm), GFP_KERNEL); ++ if (!smm) ++ return -ENOMEM; ++ ++ smm->mm = mm; ++ smm->refcount = 1; ++ ++ spin_lock_irqsave(&sva_mm_lock, flags); ++ { ++ struct sva_mm *existing; ++ ++ list_for_each_entry(existing, &sva_mm_list, list) { ++ if (existing->mm == mm) { ++ existing->refcount++; ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ kfree(smm); ++ return 0; ++ } ++ } ++ } ++ list_add_rcu(&smm->list, &sva_mm_list); ++ atomic_inc(&sva_mm_count); ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ return 0; ++} ++ ++/** ++ * iommu_sva_untrack_mm - Stop tracking an mm for kernel PT change notification ++ * @mm: the mm_struct to untrack ++ * ++ * Called when SVA is unbound for this mm. Decrements the refcount and ++ * removes the tracking entry when it reaches zero. ++ */ ++static void iommu_sva_untrack_mm(struct mm_struct *mm) ++{ ++ struct sva_mm *smm; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sva_mm_lock, flags); ++ list_for_each_entry(smm, &sva_mm_list, list) { ++ if (smm->mm == mm) { ++ if (--smm->refcount == 0) { ++ list_del_rcu(&smm->list); ++ atomic_dec(&sva_mm_count); ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ kfree_rcu(smm, rcu); ++ return; ++ } ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ return; ++ } ++ } ++ spin_unlock_irqrestore(&sva_mm_lock, flags); ++ WARN(1, "iommu_sva_untrack_mm: mm %px not found\n", mm); ++} ++ ++/** ++ * iommu_sva_invalidate_kva_range - Flush IOMMU caches before kernel PT free ++ * @start: Start of kernel virtual address range ++ * @end: End of kernel virtual address range ++ * ++ * Called from x86 mm code before freeing kernel page table pages. ++ * Iterates all tracked SVA-bound mm_structs and calls ++ * mmu_notifier_arch_invalidate_secondary_tlbs() for each, triggering ++ * IOTLB flushes via the drivers' invalidate_range callbacks. ++ * ++ * Fast path: atomic_read() returns 0 when no SVA is active. ++ */ ++void iommu_sva_invalidate_kva_range(unsigned long start, unsigned long end) ++{ ++ struct sva_mm *smm; ++ ++ if (!atomic_read(&sva_mm_count)) ++ return; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(smm, &sva_mm_list, list) { ++ if (mmget_not_zero(smm->mm)) { ++ mmu_notifier_arch_invalidate_secondary_tlbs(smm->mm, start, end); ++ mmput_async(smm->mm); ++ } ++ } ++ rcu_read_unlock(); ++} +diff --git a/include/linux/iommu.h b/include/linux/iommu.h +index c30d12e16473..cf266c0e4f73 100644 +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -1615,6 +1615,7 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, + struct mm_struct *mm); + void iommu_sva_unbind_device(struct iommu_sva *handle); + u32 iommu_sva_get_pasid(struct iommu_sva *handle); ++void iommu_sva_invalidate_kva_range(unsigned long start, unsigned long end); + #else + static inline struct iommu_sva * + iommu_sva_bind_device(struct device *dev, struct mm_struct *mm) +@@ -1630,6 +1631,8 @@ static inline u32 iommu_sva_get_pasid(struct iommu_sva *handle) + { + return IOMMU_PASID_INVALID; + } ++static inline void iommu_sva_invalidate_kva_range(unsigned long start, ++ unsigned long end) {} + static inline void mm_pasid_init(struct mm_struct *mm) {} + static inline bool mm_valid_pasid(struct mm_struct *mm) { return false; } + +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1207-x86-mm-flush-iommu-before-freeing-kernel-page-table-pages.patch b/SOURCES/1207-x86-mm-flush-iommu-before-freeing-kernel-page-table-pages.patch new file mode 100644 index 000000000..52a798545 --- /dev/null +++ b/SOURCES/1207-x86-mm-flush-iommu-before-freeing-kernel-page-table-pages.patch @@ -0,0 +1,119 @@ +From 51cb4cded7ea7ed2f5a1ae74ceb7ae0275bd9d53 Mon Sep 17 00:00:00 2001 +From: Jerry Snitselaar +Date: Mon, 30 Mar 2026 02:43:11 +0000 +Subject: [PATCH] x86/mm: flush IOMMU before freeing kernel page table pages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +JIRA: https://issues.redhat.com/browse/RHEL-148781 +Upstream-Status: RHEL only +CVE: CVE-2025-71089 + +When IOMMU SVA is active, the IOMMU can cache kernel page table +walk results. When kernel page table directory pages (PTE/PMD/PUD +pages) are freed and reallocated, the IOMMU's paging structure cache +retains stale references, leading to DMA translations through +arbitrary data interpreted as page table entries. + +Add iommu_sva_invalidate_kva_range() calls at all four kernel page +table freeing chokepoints, placed before the page is actually freed: + + 1. pud_free_pmd_page() — ioremap huge PUD promotion (pgtable.c) + 2. pmd_free_pte_page() — ioremap huge PMD promotion (pgtable.c) + 3. free_pagetable() — memory hotplug removal (init_64.c) + 4. try_to_free_pte_page() / try_to_free_pmd_page() + — CPA page table collapse (pat/set_memory.c) + +When no SVA is active, iommu_sva_invalidate_kva_range() returns +immediately after a single atomic_read(). + +Assisted-by: Claude:claude-opus-4-6 +Signed-off-by: Jerry Snitselaar + +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index dc4fcf3d8091..f05d65446d32 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -1017,6 +1018,9 @@ static void __meminit free_pagetable(struct page *page, int order) + unsigned long magic; + unsigned int nr_pages = 1 << order; + ++ /* Flush IOMMU paging structure caches before freeing PT page */ ++ iommu_sva_invalidate_kva_range(PAGE_OFFSET, TLB_FLUSH_ALL); ++ + /* bootmem page has reserved flag */ + if (PageReserved(page)) { + __ClearPageReserved(page); +diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c +index 77dca29d82f6..63cafe9f76c3 100644 +--- a/arch/x86/mm/pat/set_memory.c ++++ b/arch/x86/mm/pat/set_memory.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1204,6 +1205,8 @@ static bool try_to_free_pte_page(pte_t *pte) + if (!pte_none(pte[i])) + return false; + ++ /* Flush IOMMU paging structure caches before freeing PT page */ ++ iommu_sva_invalidate_kva_range(PAGE_OFFSET, TLB_FLUSH_ALL); + free_page((unsigned long)pte); + return true; + } +@@ -1216,6 +1219,8 @@ static bool try_to_free_pmd_page(pmd_t *pmd) + if (!pmd_none(pmd[i])) + return false; + ++ /* Flush IOMMU paging structure caches before freeing PT page */ ++ iommu_sva_invalidate_kva_range(PAGE_OFFSET, TLB_FLUSH_ALL); + free_page((unsigned long)pmd); + return true; + } +diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c +index d28d84f7d567..e7ed6a69e76f 100644 +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -832,6 +833,9 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr) + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + ++ /* Flush IOMMU paging structure caches before freeing PT pages */ ++ iommu_sva_invalidate_kva_range(PAGE_OFFSET, TLB_FLUSH_ALL); ++ + for (i = 0; i < PTRS_PER_PMD; i++) { + if (!pmd_none(pmd_sv[i])) { + pte = (pte_t *)pmd_page_vaddr(pmd_sv[i]); +@@ -865,6 +869,8 @@ int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + ++ /* Flush IOMMU paging structure caches before freeing PT page */ ++ iommu_sva_invalidate_kva_range(PAGE_OFFSET, TLB_FLUSH_ALL); + free_page((unsigned long)pte); + + return 1; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1208-nbd-defer-config-unlock-in-nbd-genl-connect.patch b/SOURCES/1208-nbd-defer-config-unlock-in-nbd-genl-connect.patch new file mode 100644 index 000000000..a62500863 --- /dev/null +++ b/SOURCES/1208-nbd-defer-config-unlock-in-nbd-genl-connect.patch @@ -0,0 +1,74 @@ +From b539a2d23355e150de78c3744e77be3ce68a6d76 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: [PATCH] nbd: defer config unlock in nbd_genl_connect + +JIRA: https://issues.redhat.com/browse/RHEL-154215 + +commit 1649714b930f9ea6233ce0810ba885999da3b5d4 +Author: Zheng Qixing +Date: Mon Nov 10 20:49:20 2025 +0800 + + nbd: defer config unlock in nbd_genl_connect + + There is one use-after-free warning when running NBD_CMD_CONNECT and + NBD_CLEAR_SOCK: + + nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + + ------------[ cut here ]------------ + refcount_t: addition on 0; use-after-free. + WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + + The issue can be easily reproduced by adding a small delay before + refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + + printk("before sleep\n"); + + mdelay(5 * 1000); + + printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + + Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") + Signed-off-by: Zheng Qixing + Reviewed-by: Yu Kuai + Signed-off-by: Jens Axboe + +Signed-off-by: Ming Lei + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index be06723f1df0..f818ff2d82a3 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2243,12 +2243,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1209-drm-mgag200-fix-mgag200-bmc-stop-scanout.patch b/SOURCES/1209-drm-mgag200-fix-mgag200-bmc-stop-scanout.patch new file mode 100644 index 000000000..da2f2219b --- /dev/null +++ b/SOURCES/1209-drm-mgag200-fix-mgag200-bmc-stop-scanout.patch @@ -0,0 +1,218 @@ +From ab21a37682dbde2caf3738756ab45242c135bc7a Mon Sep 17 00:00:00 2001 +From: Jocelyn Falempe +Date: Mon, 16 Feb 2026 14:34:02 +0100 +Subject: [PATCH] drm/mgag200: fix mgag200_bmc_stop_scanout() + +JIRA: https://issues.redhat.com/browse/RHEL-148287 +Upstream Status: v6.19 + +commit 0e0c8f4d16de92520623aa1ea485cadbf64e6929 +Author: Jacob Keller +AuthorDate: Mon Feb 2 16:16:39 2026 -0800 +Commit: Thomas Zimmermann +CommitDate: Wed Feb 4 08:52:53 2026 +0100 + + The mgag200_bmc_stop_scanout() function is called by the .atomic_disable() + handler for the MGA G200 VGA BMC encoder. This function performs a few + register writes to inform the BMC of an upcoming mode change, and then + polls to wait until the BMC actually stops. + + The polling is implemented using a busy loop with udelay() and an iteration + timeout of 300, resulting in the function blocking for 300 milliseconds. + + The function gets called ultimately by the output_poll_execute work thread + for the DRM output change polling thread of the mgag200 driver: + + kworker/0:0-mm_ 3528 [000] 4555.315364: + ffffffffaa0e25b3 delay_halt.part.0+0x33 + ffffffffc03f6188 mgag200_bmc_stop_scanout+0x178 + ffffffffc087ae7a disable_outputs+0x12a + ffffffffc087c12a drm_atomic_helper_commit_tail+0x1a + ffffffffc03fa7b6 mgag200_mode_config_helper_atomic_commit_tail+0x26 + ffffffffc087c9c1 commit_tail+0x91 + ffffffffc087d51b drm_atomic_helper_commit+0x11b + ffffffffc0509694 drm_atomic_commit+0xa4 + ffffffffc05105e8 drm_client_modeset_commit_atomic+0x1e8 + ffffffffc0510ce6 drm_client_modeset_commit_locked+0x56 + ffffffffc0510e24 drm_client_modeset_commit+0x24 + ffffffffc088a743 __drm_fb_helper_restore_fbdev_mode_unlocked+0x93 + ffffffffc088a683 drm_fb_helper_hotplug_event+0xe3 + ffffffffc050f8aa drm_client_dev_hotplug+0x9a + ffffffffc088555a output_poll_execute+0x29a + ffffffffa9b35924 process_one_work+0x194 + ffffffffa9b364ee worker_thread+0x2fe + ffffffffa9b3ecad kthread+0xdd + ffffffffa9a08549 ret_from_fork+0x29 + + On a server running ptp4l with the mgag200 driver loaded, we found that + ptp4l would sometimes get blocked from execution because of this busy + waiting loop. + + Every so often, approximately once every 20 minutes -- though with large + variance -- the output_poll_execute() thread would detect some sort of + change that required performing a hotplug event which results in attempting + to stop the BMC scanout, resulting in a 300msec delay on one CPU. + + On this system, ptp4l was pinned to a single CPU. When the + output_poll_execute() thread ran on that CPU, it blocked ptp4l from + executing for its 300 millisecond duration. + + This resulted in PTP service disruptions such as failure to send a SYNC + message on time, failure to handle ANNOUNCE messages on time, and clock + check warnings from the application. All of this despite the application + being configured with FIFO_RT and a higher priority than the background + workqueue tasks. (However, note that the kernel did not use + CONFIG_PREEMPT...) + + It is unclear if the event is due to a faulty VGA connection, another bug, + or actual events causing a change in the connection. At least on the system + under test it is not a one-time event and consistently causes disruption to + the time sensitive applications. + + The function has some helpful comments explaining what steps it is + attempting to take. In particular, step 3a and 3b are explained as such: + + 3a - The third step is to verify if there is an active scan. We are + waiting on a 0 on remhsyncsts (. + + 3b - This step occurs only if the remove is actually scanning. We are + waiting for the end of the frame which is a 1 on remvsyncsts + (). + + The actual steps 3a and 3b are implemented as while loops with a + non-sleeping udelay(). The first step iterates while the tmp value at + position 0 is *not* set. That is, it keeps iterating as long as the bit is + zero. If the bit is already 0 (because there is no active scan), it will + iterate the entire 300 attempts which wastes 300 milliseconds in total. + This is opposite of what the description claims. + + The step 3b logic only executes if we do not iterate over the entire 300 + attempts in the first loop. If it does trigger, it is trying to check and + wait for a 1 on the remvsyncsts. However, again the condition is actually + inverted and it will loop as long as the bit is 1, stopping once it hits + zero (rather than the explained attempt to wait until we see a 1). + + Worse, both loops are implemented using non-sleeping waits which spin + instead of allowing the scheduler to run other processes. If the kernel is + not configured to allow arbitrary preemption, it will waste valuable CPU + time doing nothing. + + There does not appear to be any documentation for the BMC register + interface, beyond what is in the comments here. It seems more probable that + the comment here is correct and the implementation accidentally got + inverted from the intended logic. + + Reading through other DRM driver implementations, it does not appear that + the .atomic_enable or .atomic_disable handlers need to delay instead of + sleep. For example, the ast_astdp_encoder_helper_atomic_disable() function + calls ast_dp_set_phy_sleep() which uses msleep(). The "atomic" in the name + is referring to the atomic modesetting support, which is the support to + enable atomic configuration from userspace, and not to the "atomic context" + of the kernel. There is no reason to use udelay() here if a sleep would be + sufficient. + + Replace the while loops with a read_poll_timeout() based implementation + that will sleep between iterations, and which stops polling once the + condition is met (instead of looping as long as the condition is met). This + aligns with the commented behavior and avoids blocking on the CPU while + doing nothing. + + Note the RREG_DAC is implemented using a statement expression to allow + working properly with the read_poll_timeout family of functions. The other + RREG_ macros ought to be cleaned up to have better semantics, and + several places in the mgag200 driver could make use of RREG_DAC or similar + RREG_* macros should likely be cleaned up for better semantics as well, but + that task has been left as a future cleanup for a non-bugfix. + + Fixes: 414c45310625 ("mgag200: initial g200se driver (v2)") + Suggested-by: Thomas Zimmermann + Signed-off-by: Jacob Keller + Reviewed-by: Thomas Zimmermann + Reviewed-by: Jocelyn Falempe + Signed-off-by: Thomas Zimmermann + Link: https://patch.msgid.link/20260202-jk-mgag200-fix-bad-udelay-v2-1-ce1e9665987d@intel.com + +Signed-off-by: Jocelyn Falempe + +diff --git a/drivers/gpu/drm/mgag200/mgag200_bmc.c b/drivers/gpu/drm/mgag200/mgag200_bmc.c +index a689c71ff165..bbdeb791c5b3 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_bmc.c ++++ b/drivers/gpu/drm/mgag200/mgag200_bmc.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + + #include ++#include + + #include + #include +@@ -12,7 +13,7 @@ + void mgag200_bmc_stop_scanout(struct mga_device *mdev) + { + u8 tmp; +- int iter_max; ++ int ret; + + /* + * 1 - The first step is to inform the BMC of an upcoming mode +@@ -42,30 +43,22 @@ void mgag200_bmc_stop_scanout(struct mga_device *mdev) + + /* + * 3a- The third step is to verify if there is an active scan. +- * We are waiting for a 0 on remhsyncsts ). ++ * We are waiting for a 0 on remhsyncsts (). + */ +- iter_max = 300; +- while (!(tmp & 0x1) && iter_max) { +- WREG8(DAC_INDEX, MGA1064_SPAREREG); +- tmp = RREG8(DAC_DATA); +- udelay(1000); +- iter_max--; +- } ++ ret = read_poll_timeout(RREG_DAC, tmp, !(tmp & 0x1), ++ 1000, 300000, false, ++ MGA1064_SPAREREG); ++ if (ret == -ETIMEDOUT) ++ return; + + /* +- * 3b- This step occurs only if the remove is actually ++ * 3b- This step occurs only if the remote BMC is actually + * scanning. We are waiting for the end of the frame which is + * a 1 on remvsyncsts (XSPAREREG<1>) + */ +- if (iter_max) { +- iter_max = 300; +- while ((tmp & 0x2) && iter_max) { +- WREG8(DAC_INDEX, MGA1064_SPAREREG); +- tmp = RREG8(DAC_DATA); +- udelay(1000); +- iter_max--; +- } +- } ++ (void)read_poll_timeout(RREG_DAC, tmp, (tmp & 0x2), ++ 1000, 300000, false, ++ MGA1064_SPAREREG); + } + + void mgag200_bmc_start_scanout(struct mga_device *mdev) +diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h +index f4bf40cd7c88..a875c4bf8cbe 100644 +--- a/drivers/gpu/drm/mgag200/mgag200_drv.h ++++ b/drivers/gpu/drm/mgag200/mgag200_drv.h +@@ -111,6 +111,12 @@ + #define DAC_INDEX 0x3c00 + #define DAC_DATA 0x3c0a + ++#define RREG_DAC(reg) \ ++ ({ \ ++ WREG8(DAC_INDEX, reg); \ ++ RREG8(DAC_DATA); \ ++ }) \ ++ + #define WREG_DAC(reg, v) \ + do { \ + WREG8(DAC_INDEX, reg); \ +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1210-ice-fix-timestamp-interrupt-configuration-for-e825c.patch b/SOURCES/1210-ice-fix-timestamp-interrupt-configuration-for-e825c.patch new file mode 100644 index 000000000..11ec33697 --- /dev/null +++ b/SOURCES/1210-ice-fix-timestamp-interrupt-configuration-for-e825c.patch @@ -0,0 +1,136 @@ +From c0a575a801a2040eb1e0db54b488f8c548c8458a Mon Sep 17 00:00:00 2001 +From: Grzegorz Nitka +Date: Mon, 20 Apr 2026 17:51:25 -0700 +Subject: [PATCH] ice: fix timestamp interrupt configuration for E825C + +The E825C ice_phy_cfg_intr_eth56g() function is responsible for programming +the PHY interrupt for a given port. This function writes to the +PHY_REG_TS_INT_CONFIG register of the port. The register is responsible for +configuring whether the port interrupt logic is enabled, as well as +programming the threshold of waiting timestamps that will trigger an +interrupt from this port. + +This threshold value must not be programmed to zero while the interrupt is +enabled. Doing so puts the port in a misconfigured state where the PHY +timestamp interrupt for the quad of connected ports will become stuck. + +This occurs, because a threshold of zero results in the timestamp interrupt +status for the port becoming stuck high. The four ports in the connected +quad have their timestamp status indicators muxed together. A new interrupt +cannot be generated until the timestamp status indicators return low for +all four ports. + +Normally, the timestamp status for a port will clear once there are fewer +timestamps in that ports timestamp memory bank than the threshold. A +threshold of zero makes this impossible, so the timestamp status for the +port does not clear. + +The ice driver never intentionally programs the threshold to zero, indeed +the driver always programs it to a value of 1, intending to get an +interrupt immediately as soon as even a single packet is waiting for a +timestamp. + +However, there is a subtle flaw in the programming logic in the +ice_phy_cfg_intr_eth56g() function. Due to the way that the hardware +handles enabling the PHY interrupt. If the threshold value is modified at +the same time as the interrupt is enabled, the HW PHY state machine might +enable the interrupt before the new threshold value is actually updated. +This leaves a potential race condition caused by the hardware logic where +a PHY timestamp interrupt might be triggered before the non-zero threshold +is written, resulting in the PHY timestamp logic becoming stuck. + +Once the PHY timestamp status is stuck high, it will remain stuck even +after attempting to reprogram the PHY block by changing its threshold or +disabling the interrupt. Even a typical PF or CORE reset will not reset the +particular block of the PHY that becomes stuck. Even a warm power cycle is +not guaranteed to cause the PHY block to reset, and a cold power cycle is +required. + +Prevent this by always writing the PHY_REG_TS_INT_CONFIG in two stages. +First write the threshold value with the interrupt disabled, and only write +the enable bit after the threshold has been programmed. When disabling the +interrupt, leave the threshold unchanged. Additionally, re-read the +register after writing it to guarantee that the write to the PHY has been +flushed upon exit of the function. + +While we're modifying this function implementation, explicitly reject +programming a threshold of 0 when enabling the interrupt. No caller does +this today, but the consequences of doing so are significant. An explicit +rejection in the code makes this clear. + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Signed-off-by: Grzegorz Nitka +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Petr Oros +Tested-by: Sunitha Mekala +Signed-off-by: Jacob Keller +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-1-bc2240f42251@intel.com +Signed-off-by: Jakub Kicinski + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index 5a5c511ccbb6..7f2f7440e705 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -1847,6 +1847,8 @@ static int ice_phy_cfg_mac_eth56g(struct ice_hw *hw, u8 port) + * @ena: enable or disable interrupt + * @threshold: interrupt threshold + * ++ * The threshold cannot be 0 while the interrupt is enabled. ++ * + * Configure TX timestamp interrupt for the specified port + * + * Return: +@@ -1858,19 +1860,45 @@ int ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold) + int err; + u32 val; + ++ if (ena && !threshold) ++ return -EINVAL; ++ + err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, &val); + if (err) + return err; + ++ val &= ~PHY_TS_INT_CONFIG_ENA_M; + if (ena) { +- val |= PHY_TS_INT_CONFIG_ENA_M; + val &= ~PHY_TS_INT_CONFIG_THRESHOLD_M; + val |= FIELD_PREP(PHY_TS_INT_CONFIG_THRESHOLD_M, threshold); +- } else { +- val &= ~PHY_TS_INT_CONFIG_ENA_M; ++ err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, ++ val); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, ++ "Failed to update 'threshold' PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n", ++ port, !!ena, threshold); ++ return err; ++ } ++ val |= PHY_TS_INT_CONFIG_ENA_M; + } + +- return ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, val); ++ err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, val); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, ++ "Failed to update 'ena' PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n", ++ port, !!ena, threshold); ++ return err; ++ } ++ ++ err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_TS_INT_CONFIG, &val); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, ++ "Failed to read PHY_REG_TS_INT_CONFIG port=%u ena=%u threshold=%u\n", ++ port, !!ena, threshold); ++ return err; ++ } ++ ++ return 0; + } + + /** +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1211-ice-perform-phy-soft-reset-for-e825c-ports-at-initialization.patch b/SOURCES/1211-ice-perform-phy-soft-reset-for-e825c-ports-at-initialization.patch new file mode 100644 index 000000000..24e381efd --- /dev/null +++ b/SOURCES/1211-ice-perform-phy-soft-reset-for-e825c-ports-at-initialization.patch @@ -0,0 +1,192 @@ +From 3ec46e157c7fa420c77dfc23f7030e61f2f3fd55 Mon Sep 17 00:00:00 2001 +From: Grzegorz Nitka +Date: Mon, 20 Apr 2026 17:51:26 -0700 +Subject: [PATCH] ice: perform PHY soft reset for E825C ports at initialization + +In some cases the PHY timestamp block of the E825C can become stuck. This +is known to occur if the software writes 0 to the Tx timestamp threshold, +and with older versions of the ice driver the threshold configuration is +buggy and can race in such that hardware briefly operates with a zero +threshold enabled. There are no other known ways to trigger this behavior, +but once it occurs, the hardware is not recovered by normal reset, a driver +reload, or even a warm power cycle of the system. A cold power cycle is +sufficient to recover hardware, but this is extremely invasive and can +result in significant downtime on customer deployments. + +The PHY for each port has a timestamping block which has its own reset +functionality accessible by programming the PHY_REG_GLOBAL register. +Writing to the PHY_REG_GLOBAL_SOFT_RESET_BIT triggers the hardware to +perform a complete reset of the timestamping block of the PHY. This +includes clearing the timestamp status for the port, clearing all +outstanding timestamps in the memory bank, and resetting the PHY timer. + +The new ice_ptp_phy_soft_reset_eth56g() function toggles the +PHY_REG_GLOBAL soft reset bit with the required delays, ensuring the +PHY is properly reinitialized without requiring a full device reset. +The sequence clears the reset bit, asserts it, then clears it again, +with short waits between transitions to allow hardware stabilization. + +Call this function in the new ice_ptp_init_phc_e825c(), implementing the +E825C device specific variant of the ice_ptp_init_phc(). Note that if +ice_ptp_init_phc() fails, PTP functionality may be disabled, but the driver +will still load to allow basic functionality to continue. + +This causes the clock owning PF driver to perform a PHY soft reset for +every port during initialization. This ensures the driver begins life in a +known functional state regardless of how it was previously programmed. + +This ensures that we properly reconfigure the hardware after a device reset +or when loading the driver, even if it was previously misconfigured with an +out-of-date or modified driver. + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Signed-off-by: Timothy Miskell +Signed-off-by: Grzegorz Nitka +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Petr Oros +Tested-by: Sunitha Mekala +Signed-off-by: Jacob Keller +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-2-bc2240f42251@intel.com +Signed-off-by: Jakub Kicinski + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index 7f2f7440e705..d4c2bb084255 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -377,6 +377,31 @@ static void ice_ptp_cfg_sync_delay(const struct ice_hw *hw, u32 delay) + * The following functions operate on devices with the ETH 56G PHY. + */ + ++/** ++ * ice_ptp_init_phc_e825c - Perform E825C specific PHC initialization ++ * @hw: pointer to HW struct ++ * ++ * Perform E825C-specific PTP hardware clock initialization steps. ++ * ++ * Return: 0 on success, or a negative error value on failure. ++ */ ++static int ice_ptp_init_phc_e825c(struct ice_hw *hw) ++{ ++ int err; ++ ++ /* Soft reset all ports, to ensure everything is at a clean state */ ++ for (int port = 0; port < hw->ptp.num_lports; port++) { ++ err = ice_ptp_phy_soft_reset_eth56g(hw, port); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, "Failed to soft reset port %d, err %d\n", ++ port, err); ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ + /** + * ice_ptp_get_dest_dev_e825 - get destination PHY for given port number + * @hw: pointer to the HW struct +@@ -2179,6 +2204,69 @@ int ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status) + return 0; + } + ++/** ++ * ice_ptp_phy_soft_reset_eth56g - Perform a PHY soft reset on ETH56G ++ * @hw: pointer to the HW structure ++ * @port: PHY port number ++ * ++ * Trigger a soft reset of the ETH56G PHY by toggling the soft reset ++ * bit in the PHY global register. The reset sequence consists of: ++ * 1. Clearing the soft reset bit ++ * 2. Asserting the soft reset bit ++ * 3. Clearing the soft reset bit again ++ * ++ * Short delays are inserted between each step to allow the hardware ++ * to settle. This provides a controlled way to reinitialize the PHY ++ * without requiring a full device reset. ++ * ++ * Return: 0 on success, or a negative error code on failure when ++ * reading or writing the PHY register. ++ */ ++int ice_ptp_phy_soft_reset_eth56g(struct ice_hw *hw, u8 port) ++{ ++ u32 global_val; ++ int err; ++ ++ err = ice_read_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, &global_val); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_REG_GLOBAL for port %d, err %d\n", ++ port, err); ++ return err; ++ } ++ ++ global_val &= ~PHY_REG_GLOBAL_SOFT_RESET_M; ++ ice_debug(hw, ICE_DBG_PTP, "Clearing soft reset bit for port %d, val: 0x%x\n", ++ port, global_val); ++ err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n", ++ port, err); ++ return err; ++ } ++ ++ usleep_range(5000, 6000); ++ ++ global_val |= PHY_REG_GLOBAL_SOFT_RESET_M; ++ ice_debug(hw, ICE_DBG_PTP, "Set soft reset bit for port %d, val: 0x%x\n", ++ port, global_val); ++ err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val); ++ if (err) { ++ ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n", ++ port, err); ++ return err; ++ } ++ usleep_range(5000, 6000); ++ ++ global_val &= ~PHY_REG_GLOBAL_SOFT_RESET_M; ++ ice_debug(hw, ICE_DBG_PTP, "Clear soft reset bit for port %d, val: 0x%x\n", ++ port, global_val); ++ err = ice_write_ptp_reg_eth56g(hw, port, PHY_REG_GLOBAL, global_val); ++ if (err) ++ ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_REG_GLOBAL for port %d, err %d\n", ++ port, err); ++ return err; ++} ++ + /** + * ice_get_phy_tx_tstamp_ready_eth56g - Read the Tx memory status register + * @hw: pointer to the HW struct +@@ -5592,7 +5680,7 @@ int ice_ptp_init_phc(struct ice_hw *hw) + case ICE_MAC_GENERIC: + return ice_ptp_init_phc_e82x(hw); + case ICE_MAC_GENERIC_3K_E825: +- return 0; ++ return ice_ptp_init_phc_e825c(hw); + default: + return -EOPNOTSUPP; + } +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +index 9bfd3e79c580..ac4611291052 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +@@ -374,6 +374,7 @@ int ice_stop_phy_timer_eth56g(struct ice_hw *hw, u8 port, bool soft_reset); + int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port); + int ice_phy_cfg_intr_eth56g(struct ice_hw *hw, u8 port, bool ena, u8 threshold); + int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port); ++int ice_ptp_phy_soft_reset_eth56g(struct ice_hw *hw, u8 port); + + #define ICE_ETH56G_NOMINAL_INCVAL 0x140000000ULL + #define ICE_ETH56G_NOMINAL_PCS_REF_TUS 0x100000000ULL +@@ -676,6 +677,9 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw) + #define ICE_P0_GNSS_PRSNT_N BIT(4) + + /* ETH56G PHY register addresses */ ++#define PHY_REG_GLOBAL 0x0 ++#define PHY_REG_GLOBAL_SOFT_RESET_M BIT(11) ++ + /* Timestamp PHY incval registers */ + #define PHY_REG_TIMETUS_L 0x8 + #define PHY_REG_TIMETUS_U 0xC +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1212-ice-fix-ready-bitmap-check-for-non-e822-devices.patch b/SOURCES/1212-ice-fix-ready-bitmap-check-for-non-e822-devices.patch new file mode 100644 index 000000000..ff518227c --- /dev/null +++ b/SOURCES/1212-ice-fix-ready-bitmap-check-for-non-e822-devices.patch @@ -0,0 +1,333 @@ +From 359dc1d41358c88955eeff1b75aee55da7a415d3 Mon Sep 17 00:00:00 2001 +From: Jacob Keller +Date: Mon, 20 Apr 2026 17:51:27 -0700 +Subject: [PATCH] ice: fix ready bitmap check for non-E822 devices + +The E800 hardware (apart from E810) has a ready bitmap for the PHY +indicating which timestamp slots currently have an outstanding timestamp +waiting to be read by software. + +This bitmap is checked in multiple places using the +ice_get_phy_tx_tstamp_ready(): + + * ice_ptp_process_tx_tstamp() calls it to determine which timestamps to + attempt reading from the PHY + * ice_ptp_tx_tstamps_pending() calls it in a loop at the end of the + miscellaneous IRQ to check if new timestamps came in while the interrupt + handler was executing. + * ice_ptp_maybe_trigger_tx_interrupt() calls it in the auxiliary work task + to trigger a software interrupt in the event that the hardware logic + gets stuck. + +For E82X devices, multiple PHYs share the same block, and the parameter +passed to the ready bitmap is a block number associated with the given +port. For E825-C devices, the PHYs have their own independent blocks and do +not share, so the parameter passed needs to be the port number. For E810 +devices, the ice_get_phy_tx_tstamp_ready() always returns all 1s regardless +of what port, since this hardware does not have a ready bitmap. Finally, +for E830 devices, each PF has its own ready bitmap accessible via register, +and the block parameter is unused. + +The first call correctly uses the Tx timestamp tracker block parameter to +check the appropriate timestamp block. This works because the tracker is +setup correctly for each timestamp device type. + +The second two callers behave incorrectly for all device types other than +the older E822 devices. They both iterate in a loop using +ICE_GET_QUAD_NUM() which is a macro only used by E822 devices. This logic +is incorrect for devices other than the E822 devices. + +For E810 the calls would always return true, causing E810 devices to always +attempt to trigger a software interrupt even when they have no reason to. +For E830, this results in duplicate work as the ready bitmap is checked +once per number of quads. Finally, for E825-C, this results in the pending +checks failing to detect timestamps on ports other than the first two. + +Fix this by introducing a new hardware API function to ice_ptp_hw.c, +ice_check_phy_tx_tstamp_ready(). This function will check if any timestamps +are available and returns a positive value if any timestamps are pending. +For E810, the function always returns false, so that the re-trigger checks +never happen. For E830, check the ready bitmap just once. For E82x +hardware, check each quad. Finally, for E825-C, check every port. + +The interface function returns an integer to enable reporting of error code +if the driver is unable read the ready bitmap. This enables callers to +handle this case properly. The previous implementation assumed that +timestamps are available if they failed to read the bitmap. This is +problematic as it could lead to continuous software IRQ triggering if the +PHY timestamp registers somehow become inaccessible. + +This change is especially important for E825-C devices, as the missing +checks could leave a window open where a new timestamp could arrive while +the existing timestamps aren't completed. As a result, the hardware +threshold logic would not trigger a new interrupt. Without the check, the +timestamp is left unhandled, and new timestamps will not cause an interrupt +again until the timestamp is handled. Since both the interrupt check and +the backup check in the auxiliary task do not function properly, the device +may have Tx timestamps permanently stuck failing on a given port. + +The faulty checks originate from commit d938a8cca88a ("ice: Auxbus devices +& driver for E822 TS") and commit 712e876371f8 ("ice: periodically kick Tx +timestamp interrupt"), however at the time of the original coding, both +functions only operated on E822 hardware. This is no longer the case, and +hasn't been since the introduction of the ETH56G PHY model in commit +7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Petr Oros +Tested-by: Sunitha Mekala +Signed-off-by: Jacob Keller +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-3-bc2240f42251@intel.com +Signed-off-by: Jakub Kicinski + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index 6cb0cf7a9891..36df742c326c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -2710,7 +2710,7 @@ static bool ice_any_port_has_timestamps(struct ice_pf *pf) + bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf) + { + struct ice_hw *hw = &pf->hw; +- unsigned int i; ++ int ret; + + /* Check software indicator */ + switch (pf->ptp.tx_interrupt_mode) { +@@ -2731,16 +2731,19 @@ bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf) + } + + /* Check hardware indicator */ +- for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) { +- u64 tstamp_ready = 0; +- int err; +- +- err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready); +- if (err || tstamp_ready) +- return true; ++ ret = ice_check_phy_tx_tstamp_ready(hw); ++ if (ret < 0) { ++ dev_dbg(ice_pf_to_dev(pf), "Unable to read PHY Tx timestamp ready bitmap, err %d\n", ++ ret); ++ /* Stop triggering IRQs if we're unable to read PHY */ ++ return false; + } + +- return false; ++ /* ice_check_phy_tx_tstamp_ready() returns 1 if there are timestamps ++ * available, 0 if there are no waiting timestamps, and a negative ++ * value if there was an error (which we checked for above). ++ */ ++ return ret > 0; + } + + /** +@@ -2824,8 +2827,7 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf) + { + struct device *dev = ice_pf_to_dev(pf); + struct ice_hw *hw = &pf->hw; +- bool trigger_oicr = false; +- unsigned int i; ++ int ret; + + if (!pf->ptp.port.tx.has_ready_bitmap) + return; +@@ -2833,21 +2835,11 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf) + if (!ice_pf_src_tmr_owned(pf)) + return; + +- for (i = 0; i < ICE_GET_QUAD_NUM(hw->ptp.num_lports); i++) { +- u64 tstamp_ready; +- int err; +- +- err = ice_get_phy_tx_tstamp_ready(&pf->hw, i, &tstamp_ready); +- if (!err && tstamp_ready) { +- trigger_oicr = true; +- break; +- } +- } +- +- if (trigger_oicr) { +- /* Trigger a software interrupt, to ensure this data +- * gets processed. +- */ ++ ret = ice_check_phy_tx_tstamp_ready(hw); ++ if (ret < 0) { ++ dev_dbg(dev, "PTP periodic task unable to read PHY timestamp ready bitmap, err %d\n", ++ ret); ++ } else if (ret) { + dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n"); + + wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M); +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index d4c2bb084255..4795af06b983 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -2168,6 +2168,35 @@ int ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port) + return 0; + } + ++/** ++ * ice_check_phy_tx_tstamp_ready_eth56g - Check Tx memory status for all ports ++ * @hw: pointer to the HW struct ++ * ++ * Check the PHY_REG_TX_MEMORY_STATUS for all ports. A set bit indicates ++ * a waiting timestamp. ++ * ++ * Return: 1 if any port has at least one timestamp ready bit set, ++ * 0 otherwise, and a negative error code if unable to read the bitmap. ++ */ ++static int ice_check_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw) ++{ ++ int port; ++ ++ for (port = 0; port < hw->ptp.num_lports; port++) { ++ u64 tstamp_ready; ++ int err; ++ ++ err = ice_get_phy_tx_tstamp_ready(hw, port, &tstamp_ready); ++ if (err) ++ return err; ++ ++ if (tstamp_ready) ++ return 1; ++ } ++ ++ return 0; ++} ++ + /** + * ice_ptp_read_tx_hwtstamp_status_eth56g - Get TX timestamp status + * @hw: pointer to the HW struct +@@ -4318,6 +4347,35 @@ ice_get_phy_tx_tstamp_ready_e82x(struct ice_hw *hw, u8 quad, u64 *tstamp_ready) + return 0; + } + ++/** ++ * ice_check_phy_tx_tstamp_ready_e82x - Check Tx memory status for all quads ++ * @hw: pointer to the HW struct ++ * ++ * Check the Q_REG_TX_MEMORY_STATUS for all quads. A set bit indicates ++ * a waiting timestamp. ++ * ++ * Return: 1 if any quad has at least one timestamp ready bit set, ++ * 0 otherwise, and a negative error value if unable to read the bitmap. ++ */ ++static int ice_check_phy_tx_tstamp_ready_e82x(struct ice_hw *hw) ++{ ++ int quad; ++ ++ for (quad = 0; quad < ICE_GET_QUAD_NUM(hw->ptp.num_lports); quad++) { ++ u64 tstamp_ready; ++ int err; ++ ++ err = ice_get_phy_tx_tstamp_ready(hw, quad, &tstamp_ready); ++ if (err) ++ return err; ++ ++ if (tstamp_ready) ++ return 1; ++ } ++ ++ return 0; ++} ++ + /** + * ice_phy_cfg_intr_e82x - Configure TX timestamp interrupt + * @hw: pointer to the HW struct +@@ -4871,6 +4929,23 @@ ice_get_phy_tx_tstamp_ready_e810(struct ice_hw *hw, u8 port, u64 *tstamp_ready) + return 0; + } + ++/** ++ * ice_check_phy_tx_tstamp_ready_e810 - Check Tx memory status register ++ * @hw: pointer to the HW struct ++ * ++ * The E810 devices do not have a Tx memory status register. Note this is ++ * intentionally different behavior from ice_get_phy_tx_tstamp_ready_e810 ++ * which always says that all bits are ready. This function is called in cases ++ * where code will trigger interrupts if timestamps are waiting, and should ++ * not be called for E810 hardware. ++ * ++ * Return: 0. ++ */ ++static int ice_check_phy_tx_tstamp_ready_e810(struct ice_hw *hw) ++{ ++ return 0; ++} ++ + /* E810 SMA functions + * + * The following functions operate specifically on E810 hardware and are used +@@ -5125,6 +5200,21 @@ static void ice_get_phy_tx_tstamp_ready_e830(const struct ice_hw *hw, u8 port, + *tstamp_ready |= rd32(hw, E830_PRTMAC_TS_TX_MEM_VALID_L); + } + ++/** ++ * ice_check_phy_tx_tstamp_ready_e830 - Check Tx memory status register ++ * @hw: pointer to the HW struct ++ * ++ * Return: 1 if the device has waiting timestamps, 0 otherwise. ++ */ ++static int ice_check_phy_tx_tstamp_ready_e830(struct ice_hw *hw) ++{ ++ u64 tstamp_ready; ++ ++ ice_get_phy_tx_tstamp_ready_e830(hw, 0, &tstamp_ready); ++ ++ return !!tstamp_ready; ++} ++ + /** + * ice_ptp_init_phy_e830 - initialize PHY parameters + * @ptp: pointer to the PTP HW struct +@@ -5717,6 +5807,33 @@ int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready) + } + } + ++/** ++ * ice_check_phy_tx_tstamp_ready - Check PHY Tx timestamp memory status ++ * @hw: pointer to the HW struct ++ * ++ * Check the PHY for Tx timestamp memory status on all ports. If you need to ++ * see individual timestamp status for each index, use ++ * ice_get_phy_tx_tstamp_ready() instead. ++ * ++ * Return: 1 if any port has timestamps available, 0 if there are no timestamps ++ * available, and a negative error code on failure. ++ */ ++int ice_check_phy_tx_tstamp_ready(struct ice_hw *hw) ++{ ++ switch (hw->mac_type) { ++ case ICE_MAC_E810: ++ return ice_check_phy_tx_tstamp_ready_e810(hw); ++ case ICE_MAC_E830: ++ return ice_check_phy_tx_tstamp_ready_e830(hw); ++ case ICE_MAC_GENERIC: ++ return ice_check_phy_tx_tstamp_ready_e82x(hw); ++ case ICE_MAC_GENERIC_3K_E825: ++ return ice_check_phy_tx_tstamp_ready_eth56g(hw); ++ default: ++ return -EOPNOTSUPP; ++ } ++} ++ + /** + * ice_cgu_get_pin_desc_e823 - get pin description array + * @hw: pointer to the hw struct +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +index ac4611291052..1c9e77dbc770 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +@@ -300,6 +300,7 @@ void ice_ptp_reset_ts_memory(struct ice_hw *hw); + int ice_ptp_init_phc(struct ice_hw *hw); + void ice_ptp_init_hw(struct ice_hw *hw); + int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready); ++int ice_check_phy_tx_tstamp_ready(struct ice_hw *hw); + int ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port, + enum ice_ptp_tmr_cmd configured_cmd); + +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1213-ice-fix-ice-ptp-read-tx-hwtstamp-status-eth56g.patch b/SOURCES/1213-ice-fix-ice-ptp-read-tx-hwtstamp-status-eth56g.patch new file mode 100644 index 000000000..95b65f30b --- /dev/null +++ b/SOURCES/1213-ice-fix-ice-ptp-read-tx-hwtstamp-status-eth56g.patch @@ -0,0 +1,55 @@ +From 1f75dbc53f68f0fb2acd99f92315e426a3d0b446 Mon Sep 17 00:00:00 2001 +From: Jacob Keller +Date: Mon, 20 Apr 2026 17:51:28 -0700 +Subject: [PATCH] ice: fix ice_ptp_read_tx_hwtstamp_status_eth56g + +The ice_ptp_read_tx_hwtstamp_status_eth56g function calls +ice_read_phy_eth56g with a PHY index. However the function actually expects +a port index. This causes the function to read the wrong PHY_PTP_INT_STATUS +registers, and effectively makes the status wrong for the second set of +ports from 4 to 7. + +The ice_read_phy_eth56g function uses the provided port index to determine +which PHY device to read. We could refactor the entire chain to take a PHY +index, but this would impact many code sites. Instead, multiply the PHY +index by the number of ports, so that we read from the first port of each +PHY. + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Petr Oros +Tested-by: Sunitha Mekala +Signed-off-by: Jacob Keller +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-jk-iwl-net-2026-04-20-ptp-e825c-phy-interrupt-fixes-v1-4-bc2240f42251@intel.com +Signed-off-by: Jakub Kicinski + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index 4795af06b983..24fb7a3e14d6 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -2219,13 +2219,19 @@ int ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status) + *ts_status = 0; + + for (phy = 0; phy < params->num_phys; phy++) { ++ u8 port; + int err; + +- err = ice_read_phy_eth56g(hw, phy, PHY_PTP_INT_STATUS, &status); ++ /* ice_read_phy_eth56g expects a port index, so use the first ++ * port of the PHY ++ */ ++ port = phy * hw->ptp.ports_per_phy; ++ ++ err = ice_read_phy_eth56g(hw, port, PHY_PTP_INT_STATUS, &status); + if (err) + return err; + +- *ts_status |= (status & mask) << (phy * hw->ptp.ports_per_phy); ++ *ts_status |= (status & mask) << port; + } + + ice_debug(hw, ICE_DBG_PTP, "PHY interrupt err: %x\n", *ts_status); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1214-cifs-make-default-value-of-retrans-as-zero.patch b/SOURCES/1214-cifs-make-default-value-of-retrans-as-zero.patch new file mode 100644 index 000000000..01a166c8b --- /dev/null +++ b/SOURCES/1214-cifs-make-default-value-of-retrans-as-zero.patch @@ -0,0 +1,41 @@ +From b755987ae1e0ceffe730ce1cae499d577aa10fa8 Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Fri, 24 Apr 2026 13:56:23 -0300 +Subject: [PATCH] cifs: make default value of retrans as zero + +JIRA: https://issues.redhat.com/browse/RHEL-159632 + +commit e3beefd3af09f8e460ddaf39063d3d7664d7ab59 +Author: Shyam Prasad N +Date: Wed Mar 11 10:48:54 2026 +0530 + + cifs: make default value of retrans as zero + + When retrans mount option was introduced, the default value was set + as 1. However, in the light of some bugs that this has exposed recently + we should change it to 0 and retain the old behaviour before this option + was introduced. + + Cc: + Reviewed-by: Bharath SM + Signed-off-by: Shyam Prasad N + Signed-off-by: Steve French + +Signed-off-by: Paulo Alcantara + +diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c +index 21338c06e026..296a231e8f03 100644 +--- a/fs/smb/client/fs_context.c ++++ b/fs/smb/client/fs_context.c +@@ -2015,7 +2015,7 @@ int smb3_init_fs_context(struct fs_context *fc) + ctx->backupuid_specified = false; /* no backup intent for a user */ + ctx->backupgid_specified = false; /* no backup intent for a group */ + +- ctx->retrans = 1; ++ ctx->retrans = 0; + ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT; + ctx->symlink_type = CIFS_SYMLINK_TYPE_DEFAULT; + ctx->nonativesocket = 0; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1215-net-sched-act-csum-validate-nested-vlan-headers.patch b/SOURCES/1215-net-sched-act-csum-validate-nested-vlan-headers.patch new file mode 100644 index 000000000..443a0d5bf --- /dev/null +++ b/SOURCES/1215-net-sched-act-csum-validate-nested-vlan-headers.patch @@ -0,0 +1,63 @@ +From 5d5232da1baa2166824e36281792850a35621cb8 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Mon, 27 Apr 2026 10:27:43 +0000 +Subject: [PATCH] net: sched: act_csum: validate nested VLAN headers + +JIRA: https://redhat.atlassian.net/browse/RHEL-171139 +CVE: CVE-2026-31684 + +commit c842743d073bdd683606cb414eb0ca84465dd834 +Author: Ruide Cao +Date: Thu Apr 2 22:46:20 2026 +0800 + + net: sched: act_csum: validate nested VLAN headers + + tcf_csum_act() walks nested VLAN headers directly from skb->data when an + skb still carries in-payload VLAN tags. The current code reads + vlan->h_vlan_encapsulated_proto and then pulls VLAN_HLEN bytes without + first ensuring that the full VLAN header is present in the linear area. + + If only part of an inner VLAN header is linearized, accessing + h_vlan_encapsulated_proto reads past the linear area, and the following + skb_pull(VLAN_HLEN) may violate skb invariants. + + Fix this by requiring pskb_may_pull(skb, VLAN_HLEN) before accessing and + pulling each nested VLAN header. If the header still is not fully + available, drop the packet through the existing error path. + + Fixes: 2ecba2d1e45b ("net: sched: act_csum: Fix csum calc for tagged packets") + Reported-by: Yifan Wu + Reported-by: Juefei Pu + Co-developed-by: Yuan Tan + Signed-off-by: Yuan Tan + Suggested-by: Xin Liu + Tested-by: Ren Wei + Signed-off-by: Ruide Cao + Signed-off-by: Ren Wei + Reviewed-by: Simon Horman + Link: https://patch.msgid.link/22df2fcb49f410203eafa5d97963dd36089f4ecf.1774892775.git.caoruide123@gmail.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: CKI Backport Bot + +diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c +index 5cc8e407e791..8ea37c2c3c54 100644 +--- a/net/sched/act_csum.c ++++ b/net/sched/act_csum.c +@@ -603,8 +603,12 @@ TC_INDIRECT_SCOPE int tcf_csum_act(struct sk_buff *skb, + protocol = skb->protocol; + orig_vlan_tag_present = true; + } else { +- struct vlan_hdr *vlan = (struct vlan_hdr *)skb->data; ++ struct vlan_hdr *vlan; + ++ if (!pskb_may_pull(skb, VLAN_HLEN)) ++ goto drop; ++ ++ vlan = (struct vlan_hdr *)skb->data; + protocol = vlan->h_vlan_encapsulated_proto; + skb_pull(skb, VLAN_HLEN); + skb_reset_network_header(skb); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1216-netfilter-ip6t-eui64-reject-invalid-mac-header-for-all-packe.patch b/SOURCES/1216-netfilter-ip6t-eui64-reject-invalid-mac-header-for-all-packe.patch new file mode 100644 index 000000000..796d7f844 --- /dev/null +++ b/SOURCES/1216-netfilter-ip6t-eui64-reject-invalid-mac-header-for-all-packe.patch @@ -0,0 +1,55 @@ +From da41cc73d3b75bb43102c2d364b8b3df8c3e1420 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Mon, 27 Apr 2026 10:34:55 +0000 +Subject: [PATCH] netfilter: ip6t_eui64: reject invalid MAC header for all + packets + +JIRA: https://redhat.atlassian.net/browse/RHEL-171156 +CVE: CVE-2026-31685 + +commit fdce0b3590f724540795b874b4c8850c90e6b0a8 +Author: Zhengchuan Liang +Date: Sat Apr 4 17:39:47 2026 +0800 + + netfilter: ip6t_eui64: reject invalid MAC header for all packets + + `eui64_mt6()` derives a modified EUI-64 from the Ethernet source address + and compares it with the low 64 bits of the IPv6 source address. + + The existing guard only rejects an invalid MAC header when + `par->fragoff != 0`. For packets with `par->fragoff == 0`, `eui64_mt6()` + can still reach `eth_hdr(skb)` even when the MAC header is not valid. + + Fix this by removing the `par->fragoff != 0` condition so that packets + with an invalid MAC header are rejected before accessing `eth_hdr(skb)`. + + Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2") + Reported-by: Yifan Wu + Reported-by: Juefei Pu + Co-developed-by: Yuan Tan + Signed-off-by: Yuan Tan + Suggested-by: Xin Liu + Tested-by: Ren Wei + Signed-off-by: Zhengchuan Liang + Signed-off-by: Ren Wei + Signed-off-by: Florian Westphal + +Signed-off-by: CKI Backport Bot + +diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c +index d704f7ed300c..da69a27e8332 100644 +--- a/net/ipv6/netfilter/ip6t_eui64.c ++++ b/net/ipv6/netfilter/ip6t_eui64.c +@@ -22,8 +22,7 @@ eui64_mt6(const struct sk_buff *skb, struct xt_action_param *par) + unsigned char eui64[8]; + + if (!(skb_mac_header(skb) >= skb->head && +- skb_mac_header(skb) + ETH_HLEN <= skb->data) && +- par->fragoff != 0) { ++ skb_mac_header(skb) + ETH_HLEN <= skb->data)) { + par->hotdrop = true; + return false; + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1217-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch b/SOURCES/1217-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch new file mode 100644 index 000000000..8f9ad784a --- /dev/null +++ b/SOURCES/1217-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch @@ -0,0 +1,98 @@ +From 1603e6758a3b8a26ac4e8571909826cac456d02f Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Mon, 27 Apr 2026 14:44:20 +0200 +Subject: [PATCH] scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for + Hyper-V vFC + +JIRA: https://redhat.atlassian.net/browse/RHEL-159283 + +commit 9cf351b289fb2be22491fa3964f99126db67aa08 +Author: Li Tian +Date: Mon Apr 6 09:53:44 2026 +0800 + + scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for Hyper-V vFC + + The storvsc driver has become stricter in handling SRB status codes + returned by the Hyper-V host. When using Virtual Fibre Channel (vFC) + passthrough, the host may return SRB_STATUS_DATA_OVERRUN for + PERSISTENT_RESERVE_IN commands if the allocation length in the CDB does + not match the host's expected response size. + + Currently, this status is treated as a fatal error, propagating + Host_status=0x07 [DID_ERROR] to the SCSI mid-layer. This causes + userspace storage utilities (such as sg_persist) to fail with transport + errors, even when the host has actually returned the requested + reservation data in the buffer. + + Refactor the existing command-specific workarounds into a new helper + function, storvsc_host_mishandles_cmd(), and add PERSISTENT_RESERVE_IN + to the list of commands where SRB status errors should be suppressed for + vFC devices. This ensures that the SCSI mid-layer processes the returned + data buffer instead of terminating the command. + + Signed-off-by: Li Tian + Reviewed-by: Long Li + Reviewed-by: Laurence Oberman + Link: https://patch.msgid.link/20260406015344.12566-1-litian@redhat.com + Signed-off-by: Martin K. Petersen + +Signed-off-by: Vitaly Kuznetsov + +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index c66cfdb5eb03..9b3a964edce2 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1131,6 +1131,26 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, + kfree(payload); + } + ++/* ++ * The current SCSI handling on the host side does not correctly handle: ++ * INQUIRY with page code 0x80, MODE_SENSE / MODE_SENSE_10 with cmd[2] == 0x1c, ++ * and (for FC) MAINTENANCE_IN / PERSISTENT_RESERVE_IN passthrough. ++ */ ++static bool storvsc_host_mishandles_cmd(u8 opcode, struct hv_device *device) ++{ ++ switch (opcode) { ++ case INQUIRY: ++ case MODE_SENSE: ++ case MODE_SENSE_10: ++ return true; ++ case MAINTENANCE_IN: ++ case PERSISTENT_RESERVE_IN: ++ return hv_dev_is_fc(device); ++ default: ++ return false; ++ } ++} ++ + static void storvsc_on_io_completion(struct storvsc_device *stor_device, + struct vstor_packet *vstor_packet, + struct storvsc_cmd_request *request) +@@ -1141,22 +1161,12 @@ static void storvsc_on_io_completion(struct storvsc_device *stor_device, + stor_pkt = &request->vstor_packet; + + /* +- * The current SCSI handling on the host side does +- * not correctly handle: +- * INQUIRY command with page code parameter set to 0x80 +- * MODE_SENSE and MODE_SENSE_10 command with cmd[2] == 0x1c +- * MAINTENANCE_IN is not supported by HyperV FC passthrough +- * + * Setup srb and scsi status so this won't be fatal. + * We do this so we can distinguish truly fatal failues + * (srb status == 0x4) and off-line the device in that case. + */ + +- if ((stor_pkt->vm_srb.cdb[0] == INQUIRY) || +- (stor_pkt->vm_srb.cdb[0] == MODE_SENSE) || +- (stor_pkt->vm_srb.cdb[0] == MODE_SENSE_10) || +- (stor_pkt->vm_srb.cdb[0] == MAINTENANCE_IN && +- hv_dev_is_fc(device))) { ++ if (storvsc_host_mishandles_cmd(stor_pkt->vm_srb.cdb[0], device)) { + vstor_packet->vm_srb.scsi_status = 0; + vstor_packet->vm_srb.srb_status = SRB_STATUS_SUCCESS; + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1218-dpll-zl3073x-add-output-pin-frequency-helper.patch b/SOURCES/1218-dpll-zl3073x-add-output-pin-frequency-helper.patch new file mode 100644 index 000000000..7f436dae4 --- /dev/null +++ b/SOURCES/1218-dpll-zl3073x-add-output-pin-frequency-helper.patch @@ -0,0 +1,158 @@ +From 15946df9225ee7086abe595aed92ab1ad5b63cde Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Thu, 2 Apr 2026 14:48:36 +0000 +Subject: [PATCH] dpll: zl3073x: Add output pin frequency helper + +JIRA: https://redhat.atlassian.net/browse/RHEL-164439 + +commit 24e4336a87f5c51263535201218889b5f324511f +Author: Ivan Vecera +Date: Thu Feb 5 16:43:49 2026 +0100 + + dpll: zl3073x: Add output pin frequency helper + + Introduce zl3073x_dev_output_pin_freq_get() helper function to compute + the output pin frequency based on synthesizer frequency, output divisor, + and signal format. For N-div signal formats, the N-pin frequency is + additionally divided by esync_n_period. + + Add zl3073x_out_is_ndiv() helper to check if an output is configured + in N-div mode (2_NDIV or 2_NDIV_INV signal formats). + + Refactor zl3073x_dpll_output_pin_frequency_get() callback to use the + new helper, reducing code duplication and enabling reuse of the + frequency calculation logic in other contexts. + + This is a preparatory change for adding current frequency to the + supported frequencies list in pin properties. + + Signed-off-by: Ivan Vecera + Link: https://patch.msgid.link/20260205154350.3180465-2-ivecera@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h +index 09bca2d0926d..dddfcacea5c0 100644 +--- a/drivers/dpll/zl3073x/core.h ++++ b/drivers/dpll/zl3073x/core.h +@@ -301,6 +301,36 @@ u8 zl3073x_dev_out_dpll_get(struct zl3073x_dev *zldev, u8 index) + return zl3073x_synth_dpll_get(synth); + } + ++/** ++ * zl3073x_dev_output_pin_freq_get - get output pin frequency ++ * @zldev: pointer to zl3073x device ++ * @id: output pin id ++ * ++ * Computes the output pin frequency based on the synth frequency, output ++ * divisor, and signal format. For N-div formats, N-pin frequency is ++ * additionally divided by esync_n_period. ++ * ++ * Return: frequency of the given output pin in Hz ++ */ ++static inline u32 ++zl3073x_dev_output_pin_freq_get(struct zl3073x_dev *zldev, u8 id) ++{ ++ const struct zl3073x_synth *synth; ++ const struct zl3073x_out *out; ++ u8 out_id; ++ u32 freq; ++ ++ out_id = zl3073x_output_pin_out_get(id); ++ out = zl3073x_out_state_get(zldev, out_id); ++ synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out)); ++ freq = zl3073x_synth_freq_get(synth) / out->div; ++ ++ if (zl3073x_out_is_ndiv(out) && zl3073x_is_n_pin(id)) ++ freq /= out->esync_n_period; ++ ++ return freq; ++} ++ + /** + * zl3073x_dev_out_is_diff - check if the given output is differential + * @zldev: pointer to zl3073x device +diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c +index 897ed682dbf9..78edc36b17fb 100644 +--- a/drivers/dpll/zl3073x/dpll.c ++++ b/drivers/dpll/zl3073x/dpll.c +@@ -916,46 +916,9 @@ zl3073x_dpll_output_pin_frequency_get(const struct dpll_pin *dpll_pin, + struct netlink_ext_ack *extack) + { + struct zl3073x_dpll *zldpll = dpll_priv; +- struct zl3073x_dev *zldev = zldpll->dev; + struct zl3073x_dpll_pin *pin = pin_priv; +- const struct zl3073x_synth *synth; +- const struct zl3073x_out *out; +- u32 synth_freq; +- u8 out_id; + +- out_id = zl3073x_output_pin_out_get(pin->id); +- out = zl3073x_out_state_get(zldev, out_id); +- +- /* Get attached synth frequency */ +- synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out)); +- synth_freq = zl3073x_synth_freq_get(synth); +- +- switch (zl3073x_out_signal_format_get(out)) { +- case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV: +- case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV: +- /* In case of divided format we have to distiguish between +- * given output pin type. +- * +- * For P-pin the resulting frequency is computed as simple +- * division of synth frequency and output divisor. +- * +- * For N-pin we have to divide additionally by divisor stored +- * in esync_n_period output mailbox register that is used as +- * N-pin divisor for these modes. +- */ +- *frequency = synth_freq / out->div; +- +- if (!zl3073x_dpll_is_p_pin(pin)) +- *frequency = (u32)*frequency / out->esync_n_period; +- +- break; +- default: +- /* In other modes the resulting frequency is computed as +- * division of synth frequency and output divisor. +- */ +- *frequency = synth_freq / out->div; +- break; +- } ++ *frequency = zl3073x_dev_output_pin_freq_get(zldpll->dev, pin->id); + + return 0; + } +diff --git a/drivers/dpll/zl3073x/out.h b/drivers/dpll/zl3073x/out.h +index e8ea7a0e0f07..318f9bb8da3a 100644 +--- a/drivers/dpll/zl3073x/out.h ++++ b/drivers/dpll/zl3073x/out.h +@@ -79,6 +79,23 @@ static inline bool zl3073x_out_is_enabled(const struct zl3073x_out *out) + return !!FIELD_GET(ZL_OUTPUT_CTRL_EN, out->ctrl); + } + ++/** ++ * zl3073x_out_is_ndiv - check if the given output is in N-div mode ++ * @out: pointer to out state ++ * ++ * Return: true if output is in N-div mode, false otherwise ++ */ ++static inline bool zl3073x_out_is_ndiv(const struct zl3073x_out *out) ++{ ++ switch (zl3073x_out_signal_format_get(out)) { ++ case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV: ++ case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV: ++ return true; ++ default: ++ return false; ++ } ++} ++ + /** + * zl3073x_out_synth_get - get synth connected to given output + * @out: pointer to out state +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1219-dpll-zl3073x-include-current-frequency-in-supported-frequenc.patch b/SOURCES/1219-dpll-zl3073x-include-current-frequency-in-supported-frequenc.patch new file mode 100644 index 000000000..22a637247 --- /dev/null +++ b/SOURCES/1219-dpll-zl3073x-include-current-frequency-in-supported-frequenc.patch @@ -0,0 +1,124 @@ +From 2e6a41a79f740a6c20f57f13fb94e92662affda5 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Thu, 2 Apr 2026 14:48:37 +0000 +Subject: [PATCH] dpll: zl3073x: Include current frequency in supported + frequencies list + +JIRA: https://redhat.atlassian.net/browse/RHEL-164439 + +commit 85a9aaac4a38a7ce68f30bd7678fca4e8c687fe2 +Author: Ivan Vecera +Date: Thu Feb 5 16:43:50 2026 +0100 + + dpll: zl3073x: Include current frequency in supported frequencies list + + Ensure the current pin frequency is always present in the list of + supported frequencies reported to userspace. Previously, if the + firmware node was missing or didn't include the current operating + frequency in the supported-frequencies-hz property, the pin would + report a frequency that wasn't in its supported list. + + Get the current frequency early in zl3073x_pin_props_get(): + - For input pins: use zl3073x_dev_ref_freq_get() + - For output pins: use zl3073x_dev_output_pin_freq_get() + + Place the current frequency at index 0 of the supported frequencies + array, then append frequencies from the firmware node (if present), + skipping any duplicate of the current frequency. + + Signed-off-by: Ivan Vecera + Link: https://patch.msgid.link/20260205154350.3180465-3-ivecera@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/dpll/zl3073x/prop.c b/drivers/dpll/zl3073x/prop.c +index ad1f099cbe2b..8523dc8c226e 100644 +--- a/drivers/dpll/zl3073x/prop.c ++++ b/drivers/dpll/zl3073x/prop.c +@@ -193,9 +193,10 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, + { + struct dpll_pin_frequency *ranges; + struct zl3073x_pin_props *props; +- int i, j, num_freqs, rc; ++ int i, j, num_freqs = 0, rc; ++ u64 *freqs = NULL; + const char *type; +- u64 *freqs; ++ u32 curr_freq; + + props = kzalloc(sizeof(*props), GFP_KERNEL); + if (!props) +@@ -207,6 +208,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, + props->dpll_props.capabilities = + DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE | + DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE; ++ curr_freq = zl3073x_dev_ref_freq_get(zldev, index); + } else { + u8 out, synth; + u32 f; +@@ -220,6 +222,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, + synth = zl3073x_dev_out_synth_get(zldev, out); + f = 2 * zl3073x_dev_synth_freq_get(zldev, synth); + props->dpll_props.phase_gran = f ? div_u64(PSEC_PER_SEC, f) : 1; ++ curr_freq = zl3073x_dev_output_pin_freq_get(zldev, index); + } + + props->dpll_props.phase_range.min = S32_MIN; +@@ -230,7 +233,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, + /* Get firmware node for the given pin */ + rc = zl3073x_prop_pin_fwnode_get(zldev, props, dir, index); + if (rc) +- return props; /* Return if it does not exist */ ++ goto skip_fwnode_props; + + /* Look for label property and store the value as board label */ + fwnode_property_read_string(props->fwnode, "label", +@@ -264,9 +267,10 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, + /* Read supported frequencies property if it is specified */ + num_freqs = fwnode_property_count_u64(props->fwnode, + "supported-frequencies-hz"); +- if (num_freqs <= 0) +- /* Return if the property does not exist or number is 0 */ +- return props; ++ if (num_freqs <= 0) { ++ num_freqs = 0; ++ goto skip_fwnode_props; ++ } + + /* The firmware node specifies list of supported frequencies while + * DPLL core pin properties requires list of frequency ranges. +@@ -283,19 +287,25 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, + "supported-frequencies-hz", freqs, + num_freqs); + +- /* Allocate frequency ranges list and fill it */ +- ranges = kcalloc(num_freqs, sizeof(*ranges), GFP_KERNEL); ++skip_fwnode_props: ++ /* Allocate frequency ranges list - extra slot for current frequency */ ++ ranges = kcalloc(num_freqs + 1, sizeof(*ranges), GFP_KERNEL); + if (!ranges) { + rc = -ENOMEM; + goto err_alloc_ranges; + } + +- /* Convert list of frequencies to list of frequency ranges but +- * filter-out frequencies that are not representable by device ++ /* Start with current frequency at index 0 */ ++ ranges[0] = (struct dpll_pin_frequency)DPLL_PIN_FREQUENCY(curr_freq); ++ ++ /* Add frequencies from firmware node, skipping current frequency ++ * and filtering out frequencies not representable by device + */ +- for (i = 0, j = 0; i < num_freqs; i++) { ++ for (i = 0, j = 1; i < num_freqs; i++) { + struct dpll_pin_frequency freq = DPLL_PIN_FREQUENCY(freqs[i]); + ++ if (freqs[i] == curr_freq) ++ continue; + if (zl3073x_pin_check_freq(zldev, dir, index, freqs[i])) { + ranges[j] = freq; + j++; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1220-dpll-zl3073x-fix-ref-frequency-setting.patch b/SOURCES/1220-dpll-zl3073x-fix-ref-frequency-setting.patch new file mode 100644 index 000000000..5b0862bd6 --- /dev/null +++ b/SOURCES/1220-dpll-zl3073x-fix-ref-frequency-setting.patch @@ -0,0 +1,58 @@ +From 8823135b96c424be80d82435925a56a9e53d727a Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Thu, 2 Apr 2026 14:48:38 +0000 +Subject: [PATCH] dpll: zl3073x: Fix ref frequency setting + +JIRA: https://redhat.atlassian.net/browse/RHEL-164439 + +commit a047497f952831e377564b606dcb74a7cb309384 +Author: Ivan Vecera +Date: Mon Feb 16 20:40:07 2026 +0100 + + dpll: zl3073x: Fix ref frequency setting + + The frequency for an input reference is computed as: + + frequency = freq_base * freq_mult * freq_ratio_m / freq_ratio_n + + Before commit 5bc02b190a3fb ("dpll: zl3073x: Cache all reference + properties in zl3073x_ref"), zl3073x_dpll_input_pin_frequency_set() + explicitly wrote 1 to both the REF_RATIO_M and REF_RATIO_N hardware + registers whenever a new frequency was set. This ensured the FEC ratio + was always reset to 1:1 alongside the new base/multiplier values. + + The refactoring in that commit introduced zl3073x_ref_freq_set() to + update the cached ref state, but this helper only sets freq_base and + freq_mult without resetting freq_ratio_m and freq_ratio_n to 1. Because + zl3073x_ref_state_set() uses a compare-and-write strategy, unchanged + ratio fields are never written to the hardware. If the device previously + had non-unity FEC ratio values, they remain in effect after a frequency + change, resulting in an incorrect computed frequency. + + Explicitly set freq_ratio_m and freq_ratio_n to 1 in zl3073x_ref_freq_set() + to restore the original behavior. + + Fixes: 5bc02b190a3fb ("dpll: zl3073x: Cache all reference properties in zl3073x_ref") + Signed-off-by: Ivan Vecera + Reviewed-by: Simon Horman + Link: https://patch.msgid.link/20260216194007.680416-1-ivecera@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h +index efc7f59cd9f9..0d8618f5ce8d 100644 +--- a/drivers/dpll/zl3073x/ref.h ++++ b/drivers/dpll/zl3073x/ref.h +@@ -91,6 +91,8 @@ zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq) + + ref->freq_base = base; + ref->freq_mult = mult; ++ ref->freq_ratio_m = 1; ++ ref->freq_ratio_n = 1; + + return 0; + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1221-dpll-zl3073x-fix-ref-phase-offset-comp-register-width-for-so.patch b/SOURCES/1221-dpll-zl3073x-fix-ref-phase-offset-comp-register-width-for-so.patch new file mode 100644 index 000000000..2c4c6d416 --- /dev/null +++ b/SOURCES/1221-dpll-zl3073x-fix-ref-phase-offset-comp-register-width-for-so.patch @@ -0,0 +1,175 @@ +From 991d19f0cadb6fc8c9f4e446e118a0e6121ac3ae Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Thu, 2 Apr 2026 14:48:39 +0000 +Subject: [PATCH] dpll: zl3073x: fix REF_PHASE_OFFSET_COMP register width for + some chip IDs + +JIRA: https://redhat.atlassian.net/browse/RHEL-164439 + +commit 4cfe066a82cdf9e83e48b16000f55280efc98325 +Author: Ivan Vecera +Date: Fri Feb 20 16:57:54 2026 +0100 + + dpll: zl3073x: fix REF_PHASE_OFFSET_COMP register width for some chip IDs + + The REF_PHASE_OFFSET_COMP register is 48-bit wide on most zl3073x chip + variants, but only 32-bit wide on chip IDs 0x0E30, 0x0E93..0x0E97 and + 0x1F60. The driver unconditionally uses 48-bit read/write operations, + which on 32-bit variants causes reading 2 bytes past the register + boundary (corrupting the value) and writing 2 bytes into the adjacent + register. + + Fix this by storing the chip ID in the device structure during probe + and adding a helper to detect the affected variants. Use the correct + register width for read/write operations and the matching sign extension + bit (31 vs 47) when interpreting the phase compensation value. + + Fixes: 6287262f761e ("dpll: zl3073x: Add support to adjust phase") + Signed-off-by: Ivan Vecera + Reviewed-by: Simon Horman + Link: https://patch.msgid.link/20260220155755.448185-1-ivecera@redhat.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c +index 60bf70f3c282..83d7a124ddcd 100644 +--- a/drivers/dpll/zl3073x/core.c ++++ b/drivers/dpll/zl3073x/core.c +@@ -1028,6 +1028,7 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev, + "Unknown or non-match chip ID: 0x%0x\n", + id); + } ++ zldev->chip_id = id; + + /* Read revision, firmware version and custom config version */ + rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision); +diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h +index dddfcacea5c0..fd2af3c62a7d 100644 +--- a/drivers/dpll/zl3073x/core.h ++++ b/drivers/dpll/zl3073x/core.h +@@ -35,6 +35,7 @@ struct zl3073x_dpll; + * @dev: pointer to device + * @regmap: regmap to access device registers + * @multiop_lock: to serialize multiple register operations ++ * @chip_id: chip ID read from hardware + * @ref: array of input references' invariants + * @out: array of outs' invariants + * @synth: array of synths' invariants +@@ -48,6 +49,7 @@ struct zl3073x_dev { + struct device *dev; + struct regmap *regmap; + struct mutex multiop_lock; ++ u16 chip_id; + + /* Invariants */ + struct zl3073x_ref ref[ZL3073X_NUM_REFS]; +@@ -144,6 +146,32 @@ int zl3073x_write_hwreg_seq(struct zl3073x_dev *zldev, + + int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel); + ++/** ++ * zl3073x_dev_is_ref_phase_comp_32bit - check ref phase comp register size ++ * @zldev: pointer to zl3073x device ++ * ++ * Some chip IDs have a 32-bit wide ref_phase_offset_comp register instead ++ * of the default 48-bit. ++ * ++ * Return: true if the register is 32-bit, false if 48-bit ++ */ ++static inline bool ++zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev) ++{ ++ switch (zldev->chip_id) { ++ case 0x0E30: ++ case 0x0E93: ++ case 0x0E94: ++ case 0x0E95: ++ case 0x0E96: ++ case 0x0E97: ++ case 0x1F60: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static inline bool + zl3073x_is_n_pin(u8 id) + { +diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c +index 78edc36b17fb..8ffbede117c6 100644 +--- a/drivers/dpll/zl3073x/dpll.c ++++ b/drivers/dpll/zl3073x/dpll.c +@@ -475,8 +475,11 @@ zl3073x_dpll_input_pin_phase_adjust_get(const struct dpll_pin *dpll_pin, + ref_id = zl3073x_input_pin_ref_get(pin->id); + ref = zl3073x_ref_state_get(zldev, ref_id); + +- /* Perform sign extension for 48bit signed value */ +- phase_comp = sign_extend64(ref->phase_comp, 47); ++ /* Perform sign extension based on register width */ ++ if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) ++ phase_comp = sign_extend64(ref->phase_comp, 31); ++ else ++ phase_comp = sign_extend64(ref->phase_comp, 47); + + /* Reverse two's complement negation applied during set and convert + * to 32bit signed int +diff --git a/drivers/dpll/zl3073x/ref.c b/drivers/dpll/zl3073x/ref.c +index aa2de13effa8..6b65e6103999 100644 +--- a/drivers/dpll/zl3073x/ref.c ++++ b/drivers/dpll/zl3073x/ref.c +@@ -121,8 +121,16 @@ int zl3073x_ref_state_fetch(struct zl3073x_dev *zldev, u8 index) + return rc; + + /* Read phase compensation register */ +- rc = zl3073x_read_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP, +- &ref->phase_comp); ++ if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) { ++ u32 val; ++ ++ rc = zl3073x_read_u32(zldev, ZL_REG_REF_PHASE_OFFSET_COMP_32, ++ &val); ++ ref->phase_comp = val; ++ } else { ++ rc = zl3073x_read_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP, ++ &ref->phase_comp); ++ } + if (rc) + return rc; + +@@ -179,9 +187,16 @@ int zl3073x_ref_state_set(struct zl3073x_dev *zldev, u8 index, + if (!rc && dref->sync_ctrl != ref->sync_ctrl) + rc = zl3073x_write_u8(zldev, ZL_REG_REF_SYNC_CTRL, + ref->sync_ctrl); +- if (!rc && dref->phase_comp != ref->phase_comp) +- rc = zl3073x_write_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP, +- ref->phase_comp); ++ if (!rc && dref->phase_comp != ref->phase_comp) { ++ if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) ++ rc = zl3073x_write_u32(zldev, ++ ZL_REG_REF_PHASE_OFFSET_COMP_32, ++ ref->phase_comp); ++ else ++ rc = zl3073x_write_u48(zldev, ++ ZL_REG_REF_PHASE_OFFSET_COMP, ++ ref->phase_comp); ++ } + if (rc) + return rc; + +diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h +index d837bee72b17..5573d7188406 100644 +--- a/drivers/dpll/zl3073x/regs.h ++++ b/drivers/dpll/zl3073x/regs.h +@@ -194,6 +194,7 @@ + #define ZL_REF_CONFIG_DIFF_EN BIT(2) + + #define ZL_REG_REF_PHASE_OFFSET_COMP ZL_REG(10, 0x28, 6) ++#define ZL_REG_REF_PHASE_OFFSET_COMP_32 ZL_REG(10, 0x28, 4) + + #define ZL_REG_REF_SYNC_CTRL ZL_REG(10, 0x2e, 1) + #define ZL_REF_SYNC_CTRL_MODE GENMASK(2, 0) +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1222-dpll-zl3073x-remove-redundant-cleanup-in-devm-dpll-init.patch b/SOURCES/1222-dpll-zl3073x-remove-redundant-cleanup-in-devm-dpll-init.patch new file mode 100644 index 000000000..c71bda36c --- /dev/null +++ b/SOURCES/1222-dpll-zl3073x-remove-redundant-cleanup-in-devm-dpll-init.patch @@ -0,0 +1,45 @@ +From bc96573280f4aee125de4ca6d502831893339f63 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Thu, 2 Apr 2026 14:48:41 +0000 +Subject: [PATCH] dpll: zl3073x: Remove redundant cleanup in devm_dpll_init() + +JIRA: https://redhat.atlassian.net/browse/RHEL-164439 + +commit 676c7af91fcd740d34e7cb788cbc58e3bcafde39 +Author: Felix Gu +Date: Tue Feb 24 19:04:04 2026 +0800 + + dpll: zl3073x: Remove redundant cleanup in devm_dpll_init() + + The devm_add_action_or_reset() function already executes the cleanup + action on failure before returning an error, so the explicit goto error + and subsequent zl3073x_dev_dpll_fini() call causes double cleanup. + + Fixes: ebb1031c5137 ("dpll: zl3073x: Refactor DPLL initialization") + Reviewed-by: Ivan Vecera + Signed-off-by: Felix Gu + Link: https://patch.msgid.link/20260224-dpll-v2-1-d7786414a830@gmail.com + Signed-off-by: Jakub Kicinski + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c +index 83d7a124ddcd..179fff5e7d54 100644 +--- a/drivers/dpll/zl3073x/core.c ++++ b/drivers/dpll/zl3073x/core.c +@@ -983,11 +983,7 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls) + } + + /* Add devres action to release DPLL related resources */ +- rc = devm_add_action_or_reset(zldev->dev, zl3073x_dev_dpll_fini, zldev); +- if (rc) +- goto error; +- +- return 0; ++ return devm_add_action_or_reset(zldev->dev, zl3073x_dev_dpll_fini, zldev); + + error: + zl3073x_dev_dpll_fini(zldev); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1223-ice-fix-null-pointer-dereference-in-ice-reset-all-vfs.patch b/SOURCES/1223-ice-fix-null-pointer-dereference-in-ice-reset-all-vfs.patch new file mode 100644 index 000000000..f3c5e1683 --- /dev/null +++ b/SOURCES/1223-ice-fix-null-pointer-dereference-in-ice-reset-all-vfs.patch @@ -0,0 +1,122 @@ +From 54ef02487914c24170c7e1c061e45212dc55365e Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Mon, 27 Apr 2026 22:22:17 -0700 +Subject: [PATCH] ice: fix NULL pointer dereference in ice_reset_all_vfs() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ice_reset_all_vfs() ignores the return value of ice_vf_rebuild_vsi(). +When the VSI rebuild fails (e.g. during NVM firmware update via +nvmupdate64e), ice_vsi_rebuild() tears down the VSI on its error path, +leaving txq_map and rxq_map as NULL. The subsequent unconditional call +to ice_vf_post_vsi_rebuild() leads to a NULL pointer dereference in +ice_ena_vf_q_mappings() when it accesses vsi->txq_map[0]. + +The single-VF reset path in ice_reset_vf() already handles this +correctly by checking the return value of ice_vf_reconfig_vsi() and +skipping ice_vf_post_vsi_rebuild() on failure. + +Apply the same pattern to ice_reset_all_vfs(): check the return value +of ice_vf_rebuild_vsi() and skip ice_vf_post_vsi_rebuild() and +ice_eswitch_attach_vf() on failure. The VF is left safely disabled +(ICE_VF_STATE_INIT not set, VFGEN_RSTAT not set to VFACTIVE) and can +be recovered via a VFLR triggered by a PCI reset of the VF +(sysfs reset or driver rebind). + +Note that this patch does not prevent the VF VSI rebuild from failing +during NVM update — the underlying cause is firmware being in a +transitional state while the EMP reset is processed, which can cause +Admin Queue commands (ice_add_vsi, ice_cfg_vsi_lan) to fail. This +patch only prevents the subsequent NULL pointer dereference that +crashes the kernel when the rebuild does fail. + + crash> bt + PID: 50795 TASK: ff34c9ee708dc680 CPU: 1 COMMAND: "kworker/u512:5" + #0 [ff72159bcfe5bb50] machine_kexec at ffffffffaa8850ee + #1 [ff72159bcfe5bba8] __crash_kexec at ffffffffaaa15fba + #2 [ff72159bcfe5bc68] crash_kexec at ffffffffaaa16540 + #3 [ff72159bcfe5bc70] oops_end at ffffffffaa837eda + #4 [ff72159bcfe5bc90] page_fault_oops at ffffffffaa893997 + #5 [ff72159bcfe5bce8] exc_page_fault at ffffffffab528595 + #6 [ff72159bcfe5bd10] asm_exc_page_fault at ffffffffab600bb2 + [exception RIP: ice_ena_vf_q_mappings+0x79] + RIP: ffffffffc0a85b29 RSP: ff72159bcfe5bdc8 RFLAGS: 00010206 + RAX: 00000000000f0000 RBX: ff34c9efc9c00000 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: 0000000000000010 RDI: ff34c9efc9c00000 + RBP: ff34c9efc27d4828 R8: 0000000000000093 R9: 0000000000000040 + R10: ff34c9efc27d4828 R11: 0000000000000040 R12: 0000000000100000 + R13: 0000000000000010 R14: R15: + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + #7 [ff72159bcfe5bdf8] ice_sriov_post_vsi_rebuild at ffffffffc0a85e2e [ice] + #8 [ff72159bcfe5be08] ice_reset_all_vfs at ffffffffc0a920b4 [ice] + #9 [ff72159bcfe5be48] ice_service_task at ffffffffc0a31519 [ice] + #10 [ff72159bcfe5be88] process_one_work at ffffffffaa93dca4 + #11 [ff72159bcfe5bec8] worker_thread at ffffffffaa93e9de + #12 [ff72159bcfe5bf18] kthread at ffffffffaa946663 + #13 [ff72159bcfe5bf50] ret_from_fork at ffffffffaa8086b9 + + The panic occurs attempting to dereference the NULL pointer in RDX at + ice_sriov.c:294, which loads vsi->txq_map (offset 0x4b8 in ice_vsi). + + The faulting VSI is an allocated slab object but not fully initialized + after a failed ice_vsi_rebuild(): + + crash> struct ice_vsi 0xff34c9efc27d4828 + netdev = 0x0, + rx_rings = 0x0, + tx_rings = 0x0, + q_vectors = 0x0, + txq_map = 0x0, + rxq_map = 0x0, + alloc_txq = 0x10, + num_txq = 0x10, + alloc_rxq = 0x10, + num_rxq = 0x10, + + The nvmupdate64e process was performing NVM firmware update: + + crash> bt 0xff34c9edd1a30000 + PID: 49858 TASK: ff34c9edd1a30000 CPU: 1 COMMAND: "nvmupdate64e" + #0 [ff72159bcd617618] __schedule at ffffffffab5333f8 + #4 [ff72159bcd617750] ice_sq_send_cmd at ffffffffc0a35347 [ice] + #5 [ff72159bcd6177a8] ice_sq_send_cmd_retry at ffffffffc0a35b47 [ice] + #6 [ff72159bcd617810] ice_aq_send_cmd at ffffffffc0a38018 [ice] + #7 [ff72159bcd617848] ice_aq_read_nvm at ffffffffc0a40254 [ice] + #8 [ff72159bcd6178b8] ice_read_flat_nvm at ffffffffc0a4034c [ice] + #9 [ff72159bcd617918] ice_devlink_nvm_snapshot at ffffffffc0a6ffa5 [ice] + + dmesg: + ice 0000:13:00.0: firmware recommends not updating fw.mgmt, as it + may result in a downgrade. continuing anyways + ice 0000:13:00.1: ice_init_nvm failed -5 + ice 0000:13:00.1: Rebuild failed, unload and reload driver + +Fixes: 12bb018c538c ("ice: Refactor VF reset") +Signed-off-by: Petr Oros +Tested-by: Rafal Romanowski +Signed-off-by: Jacob Keller +Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-5-cdcb48303fd8@intel.com +Signed-off-by: Paolo Abeni + +diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c +index 772f6b07340d..b1f46707dcc0 100644 +--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c ++++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c +@@ -804,7 +804,12 @@ void ice_reset_all_vfs(struct ice_pf *pf) + ice_vf_ctrl_invalidate_vsi(vf); + + ice_vf_pre_vsi_rebuild(vf); +- ice_vf_rebuild_vsi(vf); ++ if (ice_vf_rebuild_vsi(vf)) { ++ dev_err(dev, "VF %u VSI rebuild failed, leaving VF disabled\n", ++ vf->vf_id); ++ mutex_unlock(&vf->cfg_lock); ++ continue; ++ } + ice_vf_post_vsi_rebuild(vf); + + ice_eswitch_attach_vf(pf, vf); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1224-ice-fix-missing-sma-pin-initialization-in-dpll-subsystem.patch b/SOURCES/1224-ice-fix-missing-sma-pin-initialization-in-dpll-subsystem.patch new file mode 100644 index 000000000..a012174cc --- /dev/null +++ b/SOURCES/1224-ice-fix-missing-sma-pin-initialization-in-dpll-subsystem.patch @@ -0,0 +1,80 @@ +From 56a643aed0f0af5c29ebb4593d4917b78344dd48 Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Mon, 27 Apr 2026 22:22:19 -0700 +Subject: [PATCH] ice: fix missing SMA pin initialization in DPLL subsystem +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The DPLL SMA/U.FL pin redesign introduced ice_dpll_sw_pin_frequency_get() +which gates frequency reporting on the pin's active flag. This flag is +determined by ice_dpll_sw_pins_update() from the PCA9575 GPIO expander +state. Before the redesign, SMA pins were exposed as direct HW +input/output pins and ice_dpll_frequency_get() returned the CGU +frequency unconditionally — the PCA9575 state was never consulted. + +The PCA9575 powers on with all outputs high, setting ICE_SMA1_DIR_EN, +ICE_SMA1_TX_EN, ICE_SMA2_DIR_EN and ICE_SMA2_TX_EN. Nothing in the +driver writes the register during initialization, so +ice_dpll_sw_pins_update() sees all pins as inactive and +ice_dpll_sw_pin_frequency_get() permanently returns 0 Hz for every +SW pin. + +Fix this by writing a default SMA configuration in +ice_dpll_init_info_sw_pins(): clear all SMA bits, then set SMA1 and +SMA2 as active inputs (DIR_EN=0) with U.FL1 output and U.FL2 input +disabled. Each SMA/U.FL pair shares a physical signal path so only +one pin per pair can be active at a time. U.FL pins still report +frequency 0 after this fix: U.FL1 (output-only) is disabled by +ICE_SMA1_TX_EN which keeps the TX output buffer off, and U.FL2 +(input-only) is disabled by ICE_SMA2_UFL2_RX_DIS. They can be +activated by changing the corresponding SMA pin direction via dpll +netlink. + +Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control") +Signed-off-by: Petr Oros +Reviewed-by: Ivan Vecera +Reviewed-by: Arkadiusz Kubalewski +Tested-by: Alexander Nowlin +Signed-off-by: Jacob Keller +Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-7-cdcb48303fd8@intel.com +Signed-off-by: Paolo Abeni + +diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c +index 62f75701d652..498ec2c045f3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_dpll.c ++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c +@@ -4014,6 +4014,7 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf) + struct ice_dpll_pin *pin; + u32 phase_adj_max, caps; + int i, ret; ++ u8 data; + + if (pf->hw.device_id == ICE_DEV_ID_E810C_QSFP) + input_idx_offset = ICE_E810_RCLK_PINS_NUM; +@@ -4073,6 +4074,22 @@ static int ice_dpll_init_info_sw_pins(struct ice_pf *pf) + } + ice_dpll_phase_range_set(&pin->prop.phase_range, phase_adj_max); + } ++ ++ /* Initialize the SMA control register to a known-good default state. ++ * Without this write the PCA9575 GPIO expander retains its power-on ++ * default (all outputs high) which makes all SW pins appear inactive. ++ * Set SMA1 and SMA2 as active inputs, disable U.FL1 output and ++ * U.FL2 input. ++ */ ++ ret = ice_read_sma_ctrl(&pf->hw, &data); ++ if (ret) ++ return ret; ++ data &= ~ICE_ALL_SMA_MASK; ++ data |= ICE_SMA1_TX_EN | ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS; ++ ret = ice_write_sma_ctrl(&pf->hw, data); ++ if (ret) ++ return ret; ++ + ret = ice_dpll_pin_state_update(pf, pin, ICE_DPLL_PIN_TYPE_SOFTWARE, + NULL); + if (ret) +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1225-ice-fix-sma-and-u-fl-pin-state-changes-affecting-paired-pin.patch b/SOURCES/1225-ice-fix-sma-and-u-fl-pin-state-changes-affecting-paired-pin.patch new file mode 100644 index 000000000..b982f3825 --- /dev/null +++ b/SOURCES/1225-ice-fix-sma-and-u-fl-pin-state-changes-affecting-paired-pin.patch @@ -0,0 +1,132 @@ +From 6f9d8393c9f50fbc68b9c9e99f78ca5a7b43ff44 Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Mon, 27 Apr 2026 22:22:20 -0700 +Subject: [PATCH] ice: fix SMA and U.FL pin state changes affecting paired pin + +SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and +SMA2/U.FL2) controlled by the PCA9575 GPIO expander. Each pair can +only have one active pin at a time: SMA1 output and U.FL1 output share +the same CGU output, SMA2 input and U.FL2 input share the same CGU +input. The PCA9575 register bits determine which connector in each +pair owns the signal path. + +The driver does not account for this pairing in two places: + +ice_dpll_ufl_pin_state_set() modifies PCA9575 bits and disables the +backing CGU pin without checking whether the U.FL pin is currently +active. Disconnecting an already inactive U.FL pin flips bits that +the paired SMA pin relies on, breaking its connection. + +ice_dpll_sma_direction_set() does not propagate direction changes to +the paired U.FL pin. For SMA2/U.FL2 the ICE_SMA2_UFL2_RX_DIS bit is +never managed, so U.FL2 stays disconnected after SMA2 switches to +output. For both pairs the backing CGU pin of the U.FL side is never +enabled when a direction change activates it, so userspace sees the +pin as disconnected even though the routing is correct. + +Fix by guarding the U.FL disconnect path against inactive pins and by +updating the paired U.FL pin fully on SMA direction changes: manage +ICE_SMA2_UFL2_RX_DIS for the SMA2/U.FL2 pair and enable the backing +CGU pin whenever the peer becomes active. + +Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control") +Signed-off-by: Petr Oros +Tested-by: Alexander Nowlin +Reviewed-by: Arkadiusz Kubalewski +Signed-off-by: Jacob Keller +Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-8-cdcb48303fd8@intel.com +Signed-off-by: Paolo Abeni + +diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c +index 498ec2c045f3..3f8cd5b8298b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_dpll.c ++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c +@@ -1171,6 +1171,8 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, + enum dpll_pin_direction direction, + struct netlink_ext_ack *extack) + { ++ struct ice_dplls *d = &p->pf->dplls; ++ struct ice_dpll_pin *peer; + u8 data; + int ret; + +@@ -1189,8 +1191,9 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, + case ICE_DPLL_PIN_SW_2_IDX: + if (direction == DPLL_PIN_DIRECTION_INPUT) { + data &= ~ICE_SMA2_DIR_EN; ++ data |= ICE_SMA2_UFL2_RX_DIS; + } else { +- data &= ~ICE_SMA2_TX_EN; ++ data &= ~(ICE_SMA2_TX_EN | ICE_SMA2_UFL2_RX_DIS); + data |= ICE_SMA2_DIR_EN; + } + break; +@@ -1202,6 +1205,34 @@ static int ice_dpll_sma_direction_set(struct ice_dpll_pin *p, + ret = ice_dpll_pin_state_update(p->pf, p, + ICE_DPLL_PIN_TYPE_SOFTWARE, + extack); ++ if (ret) ++ return ret; ++ ++ /* When a direction change activates the paired U.FL pin, enable ++ * its backing CGU pin so the pin reports as connected. Without ++ * this the U.FL routing is correct but the CGU pin stays disabled ++ * and userspace sees the pin as disconnected. Do not disable the ++ * backing pin when U.FL becomes inactive because the SMA pin may ++ * still be using it. ++ */ ++ peer = &d->ufl[p->idx]; ++ if (peer->active) { ++ struct ice_dpll_pin *target; ++ enum ice_dpll_pin_type type; ++ ++ if (peer->output) { ++ target = peer->output; ++ type = ICE_DPLL_PIN_TYPE_OUTPUT; ++ } else { ++ target = peer->input; ++ type = ICE_DPLL_PIN_TYPE_INPUT; ++ } ++ ret = ice_dpll_pin_enable(&p->pf->hw, target, ++ d->eec.dpll_idx, type, extack); ++ if (!ret) ++ ret = ice_dpll_pin_state_update(p->pf, target, ++ type, extack); ++ } + + return ret; + } +@@ -1253,6 +1284,14 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, + data &= ~ICE_SMA1_MASK; + enable = true; + } else if (state == DPLL_PIN_STATE_DISCONNECTED) { ++ /* Skip if U.FL1 is not active, setting TX_EN ++ * while DIR_EN is set would also deactivate ++ * the paired SMA1 output. ++ */ ++ if (data & (ICE_SMA1_DIR_EN | ICE_SMA1_TX_EN)) { ++ ret = 0; ++ goto unlock; ++ } + data |= ICE_SMA1_TX_EN; + enable = false; + } else { +@@ -1267,6 +1306,15 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, + data &= ~ICE_SMA2_UFL2_RX_DIS; + enable = true; + } else if (state == DPLL_PIN_STATE_DISCONNECTED) { ++ /* Skip if U.FL2 is not active, setting ++ * UFL2_RX_DIS could also disable the paired ++ * SMA2 input. ++ */ ++ if (!(data & ICE_SMA2_DIR_EN) || ++ (data & ICE_SMA2_UFL2_RX_DIS)) { ++ ret = 0; ++ goto unlock; ++ } + data |= ICE_SMA2_UFL2_RX_DIS; + enable = false; + } else { +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1226-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch b/SOURCES/1226-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch new file mode 100644 index 000000000..f2832bdce --- /dev/null +++ b/SOURCES/1226-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch @@ -0,0 +1,72 @@ +From 620055cb1036a6125fd912e7a14b47a6572b809b Mon Sep 17 00:00:00 2001 +From: Ivan Vecera +Date: Mon, 27 Apr 2026 22:22:21 -0700 +Subject: [PATCH] dpll: export __dpll_pin_change_ntf() for use under dpll_lock + +Export __dpll_pin_change_ntf() so that drivers can send pin change +notifications from within pin callbacks, which are already called +under dpll_lock. Using dpll_pin_change_ntf() in that context would +deadlock. + +Add lockdep_assert_held() to catch misuse without the lock held. + +Acked-by: Vadim Fedorenko +Signed-off-by: Ivan Vecera +Signed-off-by: Petr Oros +Tested-by: Alexander Nowlin +Reviewed-by: Arkadiusz Kubalewski +Signed-off-by: Jacob Keller +Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-9-cdcb48303fd8@intel.com +Signed-off-by: Paolo Abeni + +diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c +index af7ce62ec55c..0ff1658c2dc1 100644 +--- a/drivers/dpll/dpll_netlink.c ++++ b/drivers/dpll/dpll_netlink.c +@@ -900,11 +900,21 @@ int dpll_pin_delete_ntf(struct dpll_pin *pin) + return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin); + } + ++/** ++ * __dpll_pin_change_ntf - notify that the pin has been changed ++ * @pin: registered pin pointer ++ * ++ * Context: caller must hold dpll_lock. Suitable for use inside pin ++ * callbacks which are already invoked under dpll_lock. ++ * Return: 0 if succeeds, error code otherwise. ++ */ + int __dpll_pin_change_ntf(struct dpll_pin *pin) + { ++ lockdep_assert_held(&dpll_lock); + dpll_pin_notify(pin, DPLL_PIN_CHANGED); + return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin); + } ++EXPORT_SYMBOL_GPL(__dpll_pin_change_ntf); + + /** + * dpll_pin_change_ntf - notify that the pin has been changed +diff --git a/drivers/dpll/dpll_netlink.h b/drivers/dpll/dpll_netlink.h +index dd28b56d27c5..a9cfd55f57fc 100644 +--- a/drivers/dpll/dpll_netlink.h ++++ b/drivers/dpll/dpll_netlink.h +@@ -11,5 +11,3 @@ int dpll_device_delete_ntf(struct dpll_device *dpll); + int dpll_pin_create_ntf(struct dpll_pin *pin); + + int dpll_pin_delete_ntf(struct dpll_pin *pin); +- +-int __dpll_pin_change_ntf(struct dpll_pin *pin); +diff --git a/include/linux/dpll.h b/include/linux/dpll.h +index b7277a8b484d..f8037f1ab20b 100644 +--- a/include/linux/dpll.h ++++ b/include/linux/dpll.h +@@ -286,6 +286,7 @@ int dpll_pin_ref_sync_pair_add(struct dpll_pin *pin, + + int dpll_device_change_ntf(struct dpll_device *dpll); + ++int __dpll_pin_change_ntf(struct dpll_pin *pin); + int dpll_pin_change_ntf(struct dpll_pin *pin); + + int register_dpll_notifier(struct notifier_block *nb); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1227-ice-fix-missing-dpll-notifications-for-sw-pins.patch b/SOURCES/1227-ice-fix-missing-dpll-notifications-for-sw-pins.patch new file mode 100644 index 000000000..e2ce7e42e --- /dev/null +++ b/SOURCES/1227-ice-fix-missing-dpll-notifications-for-sw-pins.patch @@ -0,0 +1,149 @@ +From 1a41b58fd4dc80dca16c717e6e77c88b9d4e83a7 Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Mon, 27 Apr 2026 22:22:22 -0700 +Subject: [PATCH] ice: fix missing dpll notifications for SW pins + +The SMA/U.FL pin redesign (commit 2dd5d03c77e2 ("ice: redesign dpll +sma/u.fl pins control")) introduced software-controlled pins that wrap +backing CGU input/output pins, but never updated the notification and +data paths to propagate pin events to these SW wrappers. + +The periodic work sends dpll_pin_change_ntf() only for direct CGU input +pins. SW pins that wrap these inputs never receive change or phase +offset notifications, so userspace consumers such as synce4l monitoring +SMA pins via dpll netlink never learn about state transitions or phase +offset updates. Similarly, ice_dpll_phase_offset_get() reads the SW +pin's own phase_offset field which is never updated; the PPS monitor +writes to the backing CGU input's field instead. + +Fix by introducing ice_dpll_pin_ntf(), a wrapper around +dpll_pin_change_ntf() that also notifies any registered SMA/U.FL pin +whose backing CGU input matches. Replace all direct +dpll_pin_change_ntf() calls in the periodic notification paths with +this wrapper. Fix ice_dpll_phase_offset_get() to return the backing +CGU input's phase_offset for input-direction SW pins. + +Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control") +Signed-off-by: Petr Oros +Tested-by: Alexander Nowlin +Reviewed-by: Arkadiusz Kubalewski +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Ivan Vecera +Signed-off-by: Jacob Keller +Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-10-cdcb48303fd8@intel.com +Signed-off-by: Paolo Abeni + +diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c +index 3f8cd5b8298b..721a3f4d6a28 100644 +--- a/drivers/net/ethernet/intel/ice/ice_dpll.c ++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c +@@ -1963,7 +1963,10 @@ ice_dpll_phase_offset_get(const struct dpll_pin *pin, void *pin_priv, + d->active_input == p->input->pin)) + *phase_offset = d->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR; + else if (d->phase_offset_monitor_period) +- *phase_offset = p->phase_offset * ICE_DPLL_PHASE_OFFSET_FACTOR; ++ *phase_offset = (p->input && ++ p->direction == DPLL_PIN_DIRECTION_INPUT ? ++ p->input->phase_offset : ++ p->phase_offset) * ICE_DPLL_PHASE_OFFSET_FACTOR; + else + *phase_offset = 0; + mutex_unlock(&pf->dplls.lock); +@@ -2657,6 +2660,27 @@ static u64 ice_generate_clock_id(struct ice_pf *pf) + return pci_get_dsn(pf->pdev); + } + ++/** ++ * ice_dpll_pin_ntf - notify pin change including any SW pin wrappers ++ * @dplls: pointer to dplls struct ++ * @pin: the dpll_pin that changed ++ * ++ * Send a change notification for @pin and for any registered SMA/U.FL pin ++ * whose backing CGU input matches @pin. ++ */ ++static void ice_dpll_pin_ntf(struct ice_dplls *dplls, struct dpll_pin *pin) ++{ ++ dpll_pin_change_ntf(pin); ++ for (int i = 0; i < ICE_DPLL_PIN_SW_NUM; i++) { ++ if (dplls->sma[i].pin && dplls->sma[i].input && ++ dplls->sma[i].input->pin == pin) ++ dpll_pin_change_ntf(dplls->sma[i].pin); ++ if (dplls->ufl[i].pin && dplls->ufl[i].input && ++ dplls->ufl[i].input->pin == pin) ++ dpll_pin_change_ntf(dplls->ufl[i].pin); ++ } ++} ++ + /** + * ice_dpll_notify_changes - notify dpll subsystem about changes + * @d: pointer do dpll +@@ -2665,6 +2689,7 @@ static u64 ice_generate_clock_id(struct ice_pf *pf) + */ + static void ice_dpll_notify_changes(struct ice_dpll *d) + { ++ struct ice_dplls *dplls = &d->pf->dplls; + bool pin_notified = false; + + if (d->prev_dpll_state != d->dpll_state) { +@@ -2673,17 +2698,17 @@ static void ice_dpll_notify_changes(struct ice_dpll *d) + } + if (d->prev_input != d->active_input) { + if (d->prev_input) +- dpll_pin_change_ntf(d->prev_input); ++ ice_dpll_pin_ntf(dplls, d->prev_input); + d->prev_input = d->active_input; + if (d->active_input) { +- dpll_pin_change_ntf(d->active_input); ++ ice_dpll_pin_ntf(dplls, d->active_input); + pin_notified = true; + } + } + if (d->prev_phase_offset != d->phase_offset) { + d->prev_phase_offset = d->phase_offset; + if (!pin_notified && d->active_input) +- dpll_pin_change_ntf(d->active_input); ++ ice_dpll_pin_ntf(dplls, d->active_input); + } + } + +@@ -2712,6 +2737,7 @@ static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf) + + /** + * ice_dpll_pins_notify_mask - notify dpll subsystem about bulk pin changes ++ * @dplls: pointer to dplls struct + * @pins: array of ice_dpll_pin pointers registered within dpll subsystem + * @pin_num: number of pins + * @phase_offset_ntf_mask: bitmask of pin indexes to notify +@@ -2721,15 +2747,14 @@ static bool ice_dpll_is_pps_phase_monitor(struct ice_pf *pf) + * + * Context: Must be called while pf->dplls.lock is released. + */ +-static void ice_dpll_pins_notify_mask(struct ice_dpll_pin *pins, ++static void ice_dpll_pins_notify_mask(struct ice_dplls *dplls, ++ struct ice_dpll_pin *pins, + u8 pin_num, + u32 phase_offset_ntf_mask) + { +- int i = 0; +- +- for (i = 0; i < pin_num; i++) +- if (phase_offset_ntf_mask & (1 << i)) +- dpll_pin_change_ntf(pins[i].pin); ++ for (int i = 0; i < pin_num; i++) ++ if (phase_offset_ntf_mask & BIT(i)) ++ ice_dpll_pin_ntf(dplls, pins[i].pin); + } + + /** +@@ -2905,7 +2930,7 @@ static void ice_dpll_periodic_work(struct kthread_work *work) + ice_dpll_notify_changes(de); + ice_dpll_notify_changes(dp); + if (phase_offset_ntf) +- ice_dpll_pins_notify_mask(d->inputs, d->num_inputs, ++ ice_dpll_pins_notify_mask(d, d->inputs, d->num_inputs, + phase_offset_ntf); + + resched: +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1228-ice-add-dpll-peer-notification-for-paired-sma-and-u-fl-pins.patch b/SOURCES/1228-ice-add-dpll-peer-notification-for-paired-sma-and-u-fl-pins.patch new file mode 100644 index 000000000..989bd8121 --- /dev/null +++ b/SOURCES/1228-ice-add-dpll-peer-notification-for-paired-sma-and-u-fl-pins.patch @@ -0,0 +1,93 @@ +From 9e5dead140af10e8b5f975b8f04e46197d48d274 Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Mon, 27 Apr 2026 22:22:23 -0700 +Subject: [PATCH] ice: add dpll peer notification for paired SMA and U.FL pins + +SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and +SMA2/U.FL2). When one pin's state changes via a PCA9575 GPIO write, +the paired pin's state also changes, but no notification is sent for +the peer pin. Userspace consumers monitoring the peer via dpll netlink +subscribe never learn about the update. + +Add ice_dpll_sw_pin_notify_peer() which sends a change notification for +the paired SW pin. Call it from ice_dpll_pin_sma_direction_set(), +ice_dpll_sma_pin_state_set(), and ice_dpll_ufl_pin_state_set() after +pf->dplls.lock is released. Use __dpll_pin_change_ntf() because +dpll_lock is still held by the dpll netlink layer (dpll_pin_pre_doit). + +Fixes: 2dd5d03c77e2 ("ice: redesign dpll sma/u.fl pins control") +Signed-off-by: Petr Oros +Tested-by: Alexander Nowlin +Reviewed-by: Arkadiusz Kubalewski +Reviewed-by: Aleksandr Loktionov +Signed-off-by: Jacob Keller +Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-11-cdcb48303fd8@intel.com +Signed-off-by: Paolo Abeni + +diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c +index 721a3f4d6a28..27b460926bac 100644 +--- a/drivers/net/ethernet/intel/ice/ice_dpll.c ++++ b/drivers/net/ethernet/intel/ice/ice_dpll.c +@@ -1154,6 +1154,32 @@ ice_dpll_input_state_get(const struct dpll_pin *pin, void *pin_priv, + extack, ICE_DPLL_PIN_TYPE_INPUT); + } + ++/** ++ * ice_dpll_sw_pin_notify_peer - notify the paired SW pin after a state change ++ * @d: pointer to dplls struct ++ * @changed: the SW pin that was explicitly changed (already notified by dpll core) ++ * ++ * SMA and U.FL pins share physical signal paths in pairs (SMA1/U.FL1 and ++ * SMA2/U.FL2). When one pin's routing changes via the PCA9575 GPIO ++ * expander, the paired pin's state may also change. Send a change ++ * notification for the peer pin so userspace consumers monitoring the ++ * peer via dpll netlink learn about the update. ++ * ++ * Context: Called from dpll_pin_ops callbacks after pf->dplls.lock is ++ * released. Uses __dpll_pin_change_ntf() because dpll_lock is ++ * still held by the dpll netlink layer. ++ */ ++static void ice_dpll_sw_pin_notify_peer(struct ice_dplls *d, ++ struct ice_dpll_pin *changed) ++{ ++ struct ice_dpll_pin *peer; ++ ++ peer = (changed >= d->sma && changed < d->sma + ICE_DPLL_PIN_SW_NUM) ? ++ &d->ufl[changed->idx] : &d->sma[changed->idx]; ++ if (peer->pin) ++ __dpll_pin_change_ntf(peer->pin); ++} ++ + /** + * ice_dpll_sma_direction_set - set direction of SMA pin + * @p: pointer to a pin +@@ -1344,6 +1370,8 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv, + + unlock: + mutex_unlock(&pf->dplls.lock); ++ if (!ret) ++ ice_dpll_sw_pin_notify_peer(&pf->dplls, p); + + return ret; + } +@@ -1462,6 +1490,8 @@ ice_dpll_sma_pin_state_set(const struct dpll_pin *pin, void *pin_priv, + + unlock: + mutex_unlock(&pf->dplls.lock); ++ if (!ret) ++ ice_dpll_sw_pin_notify_peer(&pf->dplls, sma); + + return ret; + } +@@ -1657,6 +1687,8 @@ ice_dpll_pin_sma_direction_set(const struct dpll_pin *pin, void *pin_priv, + mutex_lock(&pf->dplls.lock); + ret = ice_dpll_sma_direction_set(p, direction, extack); + mutex_unlock(&pf->dplls.lock); ++ if (!ret) ++ ice_dpll_sw_pin_notify_peer(&pf->dplls, p); + + return ret; + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1229-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch b/SOURCES/1229-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch new file mode 100644 index 000000000..db84b5f88 --- /dev/null +++ b/SOURCES/1229-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch @@ -0,0 +1,123 @@ +From 43b9c8ac43d8d75a29ff462fc38a362284472817 Mon Sep 17 00:00:00 2001 +From: Mete Durlu +Date: Fri, 20 Mar 2026 15:10:30 +0100 +Subject: [PATCH] s390/pci: Avoid deadlock between PCI error recovery and mlx5 + crdump + +JIRA: https://issues.redhat.com/browse/RHEL-157931 + +commit 0fd20f65df6aa430454a0deed8f43efa91c54835 +Author: Gerd Bayer +Date: Thu Oct 16 11:27:03 2025 +0200 + + s390/pci: Avoid deadlock between PCI error recovery and mlx5 crdump + + Do not block PCI config accesses through pci_cfg_access_lock() when + executing the s390 variant of PCI error recovery: Acquire just + device_lock() instead of pci_dev_lock() as powerpc's EEH and + generig PCI AER processing do. + + During error recovery testing a pair of tasks was reported to be hung: + + mlx5_core 0000:00:00.1: mlx5_health_try_recover:338:(pid 5553): health recovery flow aborted, PCI reads still not working + INFO: task kmcheck:72 blocked for more than 122 seconds. + Not tainted 5.14.0-570.12.1.bringup7.el9.s390x #1 + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + task:kmcheck state:D stack:0 pid:72 tgid:72 ppid:2 flags:0x00000000 + Call Trace: + [<000000065256f030>] __schedule+0x2a0/0x590 + [<000000065256f356>] schedule+0x36/0xe0 + [<000000065256f572>] schedule_preempt_disabled+0x22/0x30 + [<0000000652570a94>] __mutex_lock.constprop.0+0x484/0x8a8 + [<000003ff800673a4>] mlx5_unload_one+0x34/0x58 [mlx5_core] + [<000003ff8006745c>] mlx5_pci_err_detected+0x94/0x140 [mlx5_core] + [<0000000652556c5a>] zpci_event_attempt_error_recovery+0xf2/0x398 + [<0000000651b9184a>] __zpci_event_error+0x23a/0x2c0 + INFO: task kworker/u1664:6:1514 blocked for more than 122 seconds. + Not tainted 5.14.0-570.12.1.bringup7.el9.s390x #1 + "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. + task:kworker/u1664:6 state:D stack:0 pid:1514 tgid:1514 ppid:2 flags:0x00000000 + Workqueue: mlx5_health0000:00:00.0 mlx5_fw_fatal_reporter_err_work [mlx5_core] + Call Trace: + [<000000065256f030>] __schedule+0x2a0/0x590 + [<000000065256f356>] schedule+0x36/0xe0 + [<0000000652172e28>] pci_wait_cfg+0x80/0xe8 + [<0000000652172f94>] pci_cfg_access_lock+0x74/0x88 + [<000003ff800916b6>] mlx5_vsc_gw_lock+0x36/0x178 [mlx5_core] + [<000003ff80098824>] mlx5_crdump_collect+0x34/0x1c8 [mlx5_core] + [<000003ff80074b62>] mlx5_fw_fatal_reporter_dump+0x6a/0xe8 [mlx5_core] + [<0000000652512242>] devlink_health_do_dump.part.0+0x82/0x168 + [<0000000652513212>] devlink_health_report+0x19a/0x230 + [<000003ff80075a12>] mlx5_fw_fatal_reporter_err_work+0xba/0x1b0 [mlx5_core] + + No kernel log of the exact same error with an upstream kernel is + available - but the very same deadlock situation can be constructed there, + too: + + - task: kmcheck + mlx5_unload_one() tries to acquire devlink lock while the PCI error + recovery code has set pdev->block_cfg_access by way of + pci_cfg_access_lock() + - task: kworker + mlx5_crdump_collect() tries to set block_cfg_access through + pci_cfg_access_lock() while devlink_health_report() had acquired + the devlink lock. + + A similar deadlock situation can be reproduced by requesting a + crdump with + > devlink health dump show pci/ reporter fw_fatal + + while PCI error recovery is executed on the same physical function + by mlx5_core's pci_error_handlers. On s390 this can be injected with + > zpcictl --reset-fw + + Tests with this patch failed to reproduce that second deadlock situation, + the devlink command is rejected with "kernel answers: Permission denied" - + and we get a kernel log message of: + + mlx5_core 1ed0:00:00.1: mlx5_crdump_collect:50:(pid 254382): crdump: failed to lock vsc gw err -5 + + because the config read of VSC_SEMAPHORE is rejected by the underlying + hardware. + + Two prior attempts to address this issue have been discussed and + ultimately rejected [see link], with the primary argument that s390's + implementation of PCI error recovery is imposing restrictions that + neither powerpc's EEH nor PCI AER handling need. Tests show that PCI + error recovery on s390 is running to completion even without blocking + access to PCI config space. + + Link: https://lore.kernel.org/all/20251007144826.2825134-1-gbayer@linux.ibm.com/ + Cc: stable@vger.kernel.org + Fixes: 4cdf2f4e24ff ("s390/pci: implement minimal PCI error recovery") + Reviewed-by: Niklas Schnelle + Signed-off-by: Gerd Bayer + Signed-off-by: Heiko Carstens + +Signed-off-by: Mete Durlu + +diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c +index d930416d4c90..da0de34d2e5c 100644 +--- a/arch/s390/pci/pci_event.c ++++ b/arch/s390/pci/pci_event.c +@@ -187,7 +187,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev) + * is unbound or probed and that userspace can't access its + * configuration space while we perform recovery. + */ +- pci_dev_lock(pdev); ++ device_lock(&pdev->dev); + if (pdev->error_state == pci_channel_io_perm_failure) { + ers_res = PCI_ERS_RESULT_DISCONNECT; + goto out_unlock; +@@ -254,7 +254,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev) + if (driver->err_handler->resume) + driver->err_handler->resume(pdev); + out_unlock: +- pci_dev_unlock(pdev); ++ device_unlock(&pdev->dev); + zpci_report_status(zdev, "recovery", status_str); + + return ers_res; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1230-netfilter-nf-conntrack-helper-pass-helper-to-expect-cleanup.patch b/SOURCES/1230-netfilter-nf-conntrack-helper-pass-helper-to-expect-cleanup.patch new file mode 100644 index 000000000..08756c6ab --- /dev/null +++ b/SOURCES/1230-netfilter-nf-conntrack-helper-pass-helper-to-expect-cleanup.patch @@ -0,0 +1,66 @@ +From 35ad416bb63cdbaf389d758699fad43ac0e7995c Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 1 May 2026 17:38:22 +0000 +Subject: [PATCH] netfilter: nf_conntrack_helper: pass helper to expect cleanup + +JIRA: https://redhat.atlassian.net/browse/RHEL-172621 +CVE: CVE-2026-43027 + +commit a242a9ae58aa46ff7dae51ce64150a93957abe65 +Author: Qi Tang +Date: Mon Mar 30 00:50:36 2026 +0800 + + netfilter: nf_conntrack_helper: pass helper to expect cleanup + + nf_conntrack_helper_unregister() calls nf_ct_expect_iterate_destroy() + to remove expectations belonging to the helper being unregistered. + However, it passes NULL instead of the helper pointer as the data + argument, so expect_iter_me() never matches any expectation and all + of them survive the cleanup. + + After unregister returns, nfnl_cthelper_del() frees the helper + object immediately. Subsequent expectation dumps or packet-driven + init_conntrack() calls then dereference the freed exp->helper, + causing a use-after-free. + + Pass the actual helper pointer so expectations referencing it are + properly destroyed before the helper object is freed. + + BUG: KASAN: slab-use-after-free in string+0x38f/0x430 + Read of size 1 at addr ffff888003b14d20 by task poc/103 + Call Trace: + string+0x38f/0x430 + vsnprintf+0x3cc/0x1170 + seq_printf+0x17a/0x240 + exp_seq_show+0x2e5/0x560 + seq_read_iter+0x419/0x1280 + proc_reg_read+0x1ac/0x270 + vfs_read+0x179/0x930 + ksys_read+0xef/0x1c0 + Freed by task 103: + The buggy address is located 32 bytes inside of + freed 192-byte region [ffff888003b14d00, ffff888003b14dc0) + + Fixes: ac7b84839003 ("netfilter: expect: add and use nf_ct_expect_iterate helpers") + Signed-off-by: Qi Tang + Reviewed-by: Phil Sutter + Signed-off-by: Pablo Neira Ayuso + +Signed-off-by: CKI Backport Bot + +diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c +index b0ac1604600f..cc44b8f443cb 100644 +--- a/net/netfilter/nf_conntrack_helper.c ++++ b/net/netfilter/nf_conntrack_helper.c +@@ -468,7 +468,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) + */ + synchronize_rcu(); + +- nf_ct_expect_iterate_destroy(expect_iter_me, NULL); ++ nf_ct_expect_iterate_destroy(expect_iter_me, me); + nf_ct_iterate_destroy(unhelp, me); + } + EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1231-hid-wacom-fix-out-of-bounds-read-in-wacom-intuos-bt-irq.patch b/SOURCES/1231-hid-wacom-fix-out-of-bounds-read-in-wacom-intuos-bt-irq.patch new file mode 100644 index 000000000..f6e117346 --- /dev/null +++ b/SOURCES/1231-hid-wacom-fix-out-of-bounds-read-in-wacom-intuos-bt-irq.patch @@ -0,0 +1,63 @@ +From 87c5d4848ddc5c9e1a1d7fe5950b12ab0a601e5a Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 1 May 2026 18:54:54 +0000 +Subject: [PATCH] HID: wacom: fix out-of-bounds read in wacom_intuos_bt_irq +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +JIRA: https://redhat.atlassian.net/browse/RHEL-172741 +CVE: CVE-2026-43051 + +commit 2f1763f62909ccb6386ac50350fa0abbf5bb16a9 +Author: Benoît Sevens +Date: Tue Mar 3 13:58:28 2026 +0000 + + HID: wacom: fix out-of-bounds read in wacom_intuos_bt_irq + + The wacom_intuos_bt_irq() function processes Bluetooth HID reports + without sufficient bounds checking. A maliciously crafted short report + can trigger an out-of-bounds read when copying data into the wacom + structure. + + Specifically, report 0x03 requires at least 22 bytes to safely read + the processed data and battery status, while report 0x04 (which + falls through to 0x03) requires 32 bytes. + + Add explicit length checks for these report IDs and log a warning if + a short report is received. + + Signed-off-by: Benoît Sevens + Reviewed-by: Jason Gerecke + Signed-off-by: Jiri Kosina + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c +index 955b39d22524..da6e7410ee34 100644 +--- a/drivers/hid/wacom_wac.c ++++ b/drivers/hid/wacom_wac.c +@@ -1207,10 +1207,20 @@ static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len) + + switch (data[0]) { + case 0x04: ++ if (len < 32) { ++ dev_warn(wacom->pen_input->dev.parent, ++ "Report 0x04 too short: %zu bytes\n", len); ++ break; ++ } + wacom_intuos_bt_process_data(wacom, data + i); + i += 10; + fallthrough; + case 0x03: ++ if (i == 1 && len < 22) { ++ dev_warn(wacom->pen_input->dev.parent, ++ "Report 0x03 too short: %zu bytes\n", len); ++ break; ++ } + wacom_intuos_bt_process_data(wacom, data + i); + i += 10; + wacom_intuos_bt_process_data(wacom, data + i); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1232-redhat-configs-enable-config-sclp-ofb-for-s390x.patch b/SOURCES/1232-redhat-configs-enable-config-sclp-ofb-for-s390x.patch new file mode 100644 index 000000000..d8c8292ae --- /dev/null +++ b/SOURCES/1232-redhat-configs-enable-config-sclp-ofb-for-s390x.patch @@ -0,0 +1,20 @@ +From 01a86b8bb27bf5366c60aec47a4ff38f850bfd33 Mon Sep 17 00:00:00 2001 +From: Jan Polensky +Date: Mon, 27 Apr 2026 15:58:48 +0200 +Subject: [PATCH] redhat/configs: enable CONFIG_SCLP_OFB for s390x + +JIRA: https://redhat.atlassian.net/browse/RHEL-169810 +Upstream Status: RHEL-only + +Signed-off-by: Jan Polensky + +diff --git a/redhat/configs/rhel/generic/s390x/CONFIG_SCLP_OFB b/redhat/configs/rhel/generic/s390x/CONFIG_SCLP_OFB +index 9861bafbcfd6..62cca9859dd6 100644 +--- a/redhat/configs/rhel/generic/s390x/CONFIG_SCLP_OFB ++++ b/redhat/configs/rhel/generic/s390x/CONFIG_SCLP_OFB +@@ -1 +1 @@ +-# CONFIG_SCLP_OFB is not set ++CONFIG_SCLP_OFB=y +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1233-xfs-delete-attr-leaf-freemap-entries-when-empty.patch b/SOURCES/1233-xfs-delete-attr-leaf-freemap-entries-when-empty.patch new file mode 100644 index 000000000..317587445 --- /dev/null +++ b/SOURCES/1233-xfs-delete-attr-leaf-freemap-entries-when-empty.patch @@ -0,0 +1,78 @@ +From fdbdde5a23445e21f8e1a628cf09d1f254a3de1d Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 8 May 2026 14:37:50 +0000 +Subject: [PATCH] xfs: delete attr leaf freemap entries when empty + +JIRA: https://redhat.atlassian.net/browse/RHEL-174056 +CVE: CVE-2026-43158 + +commit 6f13c1d2a6271c2e73226864a0e83de2770b6f34 +Author: Darrick J. Wong +Date: Fri Jan 23 09:27:30 2026 -0800 + + xfs: delete attr leaf freemap entries when empty + + Back in commit 2a2b5932db6758 ("xfs: fix attr leaf header freemap.size + underflow"), Brian Foster observed that it's possible for a small + freemap at the end of the end of the xattr entries array to experience + a size underflow when subtracting the space consumed by an expansion of + the entries array. There are only three freemap entries, which means + that it is not a complete index of all free space in the leaf block. + + This code can leave behind a zero-length freemap entry with a nonzero + base. Subsequent setxattr operations can increase the base up to the + point that it overlaps with another freemap entry. This isn't in and of + itself a problem because the code in _leaf_add that finds free space + ignores any freemap entry with zero size. + + However, there's another bug in the freemap update code in _leaf_add, + which is that it fails to update a freemap entry that begins midway + through the xattr entry that was just appended to the array. That can + result in the freemap containing two entries with the same base but + different sizes (0 for the "pushed-up" entry, nonzero for the entry + that's actually tracking free space). A subsequent _leaf_add can then + allocate xattr namevalue entries on top of the entries array, leading to + data loss. But fixing that is for later. + + For now, eliminate the possibility of confusion by zeroing out the base + of any freemap entry that has zero size. Because the freemap is not + intended to be a complete index of free space, a subsequent failure to + find any free space for a new xattr will trigger block compaction, which + regenerates the freemap. + + It looks like this bug has been in the codebase for quite a long time. + + Cc: # v2.6.12 + Fixes: 1da177e4c3f415 ("Linux-2.6.12-rc2") + Signed-off-by: "Darrick J. Wong" + Reviewed-by: Christoph Hellwig + +Signed-off-by: CKI Backport Bot + +diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c +index fddb55605e0c..8577c01c83bd 100644 +--- a/fs/xfs/libxfs/xfs_attr_leaf.c ++++ b/fs/xfs/libxfs/xfs_attr_leaf.c +@@ -1593,6 +1593,19 @@ xfs_attr3_leaf_add_work( + min_t(uint16_t, ichdr->freemap[i].size, + sizeof(xfs_attr_leaf_entry_t)); + } ++ ++ /* ++ * Don't leave zero-length freemaps with nonzero base lying ++ * around, because we don't want the code in _remove that ++ * matches on base address to get confused and create ++ * overlapping freemaps. If we end up with no freemap entries ++ * then the next _add will compact the leaf block and ++ * regenerate the freemaps. ++ */ ++ if (ichdr->freemap[i].size == 0 && ichdr->freemap[i].base > 0) { ++ ichdr->freemap[i].base = 0; ++ ichdr->holes = 1; ++ } + } + ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index); + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1234-xfs-fix-freemap-adjustments-when-adding-xattrs-to-leaf-block.patch b/SOURCES/1234-xfs-fix-freemap-adjustments-when-adding-xattrs-to-leaf-block.patch new file mode 100644 index 000000000..fe8a01437 --- /dev/null +++ b/SOURCES/1234-xfs-fix-freemap-adjustments-when-adding-xattrs-to-leaf-block.patch @@ -0,0 +1,141 @@ +From 358cb992d6ec5a8dd5f81ac84a5c545b972dead3 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 8 May 2026 14:37:51 +0000 +Subject: [PATCH] xfs: fix freemap adjustments when adding xattrs to leaf + blocks + +JIRA: https://redhat.atlassian.net/browse/RHEL-174056 +CVE: CVE-2026-43158 + +commit 3eefc0c2b78444b64feeb3783c017d6adc3cd3ce +Author: Darrick J. Wong +Date: Fri Jan 23 09:27:31 2026 -0800 + + xfs: fix freemap adjustments when adding xattrs to leaf blocks + + xfs/592 and xfs/794 both trip this assertion in the leaf block freemap + adjustment code after ~20 minutes of running on my test VMs: + + ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t) + + xfs_attr3_leaf_hdr_size(leaf)); + + Upon enabling quite a lot more debugging code, I narrowed this down to + fsstress trying to set a local extended attribute with namelen=3 and + valuelen=71. This results in an entry size of 80 bytes. + + At the start of xfs_attr3_leaf_add_work, the freemap looks like this: + + i 0 base 448 size 0 rhs 448 count 46 + i 1 base 388 size 132 rhs 448 count 46 + i 2 base 2120 size 4 rhs 448 count 46 + firstused = 520 + + where "rhs" is the first byte past the end of the leaf entry array. + This is inconsistent -- the entries array ends at byte 448, but + freemap[1] says there's free space starting at byte 388! + + By the end of the function, the freemap is in worse shape: + + i 0 base 456 size 0 rhs 456 count 47 + i 1 base 388 size 52 rhs 456 count 47 + i 2 base 2120 size 4 rhs 456 count 47 + firstused = 440 + + Important note: 388 is not aligned with the entries array element size + of 8 bytes. + + Based on the incorrect freemap, the name area starts at byte 440, which + is below the end of the entries array! That's why the assertion + triggers and the filesystem shuts down. + + How did we end up here? First, recall from the previous patch that the + freemap array in an xattr leaf block is not intended to be a + comprehensive map of all free space in the leaf block. In other words, + it's perfectly legal to have a leaf block with: + + * 376 bytes in use by the entries array + * freemap[0] has [base = 376, size = 8] + * freemap[1] has [base = 388, size = 1500] + * the space between 376 and 388 is free, but the freemap stopped + tracking that some time ago + + If we add one xattr, the entries array grows to 384 bytes, and + freemap[0] becomes [base = 384, size = 0]. So far, so good. But if we + add a second xattr, the entries array grows to 392 bytes, and freemap[0] + gets pushed up to [base = 392, size = 0]. This is bad, because + freemap[1] hasn't been updated, and now the entries array and the free + space claim the same space. + + The fix here is to adjust all freemap entries so that none of them + collide with the entries array. Note that this fix relies on commit + 2a2b5932db6758 ("xfs: fix attr leaf header freemap.size underflow") and + the previous patch that resets zero length freemap entries to have + base = 0. + + Cc: # v2.6.12 + Fixes: 1da177e4c3f415 ("Linux-2.6.12-rc2") + Signed-off-by: "Darrick J. Wong" + Reviewed-by: Christoph Hellwig + +Signed-off-by: CKI Backport Bot + +diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c +index 8577c01c83bd..bfcac9036c11 100644 +--- a/fs/xfs/libxfs/xfs_attr_leaf.c ++++ b/fs/xfs/libxfs/xfs_attr_leaf.c +@@ -1489,6 +1489,7 @@ xfs_attr3_leaf_add_work( + struct xfs_attr_leaf_name_local *name_loc; + struct xfs_attr_leaf_name_remote *name_rmt; + struct xfs_mount *mp; ++ int old_end, new_end; + int tmp; + int i; + +@@ -1581,17 +1582,36 @@ xfs_attr3_leaf_add_work( + if (be16_to_cpu(entry->nameidx) < ichdr->firstused) + ichdr->firstused = be16_to_cpu(entry->nameidx); + +- ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t) +- + xfs_attr3_leaf_hdr_size(leaf)); +- tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t) +- + xfs_attr3_leaf_hdr_size(leaf); ++ new_end = ichdr->count * sizeof(struct xfs_attr_leaf_entry) + ++ xfs_attr3_leaf_hdr_size(leaf); ++ old_end = new_end - sizeof(struct xfs_attr_leaf_entry); ++ ++ ASSERT(ichdr->firstused >= new_end); + + for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { +- if (ichdr->freemap[i].base == tmp) { +- ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t); ++ int diff = 0; ++ ++ if (ichdr->freemap[i].base == old_end) { ++ /* ++ * This freemap entry starts at the old end of the ++ * leaf entry array, so we need to adjust its base ++ * upward to accomodate the larger array. ++ */ ++ diff = sizeof(struct xfs_attr_leaf_entry); ++ } else if (ichdr->freemap[i].size > 0 && ++ ichdr->freemap[i].base < new_end) { ++ /* ++ * This freemap entry starts in the space claimed by ++ * the new leaf entry. Adjust its base upward to ++ * reflect that. ++ */ ++ diff = new_end - ichdr->freemap[i].base; ++ } ++ ++ if (diff) { ++ ichdr->freemap[i].base += diff; + ichdr->freemap[i].size -= +- min_t(uint16_t, ichdr->freemap[i].size, +- sizeof(xfs_attr_leaf_entry_t)); ++ min_t(uint16_t, ichdr->freemap[i].size, diff); + } + + /* +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1235-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch b/SOURCES/1235-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch new file mode 100644 index 000000000..420393916 --- /dev/null +++ b/SOURCES/1235-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch @@ -0,0 +1,66 @@ +From 5dda10bce7cd3376e221d2bf7c76aa377bb21266 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Tue, 28 Apr 2026 05:41:22 +0000 +Subject: [PATCH] Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to + missing sock_hold + +JIRA: https://redhat.atlassian.net/browse/RHEL-171326 +CVE: CVE-2026-31408 + +commit 598dbba9919c5e36c54fe1709b557d64120cb94b +Author: Hyunwoo Kim +Date: Fri Mar 13 05:26:16 2026 +0900 + + Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold + + sco_recv_frame() reads conn->sk under sco_conn_lock() but immediately + releases the lock without holding a reference to the socket. A concurrent + close() can free the socket between the lock release and the subsequent + sk->sk_state access, resulting in a use-after-free. + + Other functions in the same file (sco_sock_timeout(), sco_conn_del()) + correctly use sco_sock_hold() to safely hold a reference under the lock. + + Fix by using sco_sock_hold() to take a reference before releasing the + lock, and adding sock_put() on all exit paths. + + Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") + Signed-off-by: Hyunwoo Kim + Signed-off-by: Luiz Augusto von Dentz + +Signed-off-by: CKI Backport Bot + +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index 5f6fb2c3611a..122288db9f16 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -399,7 +399,7 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) + struct sock *sk; + + sco_conn_lock(conn); +- sk = conn->sk; ++ sk = sco_sock_hold(conn); + sco_conn_unlock(conn); + + if (!sk) +@@ -408,11 +408,15 @@ static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) + BT_DBG("sk %p len %u", sk, skb->len); + + if (sk->sk_state != BT_CONNECTED) +- goto drop; ++ goto drop_put; + +- if (!sock_queue_rcv_skb(sk, skb)) ++ if (!sock_queue_rcv_skb(sk, skb)) { ++ sock_put(sk); + return; ++ } + ++drop_put: ++ sock_put(sk); + drop: + kfree_skb(skb); + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1236-smb-client-validate-the-whole-dacl-before-rewriting-it-in-ci.patch b/SOURCES/1236-smb-client-validate-the-whole-dacl-before-rewriting-it-in-ci.patch new file mode 100644 index 000000000..a4a768b87 --- /dev/null +++ b/SOURCES/1236-smb-client-validate-the-whole-dacl-before-rewriting-it-in-ci.patch @@ -0,0 +1,233 @@ +From 46c275962dc805a5e4ff6e69fcf12442816371c4 Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Mon, 11 May 2026 14:21:19 -0300 +Subject: [PATCH] smb: client: validate the whole DACL before rewriting it in + cifsacl + +JIRA: https://issues.redhat.com/browse/RHEL-172822 +CVE: CVE-2026-31709 + +commit 0a8cf165566ba55a39fd0f4de172119dd646d39a +Author: Michael Bommarito +Date: Sun Apr 19 20:11:31 2026 -0400 + + smb: client: validate the whole DACL before rewriting it in cifsacl + + build_sec_desc() and id_mode_to_cifs_acl() derive a DACL pointer from a + server-supplied dacloffset and then use the incoming ACL to rebuild the + chmod/chown security descriptor. + + The original fix only checked that the struct smb_acl header fits before + reading dacl_ptr->size or dacl_ptr->num_aces. That avoids the immediate + header-field OOB read, but the rewrite helpers still walk ACEs based on + pdacl->num_aces with no structural validation of the incoming DACL body. + + A malicious server can return a truncated DACL that still contains a + header, claims one or more ACEs, and then drive + replace_sids_and_copy_aces() or set_chmod_dacl() past the validated + extent while they compare or copy attacker-controlled ACEs. + + Factor the DACL structural checks into validate_dacl(), extend them to + validate each ACE against the DACL bounds, and use the shared validator + before the chmod/chown rebuild paths. parse_dacl() reuses the same + validator so the read-side parser and write-side rewrite paths agree on + what constitutes a well-formed incoming DACL. + + Fixes: bc3e9dd9d104 ("cifs: Change SIDs in ACEs while transferring file ownership.") + Cc: stable@vger.kernel.org + Assisted-by: Claude:claude-opus-4-6 + Assisted-by: Codex:gpt-5-4 + Signed-off-by: Michael Bommarito + Signed-off-by: Steve French + +Signed-off-by: Paulo Alcantara + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index 345d788b1cb2..1b931e82f6aa 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -757,6 +757,77 @@ static void dump_ace(struct smb_ace *pace, char *end_of_acl) + } + #endif + ++static int validate_dacl(struct smb_acl *pdacl, char *end_of_acl) ++{ ++ int i, ace_hdr_size, ace_size, min_ace_size; ++ u16 dacl_size, num_aces; ++ char *acl_base, *end_of_dacl; ++ struct smb_ace *pace; ++ ++ if (!pdacl) ++ return 0; ++ ++ if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl)) { ++ cifs_dbg(VFS, "ACL too small to parse DACL\n"); ++ return -EINVAL; ++ } ++ ++ dacl_size = le16_to_cpu(pdacl->size); ++ if (dacl_size < sizeof(struct smb_acl) || ++ end_of_acl < (char *)pdacl + dacl_size) { ++ cifs_dbg(VFS, "ACL too small to parse DACL\n"); ++ return -EINVAL; ++ } ++ ++ num_aces = le16_to_cpu(pdacl->num_aces); ++ if (!num_aces) ++ return 0; ++ ++ ace_hdr_size = offsetof(struct smb_ace, sid) + ++ offsetof(struct smb_sid, sub_auth); ++ min_ace_size = ace_hdr_size + sizeof(__le32); ++ if (num_aces > (dacl_size - sizeof(struct smb_acl)) / min_ace_size) { ++ cifs_dbg(VFS, "ACL too small to parse DACL\n"); ++ return -EINVAL; ++ } ++ ++ end_of_dacl = (char *)pdacl + dacl_size; ++ acl_base = (char *)pdacl; ++ ace_size = sizeof(struct smb_acl); ++ ++ for (i = 0; i < num_aces; ++i) { ++ if (end_of_dacl - acl_base < ace_size) { ++ cifs_dbg(VFS, "ACL too small to parse ACE\n"); ++ return -EINVAL; ++ } ++ ++ pace = (struct smb_ace *)(acl_base + ace_size); ++ acl_base = (char *)pace; ++ ++ if (end_of_dacl - acl_base < ace_hdr_size || ++ pace->sid.num_subauth == 0 || ++ pace->sid.num_subauth > SID_MAX_SUB_AUTHORITIES) { ++ cifs_dbg(VFS, "ACL too small to parse ACE\n"); ++ return -EINVAL; ++ } ++ ++ ace_size = ace_hdr_size + sizeof(__le32) * pace->sid.num_subauth; ++ if (end_of_dacl - acl_base < ace_size || ++ le16_to_cpu(pace->size) < ace_size) { ++ cifs_dbg(VFS, "ACL too small to parse ACE\n"); ++ return -EINVAL; ++ } ++ ++ ace_size = le16_to_cpu(pace->size); ++ if (end_of_dacl - acl_base < ace_size) { ++ cifs_dbg(VFS, "ACL too small to parse ACE\n"); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ + static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + struct smb_sid *pownersid, struct smb_sid *pgrpsid, + struct cifs_fattr *fattr, bool mode_from_special_sid) +@@ -764,7 +835,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + int i; + u16 num_aces = 0; + int acl_size; +- char *acl_base; ++ char *acl_base, *end_of_dacl; + struct smb_ace **ppace; + + /* BB need to add parm so we can store the SID BB */ +@@ -776,12 +847,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + return; + } + +- /* validate that we do not go past end of acl */ +- if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) || +- end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { +- cifs_dbg(VFS, "ACL too small to parse DACL\n"); ++ if (validate_dacl(pdacl, end_of_acl)) + return; +- } + + cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n", + le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), +@@ -792,6 +859,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + user/group/other have no permissions */ + fattr->cf_mode &= ~(0777); + ++ end_of_dacl = (char *)pdacl + le16_to_cpu(pdacl->size); + acl_base = (char *)pdacl; + acl_size = sizeof(struct smb_acl); + +@@ -799,36 +867,16 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + if (num_aces > 0) { + umode_t denied_mode = 0; + +- if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) / +- (offsetof(struct smb_ace, sid) + +- offsetof(struct smb_sid, sub_auth) + sizeof(__le16))) +- return; +- + ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), + GFP_KERNEL); + if (!ppace) + return; + + for (i = 0; i < num_aces; ++i) { +- if (end_of_acl - acl_base < acl_size) +- break; +- + ppace[i] = (struct smb_ace *) (acl_base + acl_size); +- acl_base = (char *)ppace[i]; +- acl_size = offsetof(struct smb_ace, sid) + +- offsetof(struct smb_sid, sub_auth); +- +- if (end_of_acl - acl_base < acl_size || +- ppace[i]->sid.num_subauth == 0 || +- ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES || +- (end_of_acl - acl_base < +- acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) || +- (le16_to_cpu(ppace[i]->size) < +- acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth)) +- break; + + #ifdef CONFIG_CIFS_DEBUG2 +- dump_ace(ppace[i], end_of_acl); ++ dump_ace(ppace[i], end_of_dacl); + #endif + if (mode_from_special_sid && + (compare_sids(&(ppace[i]->sid), +@@ -870,6 +918,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + (void *)ppace[i], + sizeof(struct smb_ace)); */ + ++ acl_base = (char *)ppace[i]; + acl_size = le16_to_cpu(ppace[i]->size); + } + +@@ -1293,10 +1342,9 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { + dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); +- if (end_of_acl < (char *)dacl_ptr + le16_to_cpu(dacl_ptr->size)) { +- cifs_dbg(VFS, "Server returned illegal ACL size\n"); +- return -EINVAL; +- } ++ rc = validate_dacl(dacl_ptr, end_of_acl); ++ if (rc) ++ return rc; + } + + owner_sid_ptr = (struct smb_sid *)((char *)pntsd + +@@ -1669,6 +1717,12 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { + dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); ++ rc = validate_dacl(dacl_ptr, (char *)pntsd + secdesclen); ++ if (rc) { ++ kfree(pntsd); ++ cifs_put_tlink(tlink); ++ return rc; ++ } + if (mode_from_sid) + nsecdesclen += + le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1237-smb-client-require-a-full-nfs-mode-sid-before-reading-mode-b.patch b/SOURCES/1237-smb-client-require-a-full-nfs-mode-sid-before-reading-mode-b.patch new file mode 100644 index 000000000..757ea87c5 --- /dev/null +++ b/SOURCES/1237-smb-client-require-a-full-nfs-mode-sid-before-reading-mode-b.patch @@ -0,0 +1,50 @@ +From 3c728813e14f108566b7787dae86c63ac78c861c Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Mon, 11 May 2026 14:21:19 -0300 +Subject: [PATCH] smb: client: require a full NFS mode SID before reading mode + bits + +JIRA: https://issues.redhat.com/browse/RHEL-172822 + +commit 2757ad3e4b6f9e0fed4c7739594e702abc5cab21 +Author: Michael Bommarito +Date: Mon Apr 20 09:50:58 2026 -0400 + + smb: client: require a full NFS mode SID before reading mode bits + + parse_dacl() treats an ACE SID matching sid_unix_NFS_mode as an NFS + mode SID and reads sid.sub_auth[2] to recover the mode bits. + + That assumes the ACE carries three subauthorities, but compare_sids() + only compares min(a, b) subauthorities. A malicious server can return + an ACE with num_subauth = 2 and sub_auth[] = {88, 3}, which still + matches sid_unix_NFS_mode and then drives the sub_auth[2] read four + bytes past the end of the ACE. + + Require num_subauth >= 3 before treating the ACE as an NFS mode SID. + This keeps the fix local to the special-SID mode path without changing + compare_sids() semantics for the rest of cifsacl. + + Fixes: e2f8fbfb8d09 ("cifs: get mode bits from special sid on stat") + Cc: stable@vger.kernel.org + Assisted-by: Claude:claude-opus-4-6 + Signed-off-by: Michael Bommarito + Signed-off-by: Steve French + +Signed-off-by: Paulo Alcantara + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index 1b931e82f6aa..114545ee58b7 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -879,6 +879,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + dump_ace(ppace[i], end_of_dacl); + #endif + if (mode_from_special_sid && ++ ppace[i]->sid.num_subauth >= 3 && + (compare_sids(&(ppace[i]->sid), + &sid_unix_NFS_mode) == 0)) { + /* +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1238-smb-client-scope-end-of-dacl-to-cifs-debug2-use-in-parse-dac.patch b/SOURCES/1238-smb-client-scope-end-of-dacl-to-cifs-debug2-use-in-parse-dac.patch new file mode 100644 index 000000000..22e5cc2c0 --- /dev/null +++ b/SOURCES/1238-smb-client-scope-end-of-dacl-to-cifs-debug2-use-in-parse-dac.patch @@ -0,0 +1,69 @@ +From 471fe53d5630a3277ae803e170a00c722ef021ec Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Mon, 11 May 2026 14:21:19 -0300 +Subject: [PATCH] smb: client: scope end_of_dacl to CIFS_DEBUG2 use in + parse_dacl + +JIRA: https://issues.redhat.com/browse/RHEL-172822 + +commit a55a60886e612bedb0e9a402ba0dca544c4c6a51 +Author: Michael Bommarito +Date: Tue Apr 21 19:40:22 2026 -0400 + + smb: client: scope end_of_dacl to CIFS_DEBUG2 use in parse_dacl + + After validate_dacl() was factored out in commit 149822e5541c, the + local end_of_dacl in parse_dacl() is only read by the dump_ace() + call under #ifdef CONFIG_CIFS_DEBUG2. With CIFS_DEBUG2 off the + variable is assigned but never used, which gcc -W=1 flags as + -Wunused-but-set-variable. + + Remove the local and compute the end-of-dacl pointer inline at the + single call site inside the existing CIFS_DEBUG2 guard. No + functional change: when CIFS_DEBUG2 is enabled the argument value + is identical to what the removed local carried; when CIFS_DEBUG2 + is disabled the code was already dead. + + Reported-by: kernel test robot + Closes: https://lore.kernel.org/oe-kbuild-all/202604220046.tGkRxVtS-lkp@intel.com/ + Fixes: 149822e5541c ("smb: client: validate the whole DACL before rewriting it in cifsacl") + Signed-off-by: Michael Bommarito + Assisted-by: Claude:claude-opus-4-7 + Signed-off-by: Steve French + +Signed-off-by: Paulo Alcantara + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index 114545ee58b7..8638fdfb6ffb 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -835,7 +835,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + int i; + u16 num_aces = 0; + int acl_size; +- char *acl_base, *end_of_dacl; ++ char *acl_base; + struct smb_ace **ppace; + + /* BB need to add parm so we can store the SID BB */ +@@ -859,7 +859,6 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + user/group/other have no permissions */ + fattr->cf_mode &= ~(0777); + +- end_of_dacl = (char *)pdacl + le16_to_cpu(pdacl->size); + acl_base = (char *)pdacl; + acl_size = sizeof(struct smb_acl); + +@@ -876,7 +875,8 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, + ppace[i] = (struct smb_ace *) (acl_base + acl_size); + + #ifdef CONFIG_CIFS_DEBUG2 +- dump_ace(ppace[i], end_of_dacl); ++ dump_ace(ppace[i], ++ (char *)pdacl + le16_to_cpu(pdacl->size)); + #endif + if (mode_from_special_sid && + ppace[i]->sid.num_subauth >= 3 && +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1239-smb-client-use-kzalloc-to-zero-initialize-security-descripto.patch b/SOURCES/1239-smb-client-use-kzalloc-to-zero-initialize-security-descripto.patch new file mode 100644 index 000000000..fefd8a143 --- /dev/null +++ b/SOURCES/1239-smb-client-use-kzalloc-to-zero-initialize-security-descripto.patch @@ -0,0 +1,57 @@ +From aa745912584aeada31b5672155cd1014c4b5f149 Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Mon, 11 May 2026 14:21:19 -0300 +Subject: [PATCH] smb: client: use kzalloc to zero-initialize security + descriptor buffer + +JIRA: https://issues.redhat.com/browse/RHEL-172822 + +commit 5e489c6c47a2ac15edbaca153b9348e42c1eacab +Author: Bjoern Doebel +Date: Thu Apr 30 08:57:17 2026 +0000 + + smb: client: use kzalloc to zero-initialize security descriptor buffer + + Commit 62e7dd0a39c2d ("smb: common: change the data type of num_aces + to le16") split struct smb_acl's __le32 num_aces field into __le16 + num_aces and __le16 reserved. The reserved field corresponds to Sbz2 + in the MS-DTYP ACL wire format, which must be zero [1]. + + When building an ACL descriptor in build_sec_desc(), we are using a + kmalloc()'ed descriptor buffer and writing the fields explicitly using + le16() writes now. This never writes to the 2 byte reserved field, + leaving it as uninitialized heap data. + + When the reserved field happens to contain non-zero slab garbage, + Samba rejects the security descriptor with "ndr_pull_security_descriptor + failed: Range Error", causing chmod to fail with EINVAL. + + Change kmalloc() to kzalloc() to ensure the entire buffer is + zero-initialized. + + Fixes: 62e7dd0a39c2d ("smb: common: change the data type of num_aces to le16") + Cc: stable@vger.kernel.org + + Signed-off-by: Bjoern Doebel + Assisted-by: Kiro:claude-opus-4.6 + [1] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/20233ed8-a6c6-4097-aafa-dd545ed24428 + Signed-off-by: Steve French + +Signed-off-by: Paulo Alcantara + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index 8638fdfb6ffb..e23bbe088221 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -1739,7 +1739,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + * descriptor parameters, and security descriptor itself + */ + nsecdesclen = max_t(u32, nsecdesclen, DEFAULT_SEC_DESC_LEN); +- pnntsd = kmalloc(nsecdesclen, GFP_KERNEL); ++ pnntsd = kzalloc(nsecdesclen, GFP_KERNEL); + if (!pnntsd) { + kfree(pntsd); + cifs_put_tlink(tlink); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1240-smb-client-validate-dacloffset-before-building-dacl-pointers.patch b/SOURCES/1240-smb-client-validate-dacloffset-before-building-dacl-pointers.patch new file mode 100644 index 000000000..08c7765d3 --- /dev/null +++ b/SOURCES/1240-smb-client-validate-dacloffset-before-building-dacl-pointers.patch @@ -0,0 +1,123 @@ +From 24a3f73bca32fcfcdecad0b9aaaa59def9a938fa Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Mon, 11 May 2026 14:21:20 -0300 +Subject: [PATCH] smb: client: validate dacloffset before building DACL + pointers + +JIRA: https://issues.redhat.com/browse/RHEL-172822 + +commit f98b48151cc502ada59d9778f0112d21f2586ca3 +Author: Michael Bommarito +Date: Mon Apr 20 10:47:47 2026 -0400 + + smb: client: validate dacloffset before building DACL pointers + + parse_sec_desc(), build_sec_desc(), and the chown path in + id_mode_to_cifs_acl() all add the server-supplied dacloffset to pntsd + before proving a DACL header fits inside the returned security + descriptor. + + On 32-bit builds a malicious server can return dacloffset near + U32_MAX, wrap the derived DACL pointer below end_of_acl, and then slip + past the later pointer-based bounds checks. build_sec_desc() and + id_mode_to_cifs_acl() can then dereference DACL fields from the wrapped + pointer in the chmod/chown rewrite paths. + + Validate dacloffset numerically before building any DACL pointer and + reuse the same helper at the three DACL entry points. + + Fixes: bc3e9dd9d104 ("cifs: Change SIDs in ACEs while transferring file ownership.") + Cc: stable@vger.kernel.org + Assisted-by: Claude:claude-opus-4-6 + Signed-off-by: Michael Bommarito + Signed-off-by: Steve French + +Signed-off-by: Paulo Alcantara + +diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c +index e23bbe088221..2206506c2e2d 100644 +--- a/fs/smb/client/cifsacl.c ++++ b/fs/smb/client/cifsacl.c +@@ -1264,6 +1264,17 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl) + return 0; + } + ++static bool dacl_offset_valid(unsigned int acl_len, __u32 dacloffset) ++{ ++ if (acl_len < sizeof(struct smb_acl)) ++ return false; ++ ++ if (dacloffset < sizeof(struct smb_ntsd)) ++ return false; ++ ++ return dacloffset <= acl_len - sizeof(struct smb_acl); ++} ++ + + /* Convert CIFS ACL to POSIX form */ + static int parse_sec_desc(struct cifs_sb_info *cifs_sb, +@@ -1284,7 +1295,6 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + group_sid_ptr = (struct smb_sid *)((char *)pntsd + + le32_to_cpu(pntsd->gsidoffset)); + dacloffset = le32_to_cpu(pntsd->dacloffset); +- dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n", + pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), + le32_to_cpu(pntsd->gsidoffset), +@@ -1315,11 +1325,18 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, + return rc; + } + +- if (dacloffset) ++ if (dacloffset) { ++ if (!dacl_offset_valid(acl_len, dacloffset)) { ++ cifs_dbg(VFS, "Server returned illegal DACL offset\n"); ++ return -EINVAL; ++ } ++ ++ dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, + group_sid_ptr, fattr, get_mode_from_special_sid); +- else ++ } else { + cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */ ++ } + + return rc; + } +@@ -1342,6 +1359,11 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, + + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { ++ if (!dacl_offset_valid(secdesclen, dacloffset)) { ++ cifs_dbg(VFS, "Server returned illegal DACL offset\n"); ++ return -EINVAL; ++ } ++ + dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + rc = validate_dacl(dacl_ptr, end_of_acl); + if (rc) +@@ -1717,6 +1739,12 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + nsecdesclen = sizeof(struct smb_ntsd) + (sizeof(struct smb_sid) * 2); + dacloffset = le32_to_cpu(pntsd->dacloffset); + if (dacloffset) { ++ if (!dacl_offset_valid(secdesclen, dacloffset)) { ++ cifs_dbg(VFS, "Server returned illegal DACL offset\n"); ++ rc = -EINVAL; ++ goto id_mode_to_cifs_acl_exit; ++ } ++ + dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset); + rc = validate_dacl(dacl_ptr, (char *)pntsd + secdesclen); + if (rc) { +@@ -1759,6 +1787,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, + rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag); + cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); + } ++id_mode_to_cifs_acl_exit: + cifs_put_tlink(tlink); + + kfree(pnntsd); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1241-ice-fix-infinite-recursion-in-ice-cfg-tx-topo-via-ice-init-d.patch b/SOURCES/1241-ice-fix-infinite-recursion-in-ice-cfg-tx-topo-via-ice-init-d.patch new file mode 100644 index 000000000..7a873cd7e --- /dev/null +++ b/SOURCES/1241-ice-fix-infinite-recursion-in-ice-cfg-tx-topo-via-ice-init-d.patch @@ -0,0 +1,106 @@ +From a528e9fad40ecec1f53b67c767c9dd1710b4451a Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Mon, 4 May 2026 08:22:52 +0000 +Subject: [PATCH] ice: fix infinite recursion in ice_cfg_tx_topo via + ice_init_dev_hw + +JIRA: https://redhat.atlassian.net/browse/RHEL-142433 + +commit 70ad216411e030f67b1743774e245601194aee6a +Author: Petr Oros +Date: Mon Apr 27 22:22:18 2026 -0700 + + ice: fix infinite recursion in ice_cfg_tx_topo via ice_init_dev_hw + + On certain E810 configurations where firmware supports Tx scheduler + topology switching (tx_sched_topo_comp_mode_en), ice_cfg_tx_topo() + may need to apply a new 5-layer or 9-layer topology from the DDP + package. If the AQ command to set the topology fails (e.g. due to + invalid DDP data or firmware limitations), the global configuration + lock must still be cleared via a CORER reset. + + Commit 86aae43f21cf ("ice: don't leave device non-functional if Tx + scheduler config fails") correctly fixed this by refactoring + ice_cfg_tx_topo() to always trigger CORER after acquiring the global + lock and re-initialize hardware via ice_init_hw() afterwards. + + However, commit 8a37f9e2ff40 ("ice: move ice_deinit_dev() to the end + of deinit paths") later moved ice_init_dev_hw() into ice_init_hw(), + breaking the reinit path introduced by 86aae43f21cf. This creates an + infinite recursive call chain: + + ice_init_hw() + ice_init_dev_hw() + ice_cfg_tx_topo() # topology change needed + ice_deinit_hw() + ice_init_hw() # reinit after CORER + ice_init_dev_hw() # recurse + ice_cfg_tx_topo() + ... # stack overflow + + Fix by moving ice_init_dev_hw() back out of ice_init_hw() and calling + it explicitly from ice_probe() and ice_devlink_reinit_up(). The third + caller, ice_cfg_tx_topo(), intentionally does not need ice_init_dev_hw() + during its reinit, it only needs the core HW reinitialization. This + breaks the recursion cleanly without adding flags or guards. + + The deinit ordering changes from commit 8a37f9e2ff40 ("ice: move + ice_deinit_dev() to the end of deinit paths") which fixed slow rmmod + are preserved, only the init-side placement of ice_init_dev_hw() is + reverted. + + Fixes: 8a37f9e2ff40 ("ice: move ice_deinit_dev() to the end of deinit paths") + Signed-off-by: Petr Oros + Reviewed-by: Paul Menzel + Reviewed-by: Jacob Keller + Reviewed-by: Aleksandr Loktionov + Reviewed-by: Przemek Kitszel + Tested-by: Alexander Nowlin + Signed-off-by: Jacob Keller + Link: https://patch.msgid.link/20260427-jk-iwl-net-petr-oros-fixes-v1-6-cdcb48303fd8@intel.com + Signed-off-by: Paolo Abeni + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c +index ac071c5b4ce3..cbd6de027ec0 100644 +--- a/drivers/net/ethernet/intel/ice/devlink/devlink.c ++++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c +@@ -1243,6 +1243,8 @@ static int ice_devlink_reinit_up(struct ice_pf *pf) + return err; + } + ++ ice_init_dev_hw(pf); ++ + /* load MSI-X values */ + ice_set_min_max_msix(pf); + +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index 785bf5cc1b25..94a16872126e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -1162,8 +1162,6 @@ int ice_init_hw(struct ice_hw *hw) + if (status) + goto err_unroll_fltr_mgmt_struct; + +- ice_init_dev_hw(hw->back); +- + mutex_init(&hw->tnl_lock); + ice_init_chk_recipe_reuse_support(hw); + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index b6dbdc343998..6b1e6eeedace 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -5339,6 +5339,8 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + return err; + } + ++ ice_init_dev_hw(pf); ++ + adapter = ice_adapter_get(pdev); + if (IS_ERR(adapter)) { + err = PTR_ERR(adapter); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1242-mm-page-alloc-clear-page-private-in-free-pages-prepare.patch b/SOURCES/1242-mm-page-alloc-clear-page-private-in-free-pages-prepare.patch new file mode 100644 index 000000000..4bf255cbe --- /dev/null +++ b/SOURCES/1242-mm-page-alloc-clear-page-private-in-free-pages-prepare.patch @@ -0,0 +1,72 @@ +From 1103c96c17fc62af309b95a2b3c8623a7067755c Mon Sep 17 00:00:00 2001 +From: Rafael Aquini +Date: Tue, 12 May 2026 07:59:17 -0400 +Subject: [PATCH] mm/page_alloc: clear page->private in free_pages_prepare() + +JIRA: https://issues.redhat.com/browse/RHEL-174754 +CVE: CVE-2026-43303 +Conflicts: + * minor context differences due to RHEL-9 missing upstream commit dcfe378c81f7 + ("lib: introduce support for page allocation tagging") as well as commit + 53fbef56e07d ("mm: introduce memdesc_flags_t") and its series. + +commit ac1ea219590c09572ed5992dc233bbf7bb70fef9 +Author: Mikhail Gavrilov +Date: Sat Feb 7 22:36:14 2026 +0500 + + mm/page_alloc: clear page->private in free_pages_prepare() + + Several subsystems (slub, shmem, ttm, etc.) use page->private but don't + clear it before freeing pages. When these pages are later allocated as + high-order pages and split via split_page(), tail pages retain stale + page->private values. + + This causes a use-after-free in the swap subsystem. The swap code uses + page->private to track swap count continuations, assuming freshly + allocated pages have page->private == 0. When stale values are present, + swap_count_continued() incorrectly assumes the continuation list is valid + and iterates over uninitialized page->lru containing LIST_POISON values, + causing a crash: + + KASAN: maybe wild-memory-access in range [0xdead000000000100-0xdead000000000107] + RIP: 0010:__do_sys_swapoff+0x1151/0x1860 + + Fix this by clearing page->private in free_pages_prepare(), ensuring all + freed pages have clean state regardless of previous use. + + Link: https://lkml.kernel.org/r/20260207173615.146159-1-mikhail.v.gavrilov@gmail.com + Fixes: 3b8000ae185c ("mm/vmalloc: huge vmalloc backing pages should be split rather than compound") + Signed-off-by: Mikhail Gavrilov + Suggested-by: Zi Yan + Acked-by: Zi Yan + Acked-by: David Hildenbrand (Arm) + Reviewed-by: Vlastimil Babka + Cc: Brendan Jackman + Cc: Chris Li + Cc: Hugh Dickins + Cc: Johannes Weiner + Cc: Kairui Song + Cc: Matthew Wilcox (Oracle) + Cc: Michal Hocko + Cc: Nicholas Piggin + Cc: Suren Baghdasaryan + Cc: + Signed-off-by: Andrew Morton + +Signed-off-by: Rafael Aquini + +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 1c5610fbfb8a..d6607174b2b4 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1160,6 +1160,7 @@ static __always_inline bool free_pages_prepare(struct page *page, + + page_cpupid_reset_last(page); + page->flags &= ~PAGE_FLAGS_CHECK_AT_PREP; ++ page->private = 0; + reset_page_owner(page, order); + page_table_check_free(page, order); + +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1243-pnfs-fix-a-missing-wake-up-while-waiting-on-nfs-layout-drain.patch b/SOURCES/1243-pnfs-fix-a-missing-wake-up-while-waiting-on-nfs-layout-drain.patch new file mode 100644 index 000000000..7d3574d8f --- /dev/null +++ b/SOURCES/1243-pnfs-fix-a-missing-wake-up-while-waiting-on-nfs-layout-drain.patch @@ -0,0 +1,63 @@ +From 2a2ee3826b4d857b8702e51590223c1fdbb8e49b Mon Sep 17 00:00:00 2001 +From: Olga Kornievskaia +Date: Tue, 17 Mar 2026 11:43:46 -0400 +Subject: [PATCH] pNFS: fix a missing wake up while waiting on NFS_LAYOUT_DRAIN + +JIRA: https://issues.redhat.com/browse/RHEL-151429 + +commit 5248d8474e594d156bee1ed10339cc16e207a28b +Author: Olga Kornievskaia +Date: Mon Jan 26 14:15:39 2026 -0500 + + pNFS: fix a missing wake up while waiting on NFS_LAYOUT_DRAIN + + It is possible to have a task get stuck on waiting on the + NFS_LAYOUT_DRAIN in the following scenario + + 1. cpu a: waiter test NFS_LAYOUT_DRAIN (1) and plh_outstanding (1) + 2. cpu b: atomic_dec_and_test() -> clear bit -> wake up + 3. cpu c: sets NFS_LAYOUT_DRAIN again + 4. cpu a: calls wait_on_bit() sleeps forever. + + To expand on this we have say 2 outstanding pnfs write IO that get + ESTALE which causes both to call pnfs_destroy_layout() and set the + NFS_LAYOUT_DRAIN bit but the 1st one doesn't call the + pnfs_put_layout_hdr() yet (as that would prevent the 2nd ESTALE write + from trying to call pnfs_destroy_layout()). If the 1st ESTALE write + is the one that initially sets the NFS_LAYOUT_DRAIN so that new IO + on this file initiates new LAYOUTGET. Another new write would find + NFS_LAYOUT_DRAIN set and phl_outstanding>0 (step 1) and would + wait_on_bit(). LAYOUTGET completes doing step 2. Now, the 2nd of + ESTALE writes is calling pnfs_destory_layout() and set the + NFS_LAYOUT_DRAIN bit (step 3). Finally, the waiting write wakes up + to check the bit and goes back to sleep. + + The problem revolves around the fact that if NFS_LAYOUT_INVALID_STID + was already set, it should not do the work of + pnfs_mark_layout_stateid_invalid(), thus NFS_LAYOUT_DRAIN will not + be set more than once for an invalid layout. + + Suggested-by: Trond Myklebust + Fixes: 880265c77ac4 ("pNFS: Avoid a live lock condition in pnfs_update_layout()") + Signed-off-by: Olga Kornievskaia + Signed-off-by: Anna Schumaker + +Signed-off-by: Olga Kornievskaia + +diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c +index 04423ebe8f76..263b9e4855d4 100644 +--- a/fs/nfs/pnfs.c ++++ b/fs/nfs/pnfs.c +@@ -465,7 +465,8 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo, + }; + struct pnfs_layout_segment *lseg, *next; + +- set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); ++ if (test_and_set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags)) ++ return !list_empty(&lo->plh_segs); + clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(lo->plh_inode)->flags); + list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list) + pnfs_clear_lseg_state(lseg, lseg_list); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1244-proc-use-the-same-treatment-to-check-proc-lseek-as-ones-for-.patch b/SOURCES/1244-proc-use-the-same-treatment-to-check-proc-lseek-as-ones-for-.patch new file mode 100644 index 000000000..6ecd17979 --- /dev/null +++ b/SOURCES/1244-proc-use-the-same-treatment-to-check-proc-lseek-as-ones-for-.patch @@ -0,0 +1,89 @@ +From d84d98bcf5d6b56fb2f0ea2614773a969bad2c7e Mon Sep 17 00:00:00 2001 +From: Abhi Das +Date: Fri, 8 May 2026 13:36:26 -0500 +Subject: [PATCH] proc: use the same treatment to check proc_lseek as ones for + proc_read_iter et.al + +JIRA: https://redhat.atlassian.net/browse/RHEL-171801 +CVE: CVE-2025-38653 + +commit ff7ec8dc1b646296f8d94c39339e8d3833d16c05 +Author: wangzijie +Date: Sat Jun 7 10:13:53 2025 +0800 + + proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al + + Check pde->proc_ops->proc_lseek directly may cause UAF in rmmod scenario. + It's a gap in proc_reg_open() after commit 654b33ada4ab("proc: fix UAF in + proc_get_inode()"). Followed by AI Viro's suggestion, fix it in same + manner. + + Link: https://lkml.kernel.org/r/20250607021353.1127963-1-wangzijie1@honor.com + Fixes: 3f61631d47f1 ("take care to handle NULL ->proc_lseek()") + Signed-off-by: wangzijie + Reviewed-by: Alexey Dobriyan + Cc: Alexei Starovoitov + Cc: Al Viro + Cc: "Edgecombe, Rick P" + Cc: Kirill A. Shuemov + Signed-off-by: Andrew Morton + +Signed-off-by: Abhi Das + +diff --git a/fs/proc/generic.c b/fs/proc/generic.c +index 24ceced87cfe..4e0ac5f5d99c 100644 +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -568,6 +568,8 @@ static void pde_set_flags(struct proc_dir_entry *pde) + if (pde->proc_ops->proc_compat_ioctl) + pde->flags |= PROC_ENTRY_proc_compat_ioctl; + #endif ++ if (pde->proc_ops->proc_lseek) ++ pde->flags |= PROC_ENTRY_proc_lseek; + } + + struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, +diff --git a/fs/proc/inode.c b/fs/proc/inode.c +index f005a3e067e7..32cf53d701fa 100644 +--- a/fs/proc/inode.c ++++ b/fs/proc/inode.c +@@ -487,7 +487,7 @@ static int proc_reg_open(struct inode *inode, struct file *file) + typeof_member(struct proc_ops, proc_release) release; + struct pde_opener *pdeo; + +- if (!pde->proc_ops->proc_lseek) ++ if (!pde_has_proc_lseek(pde)) + file->f_mode &= ~FMODE_LSEEK; + + if (pde_is_permanent(pde)) { +diff --git a/fs/proc/internal.h b/fs/proc/internal.h +index a2ff84c996c6..e85c531ec161 100644 +--- a/fs/proc/internal.h ++++ b/fs/proc/internal.h +@@ -93,6 +93,11 @@ static inline bool pde_has_proc_compat_ioctl(const struct proc_dir_entry *pde) + #endif + } + ++static inline bool pde_has_proc_lseek(const struct proc_dir_entry *pde) ++{ ++ return pde->flags & PROC_ENTRY_proc_lseek; ++} ++ + extern struct kmem_cache *proc_dir_entry_cache; + void pde_free(struct proc_dir_entry *pde); + +diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h +index 6f7b89b520d6..b71392fe84d0 100644 +--- a/include/linux/proc_fs.h ++++ b/include/linux/proc_fs.h +@@ -27,6 +27,7 @@ enum { + + PROC_ENTRY_proc_read_iter = 1U << 1, + PROC_ENTRY_proc_compat_ioctl = 1U << 2, ++ PROC_ENTRY_proc_lseek = 1U << 3, + }; + + struct proc_ops { +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1245-proc-fix-missing-pde-set-flags-for-net-proc-files.patch b/SOURCES/1245-proc-fix-missing-pde-set-flags-for-net-proc-files.patch new file mode 100644 index 000000000..43dc097eb --- /dev/null +++ b/SOURCES/1245-proc-fix-missing-pde-set-flags-for-net-proc-files.patch @@ -0,0 +1,140 @@ +From f71095c72d407f60b21042f2dfbaad3cd1ab093c Mon Sep 17 00:00:00 2001 +From: Abhi Das +Date: Fri, 8 May 2026 13:37:49 -0500 +Subject: [PATCH] proc: fix missing pde_set_flags() for net proc files +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +JIRA: https://redhat.atlassian.net/browse/RHEL-171801 +CVE: CVE-2025-38653 + +commit 2ce3d282bd5050fca8577defeff08ada0d55d062 +Author: wangzijie +Date: Mon Aug 18 20:31:02 2025 +0800 + + proc: fix missing pde_set_flags() for net proc files + + To avoid potential UAF issues during module removal races, we use + pde_set_flags() to save proc_ops flags in PDE itself before + proc_register(), and then use pde_has_proc_*() helpers instead of directly + dereferencing pde->proc_ops->*. + + However, the pde_set_flags() call was missing when creating net related + proc files. This omission caused incorrect behavior which FMODE_LSEEK was + being cleared inappropriately in proc_reg_open() for net proc files. Lars + reported it in this link[1]. + + Fix this by ensuring pde_set_flags() is called when register proc entry, + and add NULL check for proc_ops in pde_set_flags(). + + [wangzijie1@honor.com: stash pde->proc_ops in a local const variable, per Christian] + Link: https://lkml.kernel.org/r/20250821105806.1453833-1-wangzijie1@honor.com + Link: https://lkml.kernel.org/r/20250818123102.959595-1-wangzijie1@honor.com + Link: https://lore.kernel.org/all/20250815195616.64497967@chagall.paradoxon.rec/ [1] + Fixes: ff7ec8dc1b64 ("proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al") + Signed-off-by: wangzijie + Reported-by: Lars Wendler + Tested-by: Stefano Brivio + Tested-by: Petr Vaněk + Tested by: Lars Wendler + Cc: Alexei Starovoitov + Cc: Alexey Dobriyan + Cc: Al Viro + Cc: "Edgecombe, Rick P" + Cc: Greg Kroah-Hartman + Cc: Jiri Slaby + Cc: Kirill A. Shutemov + Cc: wangzijie + Cc: + Signed-off-by: Andrew Morton + +Signed-off-by: Abhi Das + +diff --git a/fs/proc/generic.c b/fs/proc/generic.c +index 4e0ac5f5d99c..1bfff5c905d8 100644 +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -363,6 +363,25 @@ static const struct inode_operations proc_dir_inode_operations = { + .setattr = proc_notify_change, + }; + ++static void pde_set_flags(struct proc_dir_entry *pde) ++{ ++ const struct proc_ops *proc_ops = pde->proc_ops; ++ ++ if (!proc_ops) ++ return; ++ ++ if (proc_ops->proc_flags & PROC_ENTRY_PERMANENT) ++ pde->flags |= PROC_ENTRY_PERMANENT; ++ if (proc_ops->proc_read_iter) ++ pde->flags |= PROC_ENTRY_proc_read_iter; ++#ifdef CONFIG_COMPAT ++ if (proc_ops->proc_compat_ioctl) ++ pde->flags |= PROC_ENTRY_proc_compat_ioctl; ++#endif ++ if (proc_ops->proc_lseek) ++ pde->flags |= PROC_ENTRY_proc_lseek; ++} ++ + /* returns the registered entry, or frees dp and returns NULL on failure */ + struct proc_dir_entry *proc_register(struct proc_dir_entry *dir, + struct proc_dir_entry *dp) +@@ -370,6 +389,8 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir, + if (proc_alloc_inum(&dp->low_ino)) + goto out_free_entry; + ++ pde_set_flags(dp); ++ + write_lock(&proc_subdir_lock); + dp->parent = dir; + if (pde_subdir_insert(dir, dp) == false) { +@@ -558,20 +579,6 @@ struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode, + return p; + } + +-static void pde_set_flags(struct proc_dir_entry *pde) +-{ +- if (pde->proc_ops->proc_flags & PROC_ENTRY_PERMANENT) +- pde->flags |= PROC_ENTRY_PERMANENT; +- if (pde->proc_ops->proc_read_iter) +- pde->flags |= PROC_ENTRY_proc_read_iter; +-#ifdef CONFIG_COMPAT +- if (pde->proc_ops->proc_compat_ioctl) +- pde->flags |= PROC_ENTRY_proc_compat_ioctl; +-#endif +- if (pde->proc_ops->proc_lseek) +- pde->flags |= PROC_ENTRY_proc_lseek; +-} +- + struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, + struct proc_dir_entry *parent, + const struct proc_ops *proc_ops, void *data) +@@ -582,7 +589,6 @@ struct proc_dir_entry *proc_create_data(const char *name, umode_t mode, + if (!p) + return NULL; + p->proc_ops = proc_ops; +- pde_set_flags(p); + return proc_register(parent, p); + } + EXPORT_SYMBOL(proc_create_data); +@@ -633,7 +639,6 @@ struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode, + p->proc_ops = &proc_seq_ops; + p->seq_ops = ops; + p->state_size = state_size; +- pde_set_flags(p); + return proc_register(parent, p); + } + EXPORT_SYMBOL(proc_create_seq_private); +@@ -664,7 +669,6 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode, + return NULL; + p->proc_ops = &proc_single_ops; + p->single_show = show; +- pde_set_flags(p); + return proc_register(parent, p); + } + EXPORT_SYMBOL(proc_create_single_data); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1246-proc-fix-type-confusion-in-pde-set-flags.patch b/SOURCES/1246-proc-fix-type-confusion-in-pde-set-flags.patch new file mode 100644 index 000000000..ffcfac2a7 --- /dev/null +++ b/SOURCES/1246-proc-fix-type-confusion-in-pde-set-flags.patch @@ -0,0 +1,59 @@ +From 3dd2462bc961a43d3b0b5faaadada3287e07c973 Mon Sep 17 00:00:00 2001 +From: Abhi Das +Date: Fri, 8 May 2026 13:39:06 -0500 +Subject: [PATCH] proc: fix type confusion in pde_set_flags() + +JIRA: https://redhat.atlassian.net/browse/RHEL-171801 +CVE: CVE-2025-38653 + +commit 0ce9398aa0830f15f92bbed73853f9861c3e74ff +Author: wangzijie +Date: Thu Sep 4 21:57:15 2025 +0800 + + proc: fix type confusion in pde_set_flags() + + Commit 2ce3d282bd50 ("proc: fix missing pde_set_flags() for net proc + files") missed a key part in the definition of proc_dir_entry: + + union { + const struct proc_ops *proc_ops; + const struct file_operations *proc_dir_ops; + }; + + So dereference of ->proc_ops assumes it is a proc_ops structure results in + type confusion and make NULL check for 'proc_ops' not work for proc dir. + + Add !S_ISDIR(dp->mode) test before calling pde_set_flags() to fix it. + + Link: https://lkml.kernel.org/r/20250904135715.3972782-1-wangzijie1@honor.com + Fixes: 2ce3d282bd50 ("proc: fix missing pde_set_flags() for net proc files") + Signed-off-by: wangzijie + Reported-by: Brad Spengler + Closes: https://lore.kernel.org/all/20250903065758.3678537-1-wangzijie1@honor.com/ + Cc: Alexey Dobriyan + Cc: Al Viro + Cc: Christian Brauner + Cc: Jiri Slaby + Cc: Stefano Brivio + Cc: + Signed-off-by: Andrew Morton + +Signed-off-by: Abhi Das + +diff --git a/fs/proc/generic.c b/fs/proc/generic.c +index 1bfff5c905d8..ec49e7ac9cfa 100644 +--- a/fs/proc/generic.c ++++ b/fs/proc/generic.c +@@ -389,7 +389,8 @@ struct proc_dir_entry *proc_register(struct proc_dir_entry *dir, + if (proc_alloc_inum(&dp->low_ino)) + goto out_free_entry; + +- pde_set_flags(dp); ++ if (!S_ISDIR(dp->mode)) ++ pde_set_flags(dp); + + write_lock(&proc_subdir_lock); + dp->parent = dir; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1247-crypto-tegra-disable-softirqs-before-finalizing-request.patch b/SOURCES/1247-crypto-tegra-disable-softirqs-before-finalizing-request.patch new file mode 100644 index 000000000..c017e9d21 --- /dev/null +++ b/SOURCES/1247-crypto-tegra-disable-softirqs-before-finalizing-request.patch @@ -0,0 +1,99 @@ +From 6dadf30d221829ac984d01bc0139550d64a62e10 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 24 Apr 2026 14:35:20 +0000 +Subject: [PATCH] crypto: tegra - Disable softirqs before finalizing request + +JIRA: https://redhat.atlassian.net/browse/RHEL-170915 + +commit 2aeec9af775fb53aa086419b953302c6f4ad4984 +Author: Herbert Xu +Date: Tue Mar 10 18:28:29 2026 +0900 + + crypto: tegra - Disable softirqs before finalizing request + + Softirqs must be disabled when calling the finalization fucntion on + a request. + + Reported-by: Guangwu Zhang + Fixes: 0880bb3b00c8 ("crypto: tegra - Add Tegra Security Engine driver") + Signed-off-by: Herbert Xu + +Signed-off-by: CKI Backport Bot + +diff --git a/drivers/crypto/tegra/tegra-se-aes.c b/drivers/crypto/tegra/tegra-se-aes.c +index 0e07d0523291..8b91f00b9c31 100644 +--- a/drivers/crypto/tegra/tegra-se-aes.c ++++ b/drivers/crypto/tegra/tegra-se-aes.c +@@ -4,6 +4,7 @@ + * Crypto driver to handle block cipher algorithms using NVIDIA Security Engine. + */ + ++#include + #include + #include + #include +@@ -333,7 +334,9 @@ static int tegra_aes_do_one_req(struct crypto_engine *engine, void *areq) + tegra_key_invalidate_reserved(ctx->se, key2_id, ctx->alg); + + out_finalize: ++ local_bh_disable(); + crypto_finalize_skcipher_request(se->engine, req, ret); ++ local_bh_enable(); + + return 0; + } +@@ -1261,7 +1264,9 @@ static int tegra_ccm_do_one_req(struct crypto_engine *engine, void *areq) + tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg); + + out_finalize: ++ local_bh_disable(); + crypto_finalize_aead_request(ctx->se->engine, req, ret); ++ local_bh_enable(); + + return 0; + } +@@ -1347,7 +1352,9 @@ static int tegra_gcm_do_one_req(struct crypto_engine *engine, void *areq) + tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg); + + out_finalize: ++ local_bh_disable(); + crypto_finalize_aead_request(ctx->se->engine, req, ret); ++ local_bh_enable(); + + return 0; + } +@@ -1745,7 +1752,9 @@ static int tegra_cmac_do_one_req(struct crypto_engine *engine, void *areq) + if (tegra_key_is_reserved(rctx->key_id)) + tegra_key_invalidate_reserved(ctx->se, rctx->key_id, ctx->alg); + ++ local_bh_disable(); + crypto_finalize_hash_request(se->engine, req, ret); ++ local_bh_enable(); + + return 0; + } +diff --git a/drivers/crypto/tegra/tegra-se-hash.c b/drivers/crypto/tegra/tegra-se-hash.c +index 42d007b7af45..90bf34eb3578 100644 +--- a/drivers/crypto/tegra/tegra-se-hash.c ++++ b/drivers/crypto/tegra/tegra-se-hash.c +@@ -4,6 +4,7 @@ + * Crypto driver to handle HASH algorithms using NVIDIA Security Engine. + */ + ++#include + #include + #include + #include +@@ -543,7 +544,9 @@ static int tegra_sha_do_one_req(struct crypto_engine *engine, void *areq) + } + + out: ++ local_bh_disable(); + crypto_finalize_hash_request(se->engine, req, ret); ++ local_bh_enable(); + + return 0; + } +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1248-bluetooth-mgmt-validate-ltk-enc-size-on-load.patch b/SOURCES/1248-bluetooth-mgmt-validate-ltk-enc-size-on-load.patch new file mode 100644 index 000000000..cc3edb22a --- /dev/null +++ b/SOURCES/1248-bluetooth-mgmt-validate-ltk-enc-size-on-load.patch @@ -0,0 +1,46 @@ +From c6005c57543c679c5841d0c34e629336fba6c808 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 1 May 2026 17:11:21 +0000 +Subject: [PATCH] Bluetooth: MGMT: validate LTK enc_size on load + +JIRA: https://redhat.atlassian.net/browse/RHEL-172573 +CVE: CVE-2026-43020 + +commit b8dbe9648d69059cfe3a28917bfbf7e61efd7f15 +Author: Keenan Dong +Date: Sat Mar 28 16:46:47 2026 +0800 + + Bluetooth: MGMT: validate LTK enc_size on load + + Load Long Term Keys stores the user-provided enc_size and later uses + it to size fixed-size stack operations when replying to LE LTK + requests. An enc_size larger than the 16-byte key buffer can therefore + overflow the reply stack buffer. + + Reject oversized enc_size values while validating the management LTK + record so invalid keys never reach the stored key state. + + Fixes: 346af67b8d11 ("Bluetooth: Add MGMT handlers for dealing with SMP LTK's") + Reported-by: Keenan Dong + Signed-off-by: Keenan Dong + Signed-off-by: Luiz Augusto von Dentz + +Signed-off-by: CKI Backport Bot + +diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c +index a758452e49b5..3756c2a152d2 100644 +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -7163,6 +7163,9 @@ static bool ltk_is_valid(struct mgmt_ltk_info *key) + if (key->initiator != 0x00 && key->initiator != 0x01) + return false; + ++ if (key->enc_size > sizeof(key->val)) ++ return false; ++ + switch (key->addr.type) { + case BDADDR_LE_PUBLIC: + return true; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1249-bluetooth-sco-fix-race-conditions-in-sco-sock-connect.patch b/SOURCES/1249-bluetooth-sco-fix-race-conditions-in-sco-sock-connect.patch new file mode 100644 index 000000000..e187bb4ca --- /dev/null +++ b/SOURCES/1249-bluetooth-sco-fix-race-conditions-in-sco-sock-connect.patch @@ -0,0 +1,147 @@ +From 88665b7faa3968be4bdd33c2f3a8e17a20abe37a Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Fri, 1 May 2026 17:17:19 +0000 +Subject: [PATCH] Bluetooth: SCO: fix race conditions in sco_sock_connect() + +JIRA: https://redhat.atlassian.net/browse/RHEL-172600 +CVE: CVE-2026-43023 + +commit 8a5b0135d4a5d9683203a3d9a12a711ccec5936b +Author: Cen Zhang +Date: Thu Mar 26 23:16:45 2026 +0800 + + Bluetooth: SCO: fix race conditions in sco_sock_connect() + + sco_sock_connect() checks sk_state and sk_type without holding + the socket lock. Two concurrent connect() syscalls on the same + socket can both pass the check and enter sco_connect(), leading + to use-after-free. + + The buggy scenario involves three participants and was confirmed + with additional logging instrumentation: + + Thread A (connect): HCI disconnect: Thread B (connect): + + sco_sock_connect(sk) sco_sock_connect(sk) + sk_state==BT_OPEN sk_state==BT_OPEN + (pass, no lock) (pass, no lock) + sco_connect(sk): sco_connect(sk): + hci_dev_lock hci_dev_lock + hci_connect_sco <- blocked + -> hcon1 + sco_conn_add->conn1 + lock_sock(sk) + sco_chan_add: + conn1->sk = sk + sk->conn = conn1 + sk_state=BT_CONNECT + release_sock + hci_dev_unlock + hci_dev_lock + sco_conn_del: + lock_sock(sk) + sco_chan_del: + sk->conn=NULL + conn1->sk=NULL + sk_state= + BT_CLOSED + SOCK_ZAPPED + release_sock + hci_dev_unlock + (unblocked) + hci_connect_sco + -> hcon2 + sco_conn_add + -> conn2 + lock_sock(sk) + sco_chan_add: + sk->conn=conn2 + sk_state= + BT_CONNECT + // zombie sk! + release_sock + hci_dev_unlock + + Thread B revives a BT_CLOSED + SOCK_ZAPPED socket back to + BT_CONNECT. Subsequent cleanup triggers double sock_put() and + use-after-free. Meanwhile conn1 is leaked as it was orphaned + when sco_conn_del() cleared the association. + + Fix this by: + - Moving lock_sock() before the sk_state/sk_type checks in + sco_sock_connect() to serialize concurrent connect attempts + - Fixing the sk_type != SOCK_SEQPACKET check to actually + return the error instead of just assigning it + - Adding a state re-check in sco_connect() after lock_sock() + to catch state changes during the window between the locks + - Adding sco_pi(sk)->conn check in sco_chan_add() to prevent + double-attach of a socket to multiple connections + - Adding hci_conn_drop() on sco_chan_add failure to prevent + HCI connection leaks + + Fixes: 9a8ec9e8ebb5 ("Bluetooth: SCO: Fix possible circular locking dependency on sco_connect_cfm") + Signed-off-by: Cen Zhang + Signed-off-by: Luiz Augusto von Dentz + +Signed-off-by: CKI Backport Bot + +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index 5f6fb2c3611a..b4a0da780c9a 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -298,7 +298,7 @@ static int sco_chan_add(struct sco_conn *conn, struct sock *sk, + int err = 0; + + sco_conn_lock(conn); +- if (conn->sk) ++ if (conn->sk || sco_pi(sk)->conn) + err = -EBUSY; + else + __sco_chan_add(conn, sk, parent); +@@ -353,9 +353,20 @@ static int sco_connect(struct sock *sk) + + lock_sock(sk); + ++ /* Recheck state after reacquiring the socket lock, as another ++ * thread may have changed it (e.g., closed the socket). ++ */ ++ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) { ++ release_sock(sk); ++ hci_conn_drop(hcon); ++ err = -EBADFD; ++ goto unlock; ++ } ++ + err = sco_chan_add(conn, sk, NULL); + if (err) { + release_sock(sk); ++ hci_conn_drop(hcon); + goto unlock; + } + +@@ -649,13 +660,18 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen + addr->sa_family != AF_BLUETOOTH) + return -EINVAL; + +- if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) ++ lock_sock(sk); ++ ++ if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) { ++ release_sock(sk); + return -EBADFD; ++ } + +- if (sk->sk_type != SOCK_SEQPACKET) +- err = -EINVAL; ++ if (sk->sk_type != SOCK_SEQPACKET) { ++ release_sock(sk); ++ return -EINVAL; ++ } + +- lock_sock(sk); + /* Set destination address and psm */ + bacpy(&sco_pi(sk)->dst, &sa->sco_bdaddr); + release_sock(sk); +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1250-wifi-brcmfmac-validate-bsscfg-indices-in-if-events.patch b/SOURCES/1250-wifi-brcmfmac-validate-bsscfg-indices-in-if-events.patch new file mode 100644 index 000000000..065199f72 --- /dev/null +++ b/SOURCES/1250-wifi-brcmfmac-validate-bsscfg-indices-in-if-events.patch @@ -0,0 +1,37 @@ +From 304950a467d83678bd0b0f46331882e2ac23b12d Mon Sep 17 00:00:00 2001 +From: Pengpeng Hou +Date: Mon, 23 Mar 2026 15:45:51 +0800 +Subject: [PATCH] wifi: brcmfmac: validate bsscfg indices in IF events + +brcmf_fweh_handle_if_event() validates the firmware-provided interface +index before it touches drvr->iflist[], but it still uses the raw +bsscfgidx field as an array index without a matching range check. + +Reject IF events whose bsscfg index does not fit in drvr->iflist[] +before indexing the interface array. + +Signed-off-by: Pengpeng Hou +Acked-by: Arend van Spriel +Link: https://patch.msgid.link/20260323074551.93530-1-pengpeng@iscas.ac.cn +[add missing wifi prefix] +Signed-off-by: Johannes Berg + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +index 984886481f4e..1cff4ba76943 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -153,6 +153,11 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, + bphy_err(drvr, "invalid interface index: %u\n", ifevent->ifidx); + return; + } ++ if (ifevent->bsscfgidx >= BRCMF_MAX_IFS) { ++ bphy_err(drvr, "invalid bsscfg index: %u\n", ++ ifevent->bsscfgidx); ++ return; ++ } + + ifp = drvr->iflist[ifevent->bsscfgidx]; + +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1251-netfilter-xt-tcpmss-check-remaining-length-before-reading-op.patch b/SOURCES/1251-netfilter-xt-tcpmss-check-remaining-length-before-reading-op.patch new file mode 100644 index 000000000..5c265f5e3 --- /dev/null +++ b/SOURCES/1251-netfilter-xt-tcpmss-check-remaining-length-before-reading-op.patch @@ -0,0 +1,46 @@ +From 037ff729f54b2fb1973a2baedd1dee11ebc75778 Mon Sep 17 00:00:00 2001 +From: CKI Backport Bot +Date: Wed, 6 May 2026 20:45:56 +0000 +Subject: [PATCH] netfilter: xt_tcpmss: check remaining length before reading + optlen + +JIRA: https://redhat.atlassian.net/browse/RHEL-174215 +CVE: CVE-2026-43190 + +commit 735ee8582da3d239eb0c7a53adca61b79fb228b3 +Author: Florian Westphal +Date: Mon Jan 19 12:30:42 2026 +0100 + + netfilter: xt_tcpmss: check remaining length before reading optlen + + Quoting reporter: + In net/netfilter/xt_tcpmss.c (lines 53-68), the TCP option parser reads + op[i+1] directly without validating the remaining option length. + + If the last byte of the option field is not EOL/NOP (0/1), the code attempts + to index op[i+1]. In the case where i + 1 == optlen, this causes an + out-of-bounds read, accessing memory past the optlen boundary + (either reading beyond the stack buffer _opt or the + following payload). + + Reported-by: sungzii + Signed-off-by: Florian Westphal + +Signed-off-by: CKI Backport Bot + +diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c +index 37704ab01799..0d32d4841cb3 100644 +--- a/net/netfilter/xt_tcpmss.c ++++ b/net/netfilter/xt_tcpmss.c +@@ -61,7 +61,7 @@ tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par) + return (mssval >= info->mss_min && + mssval <= info->mss_max) ^ info->invert; + } +- if (op[i] < 2) ++ if (op[i] < 2 || i == optlen - 1) + i++; + else + i += op[i+1] ? : 1; +-- +2.50.1 (Apple Git-155) + diff --git a/SOURCES/1252-dm-thin-fix-metadata-refcount-underflow.patch b/SOURCES/1252-dm-thin-fix-metadata-refcount-underflow.patch new file mode 100644 index 000000000..a0b257718 --- /dev/null +++ b/SOURCES/1252-dm-thin-fix-metadata-refcount-underflow.patch @@ -0,0 +1,63 @@ +From 239cbf26626f77357ad7d15407fc24666e236138 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 22 Apr 2026 20:14:10 -0400 +Subject: [PATCH] dm-thin: fix metadata refcount underflow + +JIRA: https://issues.redhat.com/browse/RHEL-169624 +Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm.git + +commit 09a65adc7d8bbfce06392cb6d375468e2728ead5 +Author: Mikulas Patocka +Date: Mon Apr 20 19:56:44 2026 +0200 + + dm-thin: fix metadata refcount underflow + + There's a bug in dm-thin in the function rebalance_children. If the + internal btree node has one entry, the code tries to copy all btree + entries from the node's child to the node itself and then decrement the + child's reference count. + + If the child node is shared (it has reference count > 1), we won't free + it, so there would be two pointers to each of the grandchildren nodes. + But the reference counts of the grandchildren is not increased, thus the + reference count doesn't match the number of pointers that point to the + grandchildren. This results in "device mapper: space map common: unable + to decrement block" errors. + + Fix this bug by incrementing reference counts on the grandchildren if the + btree node is shared. + + Signed-off-by: Mikulas Patocka + Fixes: 3241b1d3e0aa ("dm: add persistent data library") + Cc: stable@vger.kernel.org + +Signed-off-by: Benjamin Marzinski + +diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c +index 942cd47eb52d..aeec5b9a1dd5 100644 +--- a/drivers/md/persistent-data/dm-btree-remove.c ++++ b/drivers/md/persistent-data/dm-btree-remove.c +@@ -490,12 +490,20 @@ static int rebalance_children(struct shadow_spine *s, + + if (le32_to_cpu(n->header.nr_entries) == 1) { + struct dm_block *child; ++ int is_shared; + dm_block_t b = value64(n, 0); + ++ r = dm_tm_block_is_shared(info->tm, b, &is_shared); ++ if (r) ++ return r; ++ + r = dm_tm_read_lock(info->tm, b, &btree_node_validator, &child); + if (r) + return r; + ++ if (is_shared) ++ inc_children(info->tm, dm_block_data(child), vt); ++ + memcpy(n, dm_block_data(child), + dm_bm_block_size(dm_tm_get_bm(info->tm))); + +-- +2.50.1 (Apple Git-155) + diff --git a/SPECS/kernel.spec b/SPECS/kernel.spec index e9e62c850..f10134998 100644 --- a/SPECS/kernel.spec +++ b/SPECS/kernel.spec @@ -182,7 +182,7 @@ Summary: The Linux kernel # This is needed to do merge window version magic %define patchlevel 14 # This allows pkg_release to have configurable %%{?dist} tag -%define specrelease 687.10.1%{?buildid}%{?dist} +%define specrelease 687.12.1%{?buildid}%{?dist} # This defines the kabi tarball version %define kabiversion 5.14.0-687.5.1.el9_8 @@ -1073,6 +1073,61 @@ Patch1194: 1194-net-skbuff-preserve-shared-frag-marker-during-coalescing.patch Patch1195: 1195-net-move-skb-gro-receive-list-from-udp-to-core.patch Patch1196: 1196-net-skbuff-propagate-shared-frag-marker-through-frag-transfe.patch Patch1197: 1197-smb-client-reject-userspace-cifs.spnego-descriptions.patch +Patch1198: 1198-netfilter-nf-tables-release-flowtable-after-rcu-grace-period.patch +Patch1199: 1199-revert-mm-pcp-increase-pcp-free-count-threshold-to-trigger-f.patch +Patch1200: 1200-ice-fix-missing-tx-timestamps-interrupts-on-e825-devices.patch +Patch1201: 1201-ice-fix-ptp-timestamping-broken-by-synce-code-on-e825c.patch +Patch1202: 1202-i2c-i801-revert-i2c-i801-replace-acpi-lock-with-i2c-bus-lock.patch +Patch1203: 1203-ima-don-t-clear-ima-digsig-flag-when-setting-or-removing-non.patch +Patch1204: 1204-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch +Patch1205: 1205-netfilter-nf-conntrack-h323-check-for-zero-length-in-decodeq.patch +Patch1206: 1206-iommu-sva-add-kernel-page-table-iotlb-flush-notification.patch +Patch1207: 1207-x86-mm-flush-iommu-before-freeing-kernel-page-table-pages.patch +Patch1208: 1208-nbd-defer-config-unlock-in-nbd-genl-connect.patch +Patch1209: 1209-drm-mgag200-fix-mgag200-bmc-stop-scanout.patch +Patch1210: 1210-ice-fix-timestamp-interrupt-configuration-for-e825c.patch +Patch1211: 1211-ice-perform-phy-soft-reset-for-e825c-ports-at-initialization.patch +Patch1212: 1212-ice-fix-ready-bitmap-check-for-non-e822-devices.patch +Patch1213: 1213-ice-fix-ice-ptp-read-tx-hwtstamp-status-eth56g.patch +Patch1214: 1214-cifs-make-default-value-of-retrans-as-zero.patch +Patch1215: 1215-net-sched-act-csum-validate-nested-vlan-headers.patch +Patch1216: 1216-netfilter-ip6t-eui64-reject-invalid-mac-header-for-all-packe.patch +Patch1217: 1217-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch +Patch1218: 1218-dpll-zl3073x-add-output-pin-frequency-helper.patch +Patch1219: 1219-dpll-zl3073x-include-current-frequency-in-supported-frequenc.patch +Patch1220: 1220-dpll-zl3073x-fix-ref-frequency-setting.patch +Patch1221: 1221-dpll-zl3073x-fix-ref-phase-offset-comp-register-width-for-so.patch +Patch1222: 1222-dpll-zl3073x-remove-redundant-cleanup-in-devm-dpll-init.patch +Patch1223: 1223-ice-fix-null-pointer-dereference-in-ice-reset-all-vfs.patch +Patch1224: 1224-ice-fix-missing-sma-pin-initialization-in-dpll-subsystem.patch +Patch1225: 1225-ice-fix-sma-and-u-fl-pin-state-changes-affecting-paired-pin.patch +Patch1226: 1226-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch +Patch1227: 1227-ice-fix-missing-dpll-notifications-for-sw-pins.patch +Patch1228: 1228-ice-add-dpll-peer-notification-for-paired-sma-and-u-fl-pins.patch +Patch1229: 1229-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch +Patch1230: 1230-netfilter-nf-conntrack-helper-pass-helper-to-expect-cleanup.patch +Patch1231: 1231-hid-wacom-fix-out-of-bounds-read-in-wacom-intuos-bt-irq.patch +Patch1232: 1232-redhat-configs-enable-config-sclp-ofb-for-s390x.patch +Patch1233: 1233-xfs-delete-attr-leaf-freemap-entries-when-empty.patch +Patch1234: 1234-xfs-fix-freemap-adjustments-when-adding-xattrs-to-leaf-block.patch +Patch1235: 1235-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch +Patch1236: 1236-smb-client-validate-the-whole-dacl-before-rewriting-it-in-ci.patch +Patch1237: 1237-smb-client-require-a-full-nfs-mode-sid-before-reading-mode-b.patch +Patch1238: 1238-smb-client-scope-end-of-dacl-to-cifs-debug2-use-in-parse-dac.patch +Patch1239: 1239-smb-client-use-kzalloc-to-zero-initialize-security-descripto.patch +Patch1240: 1240-smb-client-validate-dacloffset-before-building-dacl-pointers.patch +Patch1241: 1241-ice-fix-infinite-recursion-in-ice-cfg-tx-topo-via-ice-init-d.patch +Patch1242: 1242-mm-page-alloc-clear-page-private-in-free-pages-prepare.patch +Patch1243: 1243-pnfs-fix-a-missing-wake-up-while-waiting-on-nfs-layout-drain.patch +Patch1244: 1244-proc-use-the-same-treatment-to-check-proc-lseek-as-ones-for-.patch +Patch1245: 1245-proc-fix-missing-pde-set-flags-for-net-proc-files.patch +Patch1246: 1246-proc-fix-type-confusion-in-pde-set-flags.patch +Patch1247: 1247-crypto-tegra-disable-softirqs-before-finalizing-request.patch +Patch1248: 1248-bluetooth-mgmt-validate-ltk-enc-size-on-load.patch +Patch1249: 1249-bluetooth-sco-fix-race-conditions-in-sco-sock-connect.patch +Patch1250: 1250-wifi-brcmfmac-validate-bsscfg-indices-in-if-events.patch +Patch1251: 1251-netfilter-xt-tcpmss-check-remaining-length-before-reading-op.patch +Patch1252: 1252-dm-thin-fix-metadata-refcount-underflow.patch Patch11111: ppc64le-kvm-support.patch # END OF PATCH DEFINITIONS @@ -1917,6 +1972,61 @@ ApplyPatch 1194-net-skbuff-preserve-shared-frag-marker-during-coalescing.patch ApplyPatch 1195-net-move-skb-gro-receive-list-from-udp-to-core.patch ApplyPatch 1196-net-skbuff-propagate-shared-frag-marker-through-frag-transfe.patch ApplyPatch 1197-smb-client-reject-userspace-cifs.spnego-descriptions.patch +ApplyPatch 1198-netfilter-nf-tables-release-flowtable-after-rcu-grace-period.patch +ApplyPatch 1199-revert-mm-pcp-increase-pcp-free-count-threshold-to-trigger-f.patch +ApplyPatch 1200-ice-fix-missing-tx-timestamps-interrupts-on-e825-devices.patch +ApplyPatch 1201-ice-fix-ptp-timestamping-broken-by-synce-code-on-e825c.patch +ApplyPatch 1202-i2c-i801-revert-i2c-i801-replace-acpi-lock-with-i2c-bus-lock.patch +ApplyPatch 1203-ima-don-t-clear-ima-digsig-flag-when-setting-or-removing-non.patch +ApplyPatch 1204-crypto-asymmetric-keys-prevent-overflow-in-asymmetric-key-ge.patch +ApplyPatch 1205-netfilter-nf-conntrack-h323-check-for-zero-length-in-decodeq.patch +ApplyPatch 1206-iommu-sva-add-kernel-page-table-iotlb-flush-notification.patch +ApplyPatch 1207-x86-mm-flush-iommu-before-freeing-kernel-page-table-pages.patch +ApplyPatch 1208-nbd-defer-config-unlock-in-nbd-genl-connect.patch +ApplyPatch 1209-drm-mgag200-fix-mgag200-bmc-stop-scanout.patch +ApplyPatch 1210-ice-fix-timestamp-interrupt-configuration-for-e825c.patch +ApplyPatch 1211-ice-perform-phy-soft-reset-for-e825c-ports-at-initialization.patch +ApplyPatch 1212-ice-fix-ready-bitmap-check-for-non-e822-devices.patch +ApplyPatch 1213-ice-fix-ice-ptp-read-tx-hwtstamp-status-eth56g.patch +ApplyPatch 1214-cifs-make-default-value-of-retrans-as-zero.patch +ApplyPatch 1215-net-sched-act-csum-validate-nested-vlan-headers.patch +ApplyPatch 1216-netfilter-ip6t-eui64-reject-invalid-mac-header-for-all-packe.patch +ApplyPatch 1217-scsi-storvsc-handle-persistent-reserve-in-truncation-for-hyp.patch +ApplyPatch 1218-dpll-zl3073x-add-output-pin-frequency-helper.patch +ApplyPatch 1219-dpll-zl3073x-include-current-frequency-in-supported-frequenc.patch +ApplyPatch 1220-dpll-zl3073x-fix-ref-frequency-setting.patch +ApplyPatch 1221-dpll-zl3073x-fix-ref-phase-offset-comp-register-width-for-so.patch +ApplyPatch 1222-dpll-zl3073x-remove-redundant-cleanup-in-devm-dpll-init.patch +ApplyPatch 1223-ice-fix-null-pointer-dereference-in-ice-reset-all-vfs.patch +ApplyPatch 1224-ice-fix-missing-sma-pin-initialization-in-dpll-subsystem.patch +ApplyPatch 1225-ice-fix-sma-and-u-fl-pin-state-changes-affecting-paired-pin.patch +ApplyPatch 1226-dpll-export-dpll-pin-change-ntf-for-use-under-dpll-lock.patch +ApplyPatch 1227-ice-fix-missing-dpll-notifications-for-sw-pins.patch +ApplyPatch 1228-ice-add-dpll-peer-notification-for-paired-sma-and-u-fl-pins.patch +ApplyPatch 1229-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch +ApplyPatch 1230-netfilter-nf-conntrack-helper-pass-helper-to-expect-cleanup.patch +ApplyPatch 1231-hid-wacom-fix-out-of-bounds-read-in-wacom-intuos-bt-irq.patch +ApplyPatch 1232-redhat-configs-enable-config-sclp-ofb-for-s390x.patch +ApplyPatch 1233-xfs-delete-attr-leaf-freemap-entries-when-empty.patch +ApplyPatch 1234-xfs-fix-freemap-adjustments-when-adding-xattrs-to-leaf-block.patch +ApplyPatch 1235-bluetooth-sco-fix-use-after-free-in-sco-recv-frame-due-to-mi.patch +ApplyPatch 1236-smb-client-validate-the-whole-dacl-before-rewriting-it-in-ci.patch +ApplyPatch 1237-smb-client-require-a-full-nfs-mode-sid-before-reading-mode-b.patch +ApplyPatch 1238-smb-client-scope-end-of-dacl-to-cifs-debug2-use-in-parse-dac.patch +ApplyPatch 1239-smb-client-use-kzalloc-to-zero-initialize-security-descripto.patch +ApplyPatch 1240-smb-client-validate-dacloffset-before-building-dacl-pointers.patch +ApplyPatch 1241-ice-fix-infinite-recursion-in-ice-cfg-tx-topo-via-ice-init-d.patch +ApplyPatch 1242-mm-page-alloc-clear-page-private-in-free-pages-prepare.patch +ApplyPatch 1243-pnfs-fix-a-missing-wake-up-while-waiting-on-nfs-layout-drain.patch +ApplyPatch 1244-proc-use-the-same-treatment-to-check-proc-lseek-as-ones-for-.patch +ApplyPatch 1245-proc-fix-missing-pde-set-flags-for-net-proc-files.patch +ApplyPatch 1246-proc-fix-type-confusion-in-pde-set-flags.patch +ApplyPatch 1247-crypto-tegra-disable-softirqs-before-finalizing-request.patch +ApplyPatch 1248-bluetooth-mgmt-validate-ltk-enc-size-on-load.patch +ApplyPatch 1249-bluetooth-sco-fix-race-conditions-in-sco-sock-connect.patch +ApplyPatch 1250-wifi-brcmfmac-validate-bsscfg-indices-in-if-events.patch +ApplyPatch 1251-netfilter-xt-tcpmss-check-remaining-length-before-reading-op.patch +ApplyPatch 1252-dm-thin-fix-metadata-refcount-underflow.patch # END OF PATCH APPLICATIONS # Any further pre-build tree manipulations happen here. @@ -3991,6 +4101,70 @@ fi # # %changelog +* Sun Jun 07 2026 Andrew Lukoshko - 5.14.0-687.12.1 +- Recreate RHEL 5.14.0-687.12.1 from CentOS Stream 9 and upstream stable + backports (SOURCES/1198-1252) +- RHEL changelog for 687.11.1..687.12.1 follows: + +* Mon May 25 2026 CKI KWF Bot [5.14.0-687.12.1.el9_8] +- dm-thin: fix metadata refcount underflow (Benjamin Marzinski) [RHEL-169626] +- netfilter: xt_tcpmss: check remaining length before reading optlen (CKI Backport Bot) [RHEL-174216] {CVE-2026-43190} +- wifi: brcmfmac: validate bsscfg indices in IF events (CKI Backport Bot) [RHEL-173848] {CVE-2026-43110} +- Bluetooth: SCO: fix race conditions in sco_sock_connect() (CKI Backport Bot) [RHEL-172599] {CVE-2026-43023} +- Bluetooth: MGMT: validate LTK enc_size on load (CKI Backport Bot) [RHEL-172572] {CVE-2026-43020} +- crypto: tegra - Disable softirqs before finalizing request (CKI Backport Bot) [RHEL-170914] +- proc: fix type confusion in pde_set_flags() (Abhi Das) [RHEL-163343] {CVE-2025-38653} +- proc: fix missing pde_set_flags() for net proc files (Abhi Das) [RHEL-163343] {CVE-2025-38653} +- proc: use the same treatment to check proc_lseek as ones for proc_read_iter et.al (CKI Backport Bot) [RHEL-163343] {CVE-2025-38653} +- pNFS: fix a missing wake up while waiting on NFS_LAYOUT_DRAIN (Olga Kornievskaia) [RHEL-157470] + +* Tue May 19 2026 CKI KWF Bot [5.14.0-687.11.1.el9_8] +- mm/page_alloc: clear page->private in free_pages_prepare() (Rafael Aquini) [RHEL-174750] {CVE-2026-43303} +- ice: fix infinite recursion in ice_cfg_tx_topo via ice_init_dev_hw (CKI Backport Bot) [RHEL-175441] +- smb: client: validate dacloffset before building DACL pointers (Paulo Alcantara) [RHEL-172821] +- smb: client: use kzalloc to zero-initialize security descriptor buffer (Paulo Alcantara) [RHEL-172821] +- smb: client: scope end_of_dacl to CIFS_DEBUG2 use in parse_dacl (Paulo Alcantara) [RHEL-172821] +- smb: client: require a full NFS mode SID before reading mode bits (Paulo Alcantara) [RHEL-172821] +- smb: client: validate the whole DACL before rewriting it in cifsacl (Paulo Alcantara) [RHEL-172821] {CVE-2026-31709} +- Bluetooth: SCO: Fix use-after-free in sco_recv_frame() due to missing sock_hold (David Marlin) [RHEL-165063] {CVE-2026-31408} +- xfs: fix freemap adjustments when adding xattrs to leaf blocks (CKI Backport Bot) [RHEL-174058] {CVE-2026-43158} +- xfs: delete attr leaf freemap entries when empty (CKI Backport Bot) [RHEL-174058] {CVE-2026-43158} +- redhat/configs: enable CONFIG_SCLP_OFB for s390x (Jan Polensky) [RHEL-172927] +- HID: wacom: fix out-of-bounds read in wacom_intuos_bt_irq (CKI Backport Bot) [RHEL-172740] {CVE-2026-43051} +- netfilter: nf_conntrack_helper: pass helper to expect cleanup (CKI Backport Bot) [RHEL-172620] {CVE-2026-43027} +- s390/pci: Avoid deadlock between PCI error recovery and mlx5 crdump (Ramesh Chhetri) [RHEL-166859] +- ice: add dpll peer notification for paired SMA and U.FL pins (Petr Oros) [RHEL-171829] +- ice: fix missing dpll notifications for SW pins (Petr Oros) [RHEL-171829] +- dpll: export __dpll_pin_change_ntf() for use under dpll_lock (Petr Oros) [RHEL-171829] +- ice: fix SMA and U.FL pin state changes affecting paired pin (Petr Oros) [RHEL-162179] +- ice: fix missing SMA pin initialization in DPLL subsystem (Petr Oros) [RHEL-171832] +- ice: fix NULL pointer dereference in ice_reset_all_vfs() (Petr Oros) [RHEL-172257] +- dpll: zl3073x: Remove redundant cleanup in devm_dpll_init() (CKI Backport Bot) [RHEL-164442] +- dpll: zl3073x: fix REF_PHASE_OFFSET_COMP register width for some chip IDs (CKI Backport Bot) [RHEL-164442] +- dpll: zl3073x: Fix ref frequency setting (CKI Backport Bot) [RHEL-164442] +- dpll: zl3073x: Include current frequency in supported frequencies list (CKI Backport Bot) [RHEL-164442] +- dpll: zl3073x: Add output pin frequency helper (CKI Backport Bot) [RHEL-164442] +- scsi: storvsc: Handle PERSISTENT_RESERVE_IN truncation for Hyper-V vFC (Vitaly Kuznetsov) [RHEL-171378] +- netfilter: ip6t_eui64: reject invalid MAC header for all packets (CKI Backport Bot) [RHEL-171155] {CVE-2026-31685} +- net: sched: act_csum: validate nested VLAN headers (CKI Backport Bot) [RHEL-171138] {CVE-2026-31684} +- cifs: make default value of retrans as zero (Paulo Alcantara) [RHEL-170960] +- ice: fix ice_ptp_read_tx_hwtstamp_status_eth56g (Petr Oros) [RHEL-170701] +- ice: fix ready bitmap check for non-E822 devices (Petr Oros) [RHEL-170701] +- ice: perform PHY soft reset for E825C ports at initialization (Petr Oros) [RHEL-170701] +- ice: fix timestamp interrupt configuration for E825C (Petr Oros) [RHEL-170701] +- drm/mgag200: fix mgag200_bmc_stop_scanout() (Jocelyn Falempe) [RHEL-150179] +- nbd: defer config unlock in nbd_genl_connect (Jeff Moyer) [RHEL-166950] {CVE-2025-68366} +- x86/mm: flush IOMMU before freeing kernel page table pages (Jerry Snitselaar) [RHEL-167100] {CVE-2025-71089} +- iommu/sva: add kernel page table IOTLB flush notification (Jerry Snitselaar) [RHEL-167100] {CVE-2025-71089} +- netfilter: nf_conntrack_h323: check for zero length in DecodeQ931() (CKI Backport Bot) [RHEL-166987] {CVE-2026-23455} +- crypto: asymmetric_keys - prevent overflow in asymmetric_key_generate_id (CKI Backport Bot) [RHEL-166927] {CVE-2025-68724} +- ima: don't clear IMA_DIGSIG flag when setting or removing non-IMA xattr (Bruno Meneguele) [RHEL-169734] {CVE-2025-68183} +- i2c: i801: Revert "i2c: i801: replace acpi_lock with I2C bus lock" (David Arcari) [RHEL-155312] +- ice: fix PTP timestamping broken by SyncE code on E825C (Petr Oros) [RHEL-162182] +- ice: fix missing TX timestamps interrupts on E825 devices (CKI Backport Bot) [RHEL-162185] +- Revert "mm: pcp: increase pcp->free_count threshold to trigger free_high" (Luiz Capitulino) [RHEL-163464] +- netfilter: nf_tables: release flowtable after rcu grace period on error (CKI Backport Bot) [RHEL-160461] {CVE-2026-23392} + * Sun Jun 07 2026 Andrew Lukoshko - 5.14.0-687.10.1 - Recreate RHEL 5.14.0-687.10.1 from CentOS Stream 9 and upstream stable backports (SOURCES/1100-1196)