From: Greg Kroah-Hartman Date: Wed, 8 Apr 2026 13:02:17 +0000 (+0200) Subject: 6.18-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=93b8917dd588ca8378bc3e1f0ec3461d85ff630f;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: drm-amd-display-fix-dce-lvds-handling.patch drm-amd-pm-disable-od_fan_curve-if-temp-or-pwm-range-invalid-for-smu-v13.patch kallsyms-clean-up-modname-and-modbuildid-initialization-in-kallsyms_lookup_buildid.patch kallsyms-clean-up-namebuf-initialization-in-kallsyms_lookup_buildid.patch kallsyms-cleanup-code-for-appending-the-module-buildid.patch kallsyms-prevent-module-removal-when-printing-module-name-and-buildid.patch mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch mm-replace-read_once-with-standard-page-table-accessors.patch net-correctly-handle-tunneled-traffic-on-ipv6_csum-gso-fallback.patch net-mana-fix-use-after-free-in-add_adev-error-path.patch scsi-target-file-use-kzalloc_flex-for-aio_cmd.patch scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch wifi-virt_wifi-remove-set_netdev_dev-to-avoid-use-after-free.patch --- diff --git a/queue-6.18/drm-amd-display-fix-dce-lvds-handling.patch b/queue-6.18/drm-amd-display-fix-dce-lvds-handling.patch new file mode 100644 index 0000000000..e807859346 --- /dev/null +++ b/queue-6.18/drm-amd-display-fix-dce-lvds-handling.patch @@ -0,0 +1,169 @@ +From stable+bounces-232617-greg=kroah.com@vger.kernel.org Wed Apr 1 02:22:43 2026 +From: Sasha Levin +Date: Tue, 31 Mar 2026 20:19:34 -0400 +Subject: drm/amd/display: Fix DCE LVDS handling +To: stable@vger.kernel.org +Cc: Alex Deucher , Srinivasan Shanmugam , Roman Li , Sasha Levin +Message-ID: <20260401001934.3984005-1-sashal@kernel.org> + +From: Alex Deucher + +[ Upstream commit 90d239cc53723c1a3f89ce08eac17bf3a9e9f2d4 ] + +LVDS does not use an HPD pin so it may be invalid. Handle +this case correctly in link encoder creation. + +Fixes: 7c8fb3b8e9ba ("drm/amd/display: Add hpd_source index check for DCE60/80/100/110/112/120 link encoders") +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/5012 +Cc: Srinivasan Shanmugam +Cc: Roman Li +Reviewed-by: Roman Li +Reviewed-by: Srinivasan Shanmugam +Signed-off-by: Alex Deucher +(cherry picked from commit 3b5620f7ee688177fcf65cf61588c5435bce1872) +Cc: stable@vger.kernel.org +[ removed unrelated VGA connector block absent from stable and split combined null/bounds check into separate guard and ternary ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c | 5 ++- + drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c | 5 ++- + drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c | 5 ++- + drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c | 5 ++- + drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c | 13 +++++----- + drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c | 5 ++- + 6 files changed, 22 insertions(+), 16 deletions(-) + +--- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +@@ -624,7 +624,7 @@ static struct link_encoder *dce100_link_ + kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) ++ if (!enc110) + return NULL; + + link_regs_id = +@@ -635,7 +635,8 @@ static struct link_encoder *dce100_link_ + &link_enc_feature, + &link_enc_regs[link_regs_id], + &link_enc_aux_regs[enc_init_data->channel - 1], +- &link_enc_hpd_regs[enc_init_data->hpd_source]); ++ enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? ++ NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); + return &enc110->base; + } + +--- a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c +@@ -668,7 +668,7 @@ static struct link_encoder *dce110_link_ + kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) ++ if (!enc110) + return NULL; + + link_regs_id = +@@ -679,7 +679,8 @@ static struct link_encoder *dce110_link_ + &link_enc_feature, + &link_enc_regs[link_regs_id], + &link_enc_aux_regs[enc_init_data->channel - 1], +- &link_enc_hpd_regs[enc_init_data->hpd_source]); ++ enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? ++ NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); + return &enc110->base; + } + +--- a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c +@@ -629,7 +629,7 @@ static struct link_encoder *dce112_link_ + kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) ++ if (!enc110) + return NULL; + + link_regs_id = +@@ -640,7 +640,8 @@ static struct link_encoder *dce112_link_ + &link_enc_feature, + &link_enc_regs[link_regs_id], + &link_enc_aux_regs[enc_init_data->channel - 1], +- &link_enc_hpd_regs[enc_init_data->hpd_source]); ++ enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? ++ NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); + return &enc110->base; + } + +--- a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c +@@ -713,7 +713,7 @@ static struct link_encoder *dce120_link_ + kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) ++ if (!enc110) + return NULL; + + link_regs_id = +@@ -724,7 +724,8 @@ static struct link_encoder *dce120_link_ + &link_enc_feature, + &link_enc_regs[link_regs_id], + &link_enc_aux_regs[enc_init_data->channel - 1], +- &link_enc_hpd_regs[enc_init_data->hpd_source]); ++ enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? ++ NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); + + return &enc110->base; + } +--- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +@@ -718,18 +718,19 @@ static struct link_encoder *dce60_link_e + kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) ++ if (!enc110) + return NULL; + + link_regs_id = + map_transmitter_id_to_phy_instance(enc_init_data->transmitter); + + dce60_link_encoder_construct(enc110, +- enc_init_data, +- &link_enc_feature, +- &link_enc_regs[link_regs_id], +- &link_enc_aux_regs[enc_init_data->channel - 1], +- &link_enc_hpd_regs[enc_init_data->hpd_source]); ++ enc_init_data, ++ &link_enc_feature, ++ &link_enc_regs[link_regs_id], ++ &link_enc_aux_regs[enc_init_data->channel - 1], ++ enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? ++ NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); + return &enc110->base; + } + +--- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c ++++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +@@ -724,7 +724,7 @@ static struct link_encoder *dce80_link_e + kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + int link_regs_id; + +- if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) ++ if (!enc110) + return NULL; + + link_regs_id = +@@ -735,7 +735,8 @@ static struct link_encoder *dce80_link_e + &link_enc_feature, + &link_enc_regs[link_regs_id], + &link_enc_aux_regs[enc_init_data->channel - 1], +- &link_enc_hpd_regs[enc_init_data->hpd_source]); ++ enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ? ++ NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]); + return &enc110->base; + } + diff --git a/queue-6.18/drm-amd-pm-disable-od_fan_curve-if-temp-or-pwm-range-invalid-for-smu-v13.patch b/queue-6.18/drm-amd-pm-disable-od_fan_curve-if-temp-or-pwm-range-invalid-for-smu-v13.patch new file mode 100644 index 0000000000..c48f20b36c --- /dev/null +++ b/queue-6.18/drm-amd-pm-disable-od_fan_curve-if-temp-or-pwm-range-invalid-for-smu-v13.patch @@ -0,0 +1,148 @@ +From stable+bounces-232821-greg=kroah.com@vger.kernel.org Wed Apr 1 18:52:00 2026 +From: Sasha Levin +Date: Wed, 1 Apr 2026 12:31:35 -0400 +Subject: drm/amd/pm: disable OD_FAN_CURVE if temp or pwm range invalid for smu v13 +To: stable@vger.kernel.org +Cc: Yang Wang , Alex Deucher , Sasha Levin +Message-ID: <20260401163135.124580-1-sashal@kernel.org> + +From: Yang Wang + +[ Upstream commit 3e6dd28a11083e83e11a284d99fcc9eb748c321c ] + +Forcibly disable the OD_FAN_CURVE feature when temperature or PWM range is invalid, +otherwise PMFW will reject this configuration on smu v13.0.x + +example: +$ sudo cat /sys/bus/pci/devices//gpu_od/fan_ctrl/fan_curve + +OD_FAN_CURVE: +0: 0C 0% +1: 0C 0% +2: 0C 0% +3: 0C 0% +4: 0C 0% +OD_RANGE: +FAN_CURVE(hotspot temp): 0C 0C +FAN_CURVE(fan speed): 0% 0% + +$ echo "0 50 40" | sudo tee fan_curve + +kernel log: +[ 756.442527] amdgpu 0000:03:00.0: amdgpu: Fan curve temp setting(50) must be within [0, 0]! +[ 777.345800] amdgpu 0000:03:00.0: amdgpu: Fan curve temp setting(50) must be within [0, 0]! + +Closes: https://github.com/ROCm/amdgpu/issues/208 +Signed-off-by: Yang Wang +Acked-by: Alex Deucher +Signed-off-by: Alex Deucher +(cherry picked from commit 470891606c5a97b1d0d937e0aa67a3bed9fcb056) +Cc: stable@vger.kernel.org +[ adapted forward declaration placement to existing FEATURE_MASK macro ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 33 ++++++++++++++++++- + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 33 ++++++++++++++++++- + 2 files changed, 64 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +@@ -59,6 +59,10 @@ + + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) + ++static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, ++ int od_feature_bit, ++ int32_t *min, int32_t *max); ++ + #define FEATURE_MASK(feature) (1ULL << feature) + #define SMC_DPM_FEATURE ( \ + FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ +@@ -1061,8 +1065,35 @@ static bool smu_v13_0_0_is_od_feature_su + PPTable_t *pptable = smu->smu_table.driver_pptable; + const OverDriveLimits_t * const overdrive_upperlimits = + &pptable->SkuTable.OverDriveLimitsBasicMax; ++ int32_t min_value, max_value; ++ bool feature_enabled; ++ ++ switch (od_feature_bit) { ++ case PP_OD_FEATURE_FAN_CURVE_BIT: ++ feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); ++ if (feature_enabled) { ++ smu_v13_0_0_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_TEMP, ++ &min_value, &max_value); ++ if (!min_value && !max_value) { ++ feature_enabled = false; ++ goto out; ++ } ++ ++ smu_v13_0_0_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_PWM, ++ &min_value, &max_value); ++ if (!min_value && !max_value) { ++ feature_enabled = false; ++ goto out; ++ } ++ } ++ break; ++ default: ++ feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); ++ break; ++ } + +- return overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit); ++out: ++ return feature_enabled; + } + + static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu, +--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c ++++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +@@ -59,6 +59,10 @@ + + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) + ++static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, ++ int od_feature_bit, ++ int32_t *min, int32_t *max); ++ + #define FEATURE_MASK(feature) (1ULL << feature) + #define SMC_DPM_FEATURE ( \ + FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ +@@ -1050,8 +1054,35 @@ static bool smu_v13_0_7_is_od_feature_su + PPTable_t *pptable = smu->smu_table.driver_pptable; + const OverDriveLimits_t * const overdrive_upperlimits = + &pptable->SkuTable.OverDriveLimitsBasicMax; ++ int32_t min_value, max_value; ++ bool feature_enabled; ++ ++ switch (od_feature_bit) { ++ case PP_OD_FEATURE_FAN_CURVE_BIT: ++ feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); ++ if (feature_enabled) { ++ smu_v13_0_7_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_TEMP, ++ &min_value, &max_value); ++ if (!min_value && !max_value) { ++ feature_enabled = false; ++ goto out; ++ } ++ ++ smu_v13_0_7_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_PWM, ++ &min_value, &max_value); ++ if (!min_value && !max_value) { ++ feature_enabled = false; ++ goto out; ++ } ++ } ++ break; ++ default: ++ feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit)); ++ break; ++ } + +- return overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit); ++out: ++ return feature_enabled; + } + + static void smu_v13_0_7_get_od_setting_limits(struct smu_context *smu, diff --git a/queue-6.18/kallsyms-clean-up-modname-and-modbuildid-initialization-in-kallsyms_lookup_buildid.patch b/queue-6.18/kallsyms-clean-up-modname-and-modbuildid-initialization-in-kallsyms_lookup_buildid.patch new file mode 100644 index 0000000000..fdbab797d2 --- /dev/null +++ b/queue-6.18/kallsyms-clean-up-modname-and-modbuildid-initialization-in-kallsyms_lookup_buildid.patch @@ -0,0 +1,67 @@ +From fda024fb64769e9d6b3916d013c78d6b189129f8 Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Fri, 28 Nov 2025 14:59:15 +0100 +Subject: kallsyms: clean up modname and modbuildid initialization in kallsyms_lookup_buildid() + +From: Petr Mladek + +commit fda024fb64769e9d6b3916d013c78d6b189129f8 upstream. + +The @modname and @modbuildid optional return parameters are set only when +the symbol is in a module. + +Always initialize them so that they do not need to be cleared when the +module is not in a module. It simplifies the logic and makes the code +even slightly more safe. + +Note that bpf_address_lookup() function will get updated in a separate +patch. + +Link: https://lkml.kernel.org/r/20251128135920.217303-3-pmladek@suse.com +Signed-off-by: Petr Mladek +Cc: Aaron Tomlin +Cc: Alexei Starovoitov +Cc: Daniel Borkman +Cc: Daniel Gomez +Cc: John Fastabend +Cc: Kees Cook +Cc: Luis Chamberalin +Cc: Marc Rutland +Cc: "Masami Hiramatsu (Google)" +Cc: Petr Pavlu +Cc: Sami Tolvanen +Cc: Steven Rostedt (Google) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + kernel/kallsyms.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -362,6 +362,14 @@ static int kallsyms_lookup_buildid(unsig + * or empty string. + */ + namebuf[0] = 0; ++ /* ++ * Initialize the module-related return values. They are not set ++ * when the symbol is in vmlinux or it is a bpf address. ++ */ ++ if (modname) ++ *modname = NULL; ++ if (modbuildid) ++ *modbuildid = NULL; + + if (is_ksym_addr(addr)) { + unsigned long pos; +@@ -370,10 +378,6 @@ static int kallsyms_lookup_buildid(unsig + /* Grab name */ + kallsyms_expand_symbol(get_symbol_offset(pos), + namebuf, KSYM_NAME_LEN); +- if (modname) +- *modname = NULL; +- if (modbuildid) +- *modbuildid = NULL; + + return strlen(namebuf); + } diff --git a/queue-6.18/kallsyms-clean-up-namebuf-initialization-in-kallsyms_lookup_buildid.patch b/queue-6.18/kallsyms-clean-up-namebuf-initialization-in-kallsyms_lookup_buildid.patch new file mode 100644 index 0000000000..85f80f9a38 --- /dev/null +++ b/queue-6.18/kallsyms-clean-up-namebuf-initialization-in-kallsyms_lookup_buildid.patch @@ -0,0 +1,112 @@ +From 426295ef18c5d5f0b7f75ac89d09022fcfafd25c Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Fri, 28 Nov 2025 14:59:14 +0100 +Subject: kallsyms: clean up @namebuf initialization in kallsyms_lookup_buildid() + +From: Petr Mladek + +commit 426295ef18c5d5f0b7f75ac89d09022fcfafd25c upstream. + +Patch series "kallsyms: Prevent invalid access when showing module +buildid", v3. + +We have seen nested crashes in __sprint_symbol(), see below. They seem to +be caused by an invalid pointer to "buildid". This patchset cleans up +kallsyms code related to module buildid and fixes this invalid access when +printing backtraces. + +I made an audit of __sprint_symbol() and found several situations +when the buildid might be wrong: + + + bpf_address_lookup() does not set @modbuildid + + + ftrace_mod_address_lookup() does not set @modbuildid + + + __sprint_symbol() does not take rcu_read_lock and + the related struct module might get removed before + mod->build_id is printed. + +This patchset solves these problems: + + + 1st, 2nd patches are preparatory + + 3rd, 4th, 6th patches fix the above problems + + 5th patch cleans up a suspicious initialization code. + +This is the backtrace, we have seen. But it is not really important. +The problems fixed by the patchset are obvious: + + crash64> bt [62/2029] + PID: 136151 TASK: ffff9f6c981d4000 CPU: 367 COMMAND: "btrfs" + #0 [ffffbdb687635c28] machine_kexec at ffffffffb4c845b3 + #1 [ffffbdb687635c80] __crash_kexec at ffffffffb4d86a6a + #2 [ffffbdb687635d08] hex_string at ffffffffb51b3b61 + #3 [ffffbdb687635d40] crash_kexec at ffffffffb4d87964 + #4 [ffffbdb687635d50] oops_end at ffffffffb4c41fc8 + #5 [ffffbdb687635d70] do_trap at ffffffffb4c3e49a + #6 [ffffbdb687635db8] do_error_trap at ffffffffb4c3e6a4 + #7 [ffffbdb687635df8] exc_stack_segment at ffffffffb5666b33 + #8 [ffffbdb687635e20] asm_exc_stack_segment at ffffffffb5800cf9 + ... + + +This patch (of 7) + +The function kallsyms_lookup_buildid() initializes the given @namebuf by +clearing the first and the last byte. It is not clear why. + +The 1st byte makes sense because some callers ignore the return code and +expect that the buffer contains a valid string, for example: + + - function_stat_show() + - kallsyms_lookup() + - kallsyms_lookup_buildid() + +The initialization of the last byte does not make much sense because it +can later be overwritten. Fortunately, it seems that all called functions +behave correctly: + + - kallsyms_expand_symbol() explicitly adds the trailing '\0' + at the end of the function. + + - All *__address_lookup() functions either use the safe strscpy() + or they do not touch the buffer at all. + +Document the reason for clearing the first byte. And remove the useless +initialization of the last byte. + +Link: https://lkml.kernel.org/r/20251128135920.217303-2-pmladek@suse.com +Signed-off-by: Petr Mladek +Reviewed-by: Aaron Tomlin +Cc: Alexei Starovoitov +Cc: Daniel Borkman +Cc: John Fastabend +Cc: Kees Cook +Cc: Luis Chamberalin +Cc: Marc Rutland +Cc: "Masami Hiramatsu (Google)" +Cc: Petr Pavlu +Cc: Sami Tolvanen +Cc: Steven Rostedt +Cc: Daniel Gomez +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + kernel/kallsyms.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -355,7 +355,12 @@ static int kallsyms_lookup_buildid(unsig + { + int ret; + +- namebuf[KSYM_NAME_LEN - 1] = 0; ++ /* ++ * kallsyms_lookus() returns pointer to namebuf on success and ++ * NULL on error. But some callers ignore the return value. ++ * Instead they expect @namebuf filled either with valid ++ * or empty string. ++ */ + namebuf[0] = 0; + + if (is_ksym_addr(addr)) { diff --git a/queue-6.18/kallsyms-cleanup-code-for-appending-the-module-buildid.patch b/queue-6.18/kallsyms-cleanup-code-for-appending-the-module-buildid.patch new file mode 100644 index 0000000000..2665a1eb7c --- /dev/null +++ b/queue-6.18/kallsyms-cleanup-code-for-appending-the-module-buildid.patch @@ -0,0 +1,98 @@ +From 8e81dac4cd5477731169b92cff7c24f8f6635950 Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Fri, 28 Nov 2025 14:59:17 +0100 +Subject: kallsyms: cleanup code for appending the module buildid + +From: Petr Mladek + +commit 8e81dac4cd5477731169b92cff7c24f8f6635950 upstream. + +Put the code for appending the optional "buildid" into a helper function, +It makes __sprint_symbol() better readable. + +Also print a warning when the "modname" is set and the "buildid" isn't. +It might catch a situation when some lookup function in +kallsyms_lookup_buildid() does not handle the "buildid". + +Use pr_*_once() to avoid an infinite recursion when the function is called +from printk(). The recursion is rather theoretical but better be on the +safe side. + +Link: https://lkml.kernel.org/r/20251128135920.217303-5-pmladek@suse.com +Signed-off-by: Petr Mladek +Cc: Aaron Tomlin +Cc: Alexei Starovoitov +Cc: Daniel Borkman +Cc: Daniel Gomez +Cc: John Fastabend +Cc: Kees Cook +Cc: Luis Chamberalin +Cc: Marc Rutland +Cc: "Masami Hiramatsu (Google)" +Cc: Petr Pavlu +Cc: Sami Tolvanen +Cc: Steven Rostedt (Google) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + kernel/kallsyms.c | 42 +++++++++++++++++++++++++++++++++--------- + 1 file changed, 33 insertions(+), 9 deletions(-) + +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -434,6 +434,37 @@ int lookup_symbol_name(unsigned long add + return lookup_module_symbol_name(addr, symname); + } + ++#ifdef CONFIG_STACKTRACE_BUILD_ID ++ ++static int append_buildid(char *buffer, const char *modname, ++ const unsigned char *buildid) ++{ ++ if (!modname) ++ return 0; ++ ++ if (!buildid) { ++ pr_warn_once("Undefined buildid for the module %s\n", modname); ++ return 0; ++ } ++ ++ /* build ID should match length of sprintf */ ++#ifdef CONFIG_MODULES ++ static_assert(sizeof(typeof_member(struct module, build_id)) == 20); ++#endif ++ ++ return sprintf(buffer, " %20phN", buildid); ++} ++ ++#else /* CONFIG_STACKTRACE_BUILD_ID */ ++ ++static int append_buildid(char *buffer, const char *modname, ++ const unsigned char *buildid) ++{ ++ return 0; ++} ++ ++#endif /* CONFIG_STACKTRACE_BUILD_ID */ ++ + /* Look up a kernel symbol and return it in a text buffer. */ + static int __sprint_symbol(char *buffer, unsigned long address, + int symbol_offset, int add_offset, int add_buildid) +@@ -456,15 +487,8 @@ static int __sprint_symbol(char *buffer, + + if (modname) { + len += sprintf(buffer + len, " [%s", modname); +-#if IS_ENABLED(CONFIG_STACKTRACE_BUILD_ID) +- if (add_buildid && buildid) { +- /* build ID should match length of sprintf */ +-#if IS_ENABLED(CONFIG_MODULES) +- static_assert(sizeof(typeof_member(struct module, build_id)) == 20); +-#endif +- len += sprintf(buffer + len, " %20phN", buildid); +- } +-#endif ++ if (add_buildid) ++ len += append_buildid(buffer + len, modname, buildid); + len += sprintf(buffer + len, "]"); + } + diff --git a/queue-6.18/kallsyms-prevent-module-removal-when-printing-module-name-and-buildid.patch b/queue-6.18/kallsyms-prevent-module-removal-when-printing-module-name-and-buildid.patch new file mode 100644 index 0000000000..dc1ad3ec77 --- /dev/null +++ b/queue-6.18/kallsyms-prevent-module-removal-when-printing-module-name-and-buildid.patch @@ -0,0 +1,49 @@ +From 3b07086444f80c844351255fd94c2cb0a7224df2 Mon Sep 17 00:00:00 2001 +From: Petr Mladek +Date: Fri, 28 Nov 2025 14:59:20 +0100 +Subject: kallsyms: prevent module removal when printing module name and buildid + +From: Petr Mladek + +commit 3b07086444f80c844351255fd94c2cb0a7224df2 upstream. + +kallsyms_lookup_buildid() copies the symbol name into the given buffer so +that it can be safely read anytime later. But it just copies pointers to +mod->name and mod->build_id which might get reused after the related +struct module gets removed. + +The lifetime of struct module is synchronized using RCU. Take the rcu +read lock for the entire __sprint_symbol(). + +Link: https://lkml.kernel.org/r/20251128135920.217303-8-pmladek@suse.com +Signed-off-by: Petr Mladek +Reviewed-by: Aaron Tomlin +Cc: Alexei Starovoitov +Cc: Daniel Borkman +Cc: Daniel Gomez +Cc: John Fastabend +Cc: Kees Cook +Cc: Luis Chamberalin +Cc: Marc Rutland +Cc: "Masami Hiramatsu (Google)" +Cc: Petr Pavlu +Cc: Sami Tolvanen +Cc: Steven Rostedt (Google) +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + kernel/kallsyms.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -474,6 +474,9 @@ static int __sprint_symbol(char *buffer, + unsigned long offset, size; + int len; + ++ /* Prevent module removal until modname and modbuildid are printed */ ++ guard(rcu)(); ++ + address += symbol_offset; + len = kallsyms_lookup_buildid(address, &size, &offset, &modname, &buildid, + buffer); diff --git a/queue-6.18/mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch b/queue-6.18/mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch new file mode 100644 index 0000000000..3f93452f12 --- /dev/null +++ b/queue-6.18/mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch @@ -0,0 +1,103 @@ +From stable+bounces-232825-greg=kroah.com@vger.kernel.org Wed Apr 1 18:51:56 2026 +From: Sasha Levin +Date: Wed, 1 Apr 2026 12:45:26 -0400 +Subject: mm/memory: fix PMD/PUD checks in follow_pfnmap_start() +To: stable@vger.kernel.org +Cc: "David Hildenbrand (Arm)" , "Mike Rapoport (Microsoft)" , "Lorenzo Stoakes (Oracle)" , Liam Howlett , Michal Hocko , Peter Xu , Suren Baghdasaryan , Vlastimil Babka , Andrew Morton , Sasha Levin +Message-ID: <20260401164526.141913-2-sashal@kernel.org> + +From: "David Hildenbrand (Arm)" + +[ Upstream commit ffef67b93aa352b34e6aeba3d52c19a63885409a ] + +follow_pfnmap_start() suffers from two problems: + +(1) We are not re-fetching the pmd/pud after taking the PTL + +Therefore, we are not properly stabilizing what the lock actually +protects. If there is concurrent zapping, we would indicate to the +caller that we found an entry, however, that entry might already have +been invalidated, or contain a different PFN after taking the lock. + +Properly use pmdp_get() / pudp_get() after taking the lock. + +(2) pmd_leaf() / pud_leaf() are not well defined on non-present entries + +pmd_leaf()/pud_leaf() could wrongly trigger on non-present entries. + +There is no real guarantee that pmd_leaf()/pud_leaf() returns something +reasonable on non-present entries. Most architectures indeed either +perform a present check or make it work by smart use of flags. + +However, for example loongarch checks the _PAGE_HUGE flag in pmd_leaf(), +and always sets the _PAGE_HUGE flag in __swp_entry_to_pmd(). Whereby +pmd_trans_huge() explicitly checks pmd_present(), pmd_leaf() does not do +that. + +Let's check pmd_present()/pud_present() before assuming "the is a present +PMD leaf" when spotting pmd_leaf()/pud_leaf(), like other page table +handling code that traverses user page tables does. + +Given that non-present PMD entries are likely rare in VM_IO|VM_PFNMAP, (1) +is likely more relevant than (2). It is questionable how often (1) would +actually trigger, but let's CC stable to be sure. + +This was found by code inspection. + +Link: https://lkml.kernel.org/r/20260323-follow_pfnmap_fix-v1-1-5b0ec10872b3@kernel.org +Fixes: 6da8e9634bb7 ("mm: new follow_pfnmap API") +Signed-off-by: David Hildenbrand (Arm) +Acked-by: Mike Rapoport (Microsoft) +Reviewed-by: Lorenzo Stoakes (Oracle) +Cc: Liam Howlett +Cc: Michal Hocko +Cc: Peter Xu +Cc: Suren Baghdasaryan +Cc: Vlastimil Babka +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/memory.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -6697,11 +6697,16 @@ retry: + + pudp = pud_offset(p4dp, address); + pud = pudp_get(pudp); +- if (pud_none(pud)) ++ if (!pud_present(pud)) + goto out; + if (pud_leaf(pud)) { + lock = pud_lock(mm, pudp); +- if (!unlikely(pud_leaf(pud))) { ++ pud = pudp_get(pudp); ++ ++ if (unlikely(!pud_present(pud))) { ++ spin_unlock(lock); ++ goto out; ++ } else if (unlikely(!pud_leaf(pud))) { + spin_unlock(lock); + goto retry; + } +@@ -6713,9 +6718,16 @@ retry: + + pmdp = pmd_offset(pudp, address); + pmd = pmdp_get_lockless(pmdp); ++ if (!pmd_present(pmd)) ++ goto out; + if (pmd_leaf(pmd)) { + lock = pmd_lock(mm, pmdp); +- if (!unlikely(pmd_leaf(pmd))) { ++ pmd = pmdp_get(pmdp); ++ ++ if (unlikely(!pmd_present(pmd))) { ++ spin_unlock(lock); ++ goto out; ++ } else if (unlikely(!pmd_leaf(pmd))) { + spin_unlock(lock); + goto retry; + } diff --git a/queue-6.18/mm-replace-read_once-with-standard-page-table-accessors.patch b/queue-6.18/mm-replace-read_once-with-standard-page-table-accessors.patch new file mode 100644 index 0000000000..5540ddf416 --- /dev/null +++ b/queue-6.18/mm-replace-read_once-with-standard-page-table-accessors.patch @@ -0,0 +1,143 @@ +From stable+bounces-232824-greg=kroah.com@vger.kernel.org Wed Apr 1 19:02:06 2026 +From: Sasha Levin +Date: Wed, 1 Apr 2026 12:45:25 -0400 +Subject: mm: replace READ_ONCE() with standard page table accessors +To: stable@vger.kernel.org +Cc: Anshuman Khandual , David Hildenbrand , Lance Yang , Wei Yang , Dev Jain , Andrew Morton , Sasha Levin +Message-ID: <20260401164526.141913-1-sashal@kernel.org> + +From: Anshuman Khandual + +[ Upstream commit c0efdb373c3aaacb32db59cadb0710cac13e44ae ] + +Replace all READ_ONCE() with a standard page table accessors i.e +pxdp_get() that defaults into READ_ONCE() in cases where platform does not +override. + +Link: https://lkml.kernel.org/r/20251007063100.2396936-1-anshuman.khandual@arm.com +Signed-off-by: Anshuman Khandual +Acked-by: David Hildenbrand +Reviewed-by: Lance Yang +Reviewed-by: Wei Yang +Reviewed-by: Dev Jain +Signed-off-by: Andrew Morton +Stable-dep-of: ffef67b93aa3 ("mm/memory: fix PMD/PUD checks in follow_pfnmap_start()") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/gup.c | 10 +++++----- + mm/hmm.c | 2 +- + mm/memory.c | 4 ++-- + mm/mprotect.c | 2 +- + mm/sparse-vmemmap.c | 2 +- + mm/vmscan.c | 2 +- + 6 files changed, 11 insertions(+), 11 deletions(-) + +--- a/mm/gup.c ++++ b/mm/gup.c +@@ -950,7 +950,7 @@ static struct page *follow_pud_mask(stru + struct mm_struct *mm = vma->vm_mm; + + pudp = pud_offset(p4dp, address); +- pud = READ_ONCE(*pudp); ++ pud = pudp_get(pudp); + if (!pud_present(pud)) + return no_page_table(vma, flags, address); + if (pud_leaf(pud)) { +@@ -975,7 +975,7 @@ static struct page *follow_p4d_mask(stru + p4d_t *p4dp, p4d; + + p4dp = p4d_offset(pgdp, address); +- p4d = READ_ONCE(*p4dp); ++ p4d = p4dp_get(p4dp); + BUILD_BUG_ON(p4d_leaf(p4d)); + + if (!p4d_present(p4d) || p4d_bad(p4d)) +@@ -3060,7 +3060,7 @@ static int gup_fast_pud_range(p4d_t *p4d + + pudp = pud_offset_lockless(p4dp, p4d, addr); + do { +- pud_t pud = READ_ONCE(*pudp); ++ pud_t pud = pudp_get(pudp); + + next = pud_addr_end(addr, end); + if (unlikely(!pud_present(pud))) +@@ -3086,7 +3086,7 @@ static int gup_fast_p4d_range(pgd_t *pgd + + p4dp = p4d_offset_lockless(pgdp, pgd, addr); + do { +- p4d_t p4d = READ_ONCE(*p4dp); ++ p4d_t p4d = p4dp_get(p4dp); + + next = p4d_addr_end(addr, end); + if (!p4d_present(p4d)) +@@ -3108,7 +3108,7 @@ static void gup_fast_pgd_range(unsigned + + pgdp = pgd_offset(current->mm, addr); + do { +- pgd_t pgd = READ_ONCE(*pgdp); ++ pgd_t pgd = pgdp_get(pgdp); + + next = pgd_addr_end(addr, end); + if (pgd_none(pgd)) +--- a/mm/hmm.c ++++ b/mm/hmm.c +@@ -491,7 +491,7 @@ static int hmm_vma_walk_pud(pud_t *pudp, + /* Normally we don't want to split the huge page */ + walk->action = ACTION_CONTINUE; + +- pud = READ_ONCE(*pudp); ++ pud = pudp_get(pudp); + if (!pud_present(pud)) { + spin_unlock(ptl); + return hmm_vma_walk_hole(start, end, -1, walk); +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -6691,12 +6691,12 @@ retry: + goto out; + + p4dp = p4d_offset(pgdp, address); +- p4d = READ_ONCE(*p4dp); ++ p4d = p4dp_get(p4dp); + if (p4d_none(p4d) || unlikely(p4d_bad(p4d))) + goto out; + + pudp = pud_offset(p4dp, address); +- pud = READ_ONCE(*pudp); ++ pud = pudp_get(pudp); + if (pud_none(pud)) + goto out; + if (pud_leaf(pud)) { +--- a/mm/mprotect.c ++++ b/mm/mprotect.c +@@ -599,7 +599,7 @@ again: + break; + } + +- pud = READ_ONCE(*pudp); ++ pud = pudp_get(pudp); + if (pud_none(pud)) + continue; + +--- a/mm/sparse-vmemmap.c ++++ b/mm/sparse-vmemmap.c +@@ -439,7 +439,7 @@ int __meminit vmemmap_populate_hugepages + return -ENOMEM; + + pmd = pmd_offset(pud, addr); +- if (pmd_none(READ_ONCE(*pmd))) { ++ if (pmd_none(pmdp_get(pmd))) { + void *p; + + p = vmemmap_alloc_block_buf(PMD_SIZE, node, altmap); +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3783,7 +3783,7 @@ static int walk_pud_range(p4d_t *p4d, un + pud = pud_offset(p4d, start & P4D_MASK); + restart: + for (i = pud_index(start), addr = start; addr != end; i++, addr = next) { +- pud_t val = READ_ONCE(pud[i]); ++ pud_t val = pudp_get(pud + i); + + next = pud_addr_end(addr, end); + diff --git a/queue-6.18/net-correctly-handle-tunneled-traffic-on-ipv6_csum-gso-fallback.patch b/queue-6.18/net-correctly-handle-tunneled-traffic-on-ipv6_csum-gso-fallback.patch new file mode 100644 index 0000000000..7120ad10ca --- /dev/null +++ b/queue-6.18/net-correctly-handle-tunneled-traffic-on-ipv6_csum-gso-fallback.patch @@ -0,0 +1,77 @@ +From stable+bounces-231625-greg=kroah.com@vger.kernel.org Tue Mar 31 18:36:51 2026 +From: Sasha Levin +Date: Tue, 31 Mar 2026 12:30:43 -0400 +Subject: net: correctly handle tunneled traffic on IPV6_CSUM GSO fallback +To: stable@vger.kernel.org +Cc: Willem de Bruijn , Tangxin Xie , Paolo Abeni , Sasha Levin +Message-ID: <20260331163043.2733473-1-sashal@kernel.org> + +From: Willem de Bruijn + +[ Upstream commit c4336a07eb6b2526dc2b62928b5104b41a7f81f5 ] + +NETIF_F_IPV6_CSUM only advertises support for checksum offload of +packets without IPv6 extension headers. Packets with extension +headers must fall back onto software checksumming. Since TSO +depends on checksum offload, those must revert to GSO. + +The below commit introduces that fallback. It always checks +network header length. For tunneled packets, the inner header length +must be checked instead. Extend the check accordingly. + +A special case is tunneled packets without inner IP protocol. Such as +RFC 6951 SCTP in UDP. Those are not standard IPv6 followed by +transport header either, so also must revert to the software GSO path. + +Cc: stable@vger.kernel.org +Fixes: 864e3396976e ("net: gso: Forbid IPv6 TSO with extensions on devices with only IPV6_CSUM") +Reported-by: Tangxin Xie +Closes: https://lore.kernel.org/netdev/0414e7e2-9a1c-4d7c-a99d-b9039cf68f40@yeah.net/ +Suggested-by: Paolo Abeni +Signed-off-by: Willem de Bruijn +Link: https://patch.msgid.link/20260320190148.2409107-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -3755,6 +3755,22 @@ static netdev_features_t dflt_features_c + return vlan_features_check(skb, features); + } + ++static bool skb_gso_has_extension_hdr(const struct sk_buff *skb) ++{ ++ if (!skb->encapsulation) ++ return ((skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6 || ++ (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && ++ vlan_get_protocol(skb) == htons(ETH_P_IPV6))) && ++ skb_transport_header_was_set(skb) && ++ skb_network_header_len(skb) != sizeof(struct ipv6hdr)); ++ else ++ return (!skb_inner_network_header_was_set(skb) || ++ ((skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6 || ++ (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && ++ inner_ip_hdr(skb)->version == 6)) && ++ skb_inner_network_header_len(skb) != sizeof(struct ipv6hdr))); ++} ++ + static netdev_features_t gso_features_check(const struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) +@@ -3807,11 +3823,7 @@ static netdev_features_t gso_features_ch + * so neither does TSO that depends on it. + */ + if (features & NETIF_F_IPV6_CSUM && +- (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6 || +- (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4 && +- vlan_get_protocol(skb) == htons(ETH_P_IPV6))) && +- skb_transport_header_was_set(skb) && +- skb_network_header_len(skb) != sizeof(struct ipv6hdr) && ++ skb_gso_has_extension_hdr(skb) && + !ipv6_has_hopopt_jumbo(skb)) + features &= ~(NETIF_F_IPV6_CSUM | NETIF_F_TSO6 | NETIF_F_GSO_UDP_L4); + diff --git a/queue-6.18/net-mana-fix-use-after-free-in-add_adev-error-path.patch b/queue-6.18/net-mana-fix-use-after-free-in-add_adev-error-path.patch new file mode 100644 index 0000000000..fc5aa05d46 --- /dev/null +++ b/queue-6.18/net-mana-fix-use-after-free-in-add_adev-error-path.patch @@ -0,0 +1,65 @@ +From stable+bounces-231621-greg=kroah.com@vger.kernel.org Tue Mar 31 18:39:51 2026 +From: Sasha Levin +Date: Tue, 31 Mar 2026 12:30:38 -0400 +Subject: net: mana: fix use-after-free in add_adev() error path +To: stable@vger.kernel.org +Cc: Guangshuo Li , Long Li , Jakub Kicinski , Sasha Levin +Message-ID: <20260331163038.2733327-1-sashal@kernel.org> + +From: Guangshuo Li + +[ Upstream commit c4ea7d8907cf72b259bf70bd8c2e791e1c4ff70f ] + +If auxiliary_device_add() fails, add_adev() jumps to add_fail and calls +auxiliary_device_uninit(adev). + +The auxiliary device has its release callback set to adev_release(), +which frees the containing struct mana_adev. Since adev is embedded in +struct mana_adev, the subsequent fall-through to init_fail and access +to adev->id may result in a use-after-free. + +Fix this by saving the allocated auxiliary device id in a local +variable before calling auxiliary_device_add(), and use that saved id +in the cleanup path after auxiliary_device_uninit(). + +Fixes: a69839d4327d ("net: mana: Add support for auxiliary device") +Cc: stable@vger.kernel.org +Reviewed-by: Long Li +Signed-off-by: Guangshuo Li +Link: https://patch.msgid.link/20260323165730.945365-1-lgs201920130244@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/microsoft/mana/mana_en.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/microsoft/mana/mana_en.c ++++ b/drivers/net/ethernet/microsoft/mana/mana_en.c +@@ -3302,6 +3302,7 @@ static int add_adev(struct gdma_dev *gd, + struct auxiliary_device *adev; + struct mana_adev *madev; + int ret; ++ int id; + + madev = kzalloc(sizeof(*madev), GFP_KERNEL); + if (!madev) +@@ -3311,7 +3312,8 @@ static int add_adev(struct gdma_dev *gd, + ret = mana_adev_idx_alloc(); + if (ret < 0) + goto idx_fail; +- adev->id = ret; ++ id = ret; ++ adev->id = id; + + adev->name = name; + adev->dev.parent = gd->gdma_context->dev; +@@ -3337,7 +3339,7 @@ add_fail: + auxiliary_device_uninit(adev); + + init_fail: +- mana_adev_idx_free(adev->id); ++ mana_adev_idx_free(id); + + idx_fail: + kfree(madev); diff --git a/queue-6.18/scsi-target-file-use-kzalloc_flex-for-aio_cmd.patch b/queue-6.18/scsi-target-file-use-kzalloc_flex-for-aio_cmd.patch new file mode 100644 index 0000000000..29ebac7e99 --- /dev/null +++ b/queue-6.18/scsi-target-file-use-kzalloc_flex-for-aio_cmd.patch @@ -0,0 +1,45 @@ +From stable+bounces-231448-greg=kroah.com@vger.kernel.org Tue Mar 31 17:33:20 2026 +From: Sasha Levin +Date: Tue, 31 Mar 2026 11:29:10 -0400 +Subject: scsi: target: file: Use kzalloc_flex for aio_cmd +To: stable@vger.kernel.org +Cc: Thinh Nguyen , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260331152910.2628504-1-sashal@kernel.org> + +From: Thinh Nguyen + +[ Upstream commit 01f784fc9d0ab2a6dac45ee443620e517cb2a19b ] + +The target_core_file doesn't initialize the aio_cmd->iocb for the +ki_write_stream. When a write command fd_execute_rw_aio() is executed, +we may get a bogus ki_write_stream value, causing unintended write +failure status when checking iocb->ki_write_stream > max_write_streams +in the block device. + +Let's just use kzalloc_flex when allocating the aio_cmd and let +ki_write_stream=0 to fix this issue. + +Fixes: 732f25a2895a ("fs: add a write stream field to the kiocb") +Fixes: c27683da6406 ("block: expose write streams for block device nodes") +Cc: stable@vger.kernel.org +Signed-off-by: Thinh Nguyen +Link: https://patch.msgid.link/f1a2f81c62f043e31f80bb92d5f29893400c8ee2.1773450782.git.Thinh.Nguyen@synopsys.com +Signed-off-by: Martin K. Petersen +[ changed kmalloc() to kzalloc() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/target_core_file.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -276,7 +276,7 @@ fd_execute_rw_aio(struct se_cmd *cmd, st + ssize_t len = 0; + int ret = 0, i; + +- aio_cmd = kmalloc(struct_size(aio_cmd, bvecs, sgl_nents), GFP_KERNEL); ++ aio_cmd = kzalloc(struct_size(aio_cmd, bvecs, sgl_nents), GFP_KERNEL); + if (!aio_cmd) + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + diff --git a/queue-6.18/scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch b/queue-6.18/scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch new file mode 100644 index 0000000000..434493af91 --- /dev/null +++ b/queue-6.18/scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch @@ -0,0 +1,147 @@ +From stable+bounces-231439-greg=kroah.com@vger.kernel.org Tue Mar 31 16:49:01 2026 +From: Sasha Levin +Date: Tue, 31 Mar 2026 10:43:24 -0400 +Subject: scsi: target: tcm_loop: Drain commands in target_reset handler +To: stable@vger.kernel.org +Cc: Josef Bacik , "Martin K. Petersen" , Sasha Levin +Message-ID: <20260331144324.2532262-1-sashal@kernel.org> + +From: Josef Bacik + +[ Upstream commit 1333eee56cdf3f0cf67c6ab4114c2c9e0a952026 ] + +tcm_loop_target_reset() violates the SCSI EH contract: it returns SUCCESS +without draining any in-flight commands. The SCSI EH documentation +(scsi_eh.rst) requires that when a reset handler returns SUCCESS the driver +has made lower layers "forget about timed out scmds" and is ready for new +commands. Every other SCSI LLD (virtio_scsi, mpt3sas, ipr, scsi_debug, +mpi3mr) enforces this by draining or completing outstanding commands before +returning SUCCESS. + +Because tcm_loop_target_reset() doesn't drain, the SCSI EH reuses in-flight +scsi_cmnd structures for recovery commands (e.g. TUR) while the target core +still has async completion work queued for the old se_cmd. The memset in +queuecommand zeroes se_lun and lun_ref_active, causing +transport_lun_remove_cmd() to skip its percpu_ref_put(). The leaked LUN +reference prevents transport_clear_lun_ref() from completing, hanging +configfs LUN unlink forever in D-state: + + INFO: task rm:264 blocked for more than 122 seconds. + rm D 0 264 258 0x00004000 + Call Trace: + __schedule+0x3d0/0x8e0 + schedule+0x36/0xf0 + transport_clear_lun_ref+0x78/0x90 [target_core_mod] + core_tpg_remove_lun+0x28/0xb0 [target_core_mod] + target_fabric_port_unlink+0x50/0x60 [target_core_mod] + configfs_unlink+0x156/0x1f0 [configfs] + vfs_unlink+0x109/0x290 + do_unlinkat+0x1d5/0x2d0 + +Fix this by making tcm_loop_target_reset() actually drain commands: + + 1. Issue TMR_LUN_RESET via tcm_loop_issue_tmr() to drain all commands that + the target core knows about (those not yet CMD_T_COMPLETE). + + 2. Use blk_mq_tagset_busy_iter() to iterate all started requests and + flush_work() on each se_cmd — this drains any deferred completion work + for commands that already had CMD_T_COMPLETE set before the TMR (which + the TMR skips via __target_check_io_state()). This is the same pattern + used by mpi3mr, scsi_debug, and libsas to drain outstanding commands + during reset. + +Fixes: e0eb5d38b732 ("scsi: target: tcm_loop: Use block cmd allocator for se_cmds") +Cc: stable@vger.kernel.org +Assisted-by: Claude:claude-opus-4-6 +Signed-off-by: Josef Bacik +Link: https://patch.msgid.link/27011aa34c8f6b1b94d2e3cf5655b6d037f53428.1773706803.git.josef@toxicpanda.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/target/loopback/tcm_loop.c | 52 ++++++++++++++++++++++++++++++++----- + 1 file changed, 46 insertions(+), 6 deletions(-) + +--- a/drivers/target/loopback/tcm_loop.c ++++ b/drivers/target/loopback/tcm_loop.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -268,15 +269,27 @@ static int tcm_loop_device_reset(struct + return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED; + } + ++static bool tcm_loop_flush_work_iter(struct request *rq, void *data) ++{ ++ struct scsi_cmnd *sc = blk_mq_rq_to_pdu(rq); ++ struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc); ++ struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd; ++ ++ flush_work(&se_cmd->work); ++ return true; ++} ++ + static int tcm_loop_target_reset(struct scsi_cmnd *sc) + { + struct tcm_loop_hba *tl_hba; + struct tcm_loop_tpg *tl_tpg; ++ struct Scsi_Host *sh = sc->device->host; ++ int ret; + + /* + * Locate the tcm_loop_hba_t pointer + */ +- tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); ++ tl_hba = *(struct tcm_loop_hba **)shost_priv(sh); + if (!tl_hba) { + pr_err("Unable to perform device reset without active I_T Nexus\n"); + return FAILED; +@@ -285,11 +298,38 @@ static int tcm_loop_target_reset(struct + * Locate the tl_tpg pointer from TargetID in sc->device->id + */ + tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; +- if (tl_tpg) { +- tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE; +- return SUCCESS; +- } +- return FAILED; ++ if (!tl_tpg) ++ return FAILED; ++ ++ /* ++ * Issue a LUN_RESET to drain all commands that the target core ++ * knows about. This handles commands not yet marked CMD_T_COMPLETE. ++ */ ++ ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun, 0, TMR_LUN_RESET); ++ if (ret != TMR_FUNCTION_COMPLETE) ++ return FAILED; ++ ++ /* ++ * Flush any deferred target core completion work that may still be ++ * queued. Commands that already had CMD_T_COMPLETE set before the TMR ++ * are skipped by the TMR drain, but their async completion work ++ * (transport_lun_remove_cmd → percpu_ref_put, release_cmd → scsi_done) ++ * may still be pending in target_completion_wq. ++ * ++ * The SCSI EH will reuse in-flight scsi_cmnd structures for recovery ++ * commands (e.g. TUR) immediately after this handler returns SUCCESS — ++ * if deferred work is still pending, the memset in queuecommand would ++ * zero the se_cmd while the work accesses it, leaking the LUN ++ * percpu_ref and hanging configfs unlink forever. ++ * ++ * Use blk_mq_tagset_busy_iter() to find all started requests and ++ * flush_work() on each — the same pattern used by mpi3mr, scsi_debug, ++ * and other SCSI drivers to drain outstanding commands during reset. ++ */ ++ blk_mq_tagset_busy_iter(&sh->tag_set, tcm_loop_flush_work_iter, NULL); ++ ++ tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE; ++ return SUCCESS; + } + + static const struct scsi_host_template tcm_loop_driver_template = { diff --git a/queue-6.18/series b/queue-6.18/series index dc4e9819ff..f8bce19b62 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -260,3 +260,16 @@ usb-gadget-f_subset-fix-net_device-lifecycle-with-device_move.patch usb-gadget-f_rndis-fix-net_device-lifecycle-with-device_move.patch usb-gadget-f_hid-move-list-and-spinlock-inits-from-bind-to-alloc.patch usb-gadget-f_uac1_legacy-validate-control-request-size.patch +kallsyms-clean-up-namebuf-initialization-in-kallsyms_lookup_buildid.patch +kallsyms-clean-up-modname-and-modbuildid-initialization-in-kallsyms_lookup_buildid.patch +kallsyms-cleanup-code-for-appending-the-module-buildid.patch +kallsyms-prevent-module-removal-when-printing-module-name-and-buildid.patch +wifi-virt_wifi-remove-set_netdev_dev-to-avoid-use-after-free.patch +drm-amd-pm-disable-od_fan_curve-if-temp-or-pwm-range-invalid-for-smu-v13.patch +drm-amd-display-fix-dce-lvds-handling.patch +net-mana-fix-use-after-free-in-add_adev-error-path.patch +net-correctly-handle-tunneled-traffic-on-ipv6_csum-gso-fallback.patch +scsi-target-file-use-kzalloc_flex-for-aio_cmd.patch +scsi-target-tcm_loop-drain-commands-in-target_reset-handler.patch +mm-replace-read_once-with-standard-page-table-accessors.patch +mm-memory-fix-pmd-pud-checks-in-follow_pfnmap_start.patch diff --git a/queue-6.18/wifi-virt_wifi-remove-set_netdev_dev-to-avoid-use-after-free.patch b/queue-6.18/wifi-virt_wifi-remove-set_netdev_dev-to-avoid-use-after-free.patch new file mode 100644 index 0000000000..4bb2357701 --- /dev/null +++ b/queue-6.18/wifi-virt_wifi-remove-set_netdev_dev-to-avoid-use-after-free.patch @@ -0,0 +1,101 @@ +From 789b06f9f39cdc7e895bdab2c034e39c41c8f8d6 Mon Sep 17 00:00:00 2001 +From: Alexander Popov +Date: Wed, 25 Mar 2026 01:46:02 +0300 +Subject: wifi: virt_wifi: remove SET_NETDEV_DEV to avoid use-after-free + +From: Alexander Popov + +commit 789b06f9f39cdc7e895bdab2c034e39c41c8f8d6 upstream. + +Currently we execute `SET_NETDEV_DEV(dev, &priv->lowerdev->dev)` for +the virt_wifi net devices. However, unregistering a virt_wifi device in +netdev_run_todo() can happen together with the device referenced by +SET_NETDEV_DEV(). + +It can result in use-after-free during the ethtool operations performed +on a virt_wifi device that is currently being unregistered. Such a net +device can have the `dev.parent` field pointing to the freed memory, +but ethnl_ops_begin() calls `pm_runtime_get_sync(dev->dev.parent)`. + +Let's remove SET_NETDEV_DEV for virt_wifi to avoid bugs like this: + + ================================================================== + BUG: KASAN: slab-use-after-free in __pm_runtime_resume+0xe2/0xf0 + Read of size 2 at addr ffff88810cfc46f8 by task pm/606 + + Call Trace: + + dump_stack_lvl+0x4d/0x70 + print_report+0x170/0x4f3 + ? __pfx__raw_spin_lock_irqsave+0x10/0x10 + kasan_report+0xda/0x110 + ? __pm_runtime_resume+0xe2/0xf0 + ? __pm_runtime_resume+0xe2/0xf0 + __pm_runtime_resume+0xe2/0xf0 + ethnl_ops_begin+0x49/0x270 + ethnl_set_features+0x23c/0xab0 + ? __pfx_ethnl_set_features+0x10/0x10 + ? kvm_sched_clock_read+0x11/0x20 + ? local_clock_noinstr+0xf/0xf0 + ? local_clock+0x10/0x30 + ? kasan_save_track+0x25/0x60 + ? __kasan_kmalloc+0x7f/0x90 + ? genl_family_rcv_msg_attrs_parse.isra.0+0x150/0x2c0 + genl_family_rcv_msg_doit+0x1e7/0x2c0 + ? __pfx_genl_family_rcv_msg_doit+0x10/0x10 + ? __pfx_cred_has_capability.isra.0+0x10/0x10 + ? stack_trace_save+0x8e/0xc0 + genl_rcv_msg+0x411/0x660 + ? __pfx_genl_rcv_msg+0x10/0x10 + ? __pfx_ethnl_set_features+0x10/0x10 + netlink_rcv_skb+0x121/0x380 + ? __pfx_genl_rcv_msg+0x10/0x10 + ? __pfx_netlink_rcv_skb+0x10/0x10 + ? __pfx_down_read+0x10/0x10 + genl_rcv+0x23/0x30 + netlink_unicast+0x60f/0x830 + ? __pfx_netlink_unicast+0x10/0x10 + ? __pfx___alloc_skb+0x10/0x10 + netlink_sendmsg+0x6ea/0xbc0 + ? __pfx_netlink_sendmsg+0x10/0x10 + ? __futex_queue+0x10b/0x1f0 + ____sys_sendmsg+0x7a2/0x950 + ? copy_msghdr_from_user+0x26b/0x430 + ? __pfx_____sys_sendmsg+0x10/0x10 + ? __pfx_copy_msghdr_from_user+0x10/0x10 + ___sys_sendmsg+0xf8/0x180 + ? __pfx____sys_sendmsg+0x10/0x10 + ? __pfx_futex_wait+0x10/0x10 + ? fdget+0x2e4/0x4a0 + __sys_sendmsg+0x11f/0x1c0 + ? __pfx___sys_sendmsg+0x10/0x10 + do_syscall_64+0xe2/0x570 + ? exc_page_fault+0x66/0xb0 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + + +This fix may be combined with another one in the ethtool subsystem: +https://lore.kernel.org/all/20260322075917.254874-1-alex.popov@linux.com/T/#u + +Fixes: d43c65b05b848e0b ("ethtool: runtime-resume netdev parent in ethnl_ops_begin") +Cc: stable@vger.kernel.org +Signed-off-by: Alexander Popov +Acked-by: Greg Kroah-Hartman +Reviewed-by: Breno Leitao +Link: https://patch.msgid.link/20260324224607.374327-1-alex.popov@linux.com +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/virtual/virt_wifi.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/virtual/virt_wifi.c ++++ b/drivers/net/wireless/virtual/virt_wifi.c +@@ -557,7 +557,6 @@ static int virt_wifi_newlink(struct net_ + eth_hw_addr_inherit(dev, priv->lowerdev); + netif_stacked_transfer_operstate(priv->lowerdev, dev); + +- SET_NETDEV_DEV(dev, &priv->lowerdev->dev); + dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL); + + if (!dev->ieee80211_ptr) {