From 3e983429a5c301a650f93236396e262ab8d5eaa8 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:10 -0500 Subject: [PATCH 01/25] coredump: Only sort VMAs when core_sort_vma sysctl is set jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Kees Cook commit 39ec9eaaa165d297d008d1fa385748430bd18e4d The sorting of VMAs by size in commit 7d442a33bfe8 ("binfmt_elf: Dump smaller VMAs first in ELF cores") breaks elfutils[1]. Instead, sort based on the setting of the new sysctl, core_sort_vma, which defaults to 0, no sorting. Reported-by: Michael Stapelberg Closes: https://lore.kernel.org/all/20250218085407.61126-1-michael@stapelberg.de/ [1] Fixes: 7d442a33bfe8 ("binfmt_elf: Dump smaller VMAs first in ELF cores") Signed-off-by: Kees Cook (cherry picked from commit 39ec9eaaa165d297d008d1fa385748430bd18e4d) Signed-off-by: Jonathan Maple --- Documentation/admin-guide/sysctl/kernel.rst | 11 +++++++++++ fs/coredump.c | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst index b1d9bc9c1df35..2234828413086 100644 --- a/Documentation/admin-guide/sysctl/kernel.rst +++ b/Documentation/admin-guide/sysctl/kernel.rst @@ -212,6 +212,17 @@ pid>/``). This value defaults to 0. +core_sort_vma +============= + +The default coredump writes VMAs in address order. By setting +``core_sort_vma`` to 1, VMAs will be written from smallest size +to largest size. This is known to break at least elfutils, but +can be handy when dealing with very large (and truncated) +coredumps where the more useful debugging details are included +in the smaller VMAs. + + core_uses_pid ============= diff --git a/fs/coredump.c b/fs/coredump.c index 45737b43dda5c..2b8c36c9660c5 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -63,6 +63,7 @@ static void free_vma_snapshot(struct coredump_params *cprm); static int core_uses_pid; static unsigned int core_pipe_limit; +static unsigned int core_sort_vma; static char core_pattern[CORENAME_MAX_SIZE] = "core"; static int core_name_size = CORENAME_MAX_SIZE; unsigned int core_file_note_size_limit = CORE_FILE_NOTE_SIZE_DEFAULT; @@ -1025,6 +1026,15 @@ static struct ctl_table coredump_sysctls[] = { .extra1 = (unsigned int *)&core_file_note_size_min, .extra2 = (unsigned int *)&core_file_note_size_max, }, + { + .procname = "core_sort_vma", + .data = &core_sort_vma, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_douintvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, }; static int __init init_fs_coredump_sysctls(void) @@ -1255,8 +1265,9 @@ static bool dump_vma_snapshot(struct coredump_params *cprm) cprm->vma_data_size += m->dump_size; } - sort(cprm->vma_meta, cprm->vma_count, sizeof(*cprm->vma_meta), - cmp_vma_size, NULL); + if (core_sort_vma) + sort(cprm->vma_meta, cprm->vma_count, sizeof(*cprm->vma_meta), + cmp_vma_size, NULL); return true; } From d3b00f9eee3512f3f1f343ea4de539752cf2ea09 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:10 -0500 Subject: [PATCH 02/25] smb: client: Fix NULL pointer dereference in cifs_debug_dirs_proc_show() jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Wang Zhaolong commit 6976c7a69dafbb34a0d4814e2def9d3d7114836d Reading /proc/fs/cifs/open_dirs may hit a NULL dereference when tcon->cfids is NULL. Add NULL check before accessing cfids to prevent the crash. Reproduction: - Mount CIFS share - cat /proc/fs/cifs/open_dirs Fixes: 844e5c0eb176 ("smb3 client: add way to show directory leases for improved debugging") Signed-off-by: Wang Zhaolong Signed-off-by: Steve French (cherry picked from commit 6976c7a69dafbb34a0d4814e2def9d3d7114836d) Signed-off-by: Jonathan Maple --- fs/smb/client/cifs_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 80d6a51b8c11d..9296b0b1534ff 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -304,6 +304,8 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v) list_for_each(tmp1, &ses->tcon_list) { tcon = list_entry(tmp1, struct cifs_tcon, tcon_list); cfids = tcon->cfids; + if (!cfids) + continue; spin_lock(&cfids->cfid_list_lock); /* check lock ordering */ seq_printf(m, "Num entries: %d\n", cfids->num_entries); list_for_each_entry(cfid, &cfids->entries, entry) { @@ -319,8 +321,6 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v) seq_printf(m, "\n"); } spin_unlock(&cfids->cfid_list_lock); - - } } } From 0b9574617fcab1e12740252a9641c7c3d1109dc6 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:10 -0500 Subject: [PATCH 03/25] smb: client: add new tracepoint to trace lease break notification jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Bharath SM commit 72595cb6da1841b355644fe8882d60e725205c32 Add smb3_lease_break_enter to trace lease break notifications, recording lease state, flags, epoch, and lease key. Align smb3_lease_not_found to use the same payload and print format. Signed-off-by: Bharath SM Acked-by: Paulo Alcantara (Red Hat) Signed-off-by: Steve French (cherry picked from commit 72595cb6da1841b355644fe8882d60e725205c32) Signed-off-by: Jonathan Maple --- fs/smb/client/smb2misc.c | 19 +++++++++++---- fs/smb/client/smb2pdu.c | 4 ++-- fs/smb/client/trace.h | 52 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c index cddf273c14aed..89d933b4a8bc2 100644 --- a/fs/smb/client/smb2misc.c +++ b/fs/smb/client/smb2misc.c @@ -614,6 +614,15 @@ smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server) struct cifs_tcon *tcon; struct cifs_pending_open *open; + /* Trace receipt of lease break request from server */ + trace_smb3_lease_break_enter(le32_to_cpu(rsp->CurrentLeaseState), + le32_to_cpu(rsp->Flags), + le16_to_cpu(rsp->Epoch), + le32_to_cpu(rsp->hdr.Id.SyncId.TreeId), + le64_to_cpu(rsp->hdr.SessionId), + *((u64 *)rsp->LeaseKey), + *((u64 *)&rsp->LeaseKey[8])); + cifs_dbg(FYI, "Checking for lease break\n"); /* If server is a channel, select the primary channel */ @@ -660,10 +669,12 @@ smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server) spin_unlock(&cifs_tcp_ses_lock); cifs_dbg(FYI, "Can not process lease break - no lease matched\n"); trace_smb3_lease_not_found(le32_to_cpu(rsp->CurrentLeaseState), - le32_to_cpu(rsp->hdr.Id.SyncId.TreeId), - le64_to_cpu(rsp->hdr.SessionId), - *((u64 *)rsp->LeaseKey), - *((u64 *)&rsp->LeaseKey[8])); + le32_to_cpu(rsp->Flags), + le16_to_cpu(rsp->Epoch), + le32_to_cpu(rsp->hdr.Id.SyncId.TreeId), + le64_to_cpu(rsp->hdr.SessionId), + *((u64 *)rsp->LeaseKey), + *((u64 *)&rsp->LeaseKey[8])); return false; } diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 2df93a75e3b8f..c3b9d3f6210ff 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -6192,11 +6192,11 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, please_key_high = (__u64 *)(lease_key+8); if (rc) { cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE); - trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid, + trace_smb3_lease_ack_err(le32_to_cpu(lease_state), tcon->tid, ses->Suid, *please_key_low, *please_key_high, rc); cifs_dbg(FYI, "Send error in Lease Break = %d\n", rc); } else - trace_smb3_lease_done(le32_to_cpu(lease_state), tcon->tid, + trace_smb3_lease_ack_done(le32_to_cpu(lease_state), tcon->tid, ses->Suid, *please_key_low, *please_key_high); return rc; diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h index a8c6f11699a3b..fd650e2afc762 100644 --- a/fs/smb/client/trace.h +++ b/fs/smb/client/trace.h @@ -1168,8 +1168,54 @@ DEFINE_EVENT(smb3_lease_done_class, smb3_##name, \ __u64 lease_key_high), \ TP_ARGS(lease_state, tid, sesid, lease_key_low, lease_key_high)) -DEFINE_SMB3_LEASE_DONE_EVENT(lease_done); -DEFINE_SMB3_LEASE_DONE_EVENT(lease_not_found); +DEFINE_SMB3_LEASE_DONE_EVENT(lease_ack_done); +/* Tracepoint when a lease break request is received/entered (includes epoch and flags) */ +DECLARE_EVENT_CLASS(smb3_lease_enter_class, + TP_PROTO(__u32 lease_state, + __u32 flags, + __u16 epoch, + __u32 tid, + __u64 sesid, + __u64 lease_key_low, + __u64 lease_key_high), + TP_ARGS(lease_state, flags, epoch, tid, sesid, lease_key_low, lease_key_high), + TP_STRUCT__entry( + __field(__u32, lease_state) + __field(__u32, flags) + __field(__u16, epoch) + __field(__u32, tid) + __field(__u64, sesid) + __field(__u64, lease_key_low) + __field(__u64, lease_key_high) + ), + TP_fast_assign( + __entry->lease_state = lease_state; + __entry->flags = flags; + __entry->epoch = epoch; + __entry->tid = tid; + __entry->sesid = sesid; + __entry->lease_key_low = lease_key_low; + __entry->lease_key_high = lease_key_high; + ), + TP_printk("sid=0x%llx tid=0x%x lease_key=0x%llx%llx lease_state=0x%x flags=0x%x epoch=%u", + __entry->sesid, __entry->tid, __entry->lease_key_high, + __entry->lease_key_low, __entry->lease_state, __entry->flags, __entry->epoch) +) + +#define DEFINE_SMB3_LEASE_ENTER_EVENT(name) \ +DEFINE_EVENT(smb3_lease_enter_class, smb3_##name, \ + TP_PROTO(__u32 lease_state, \ + __u32 flags, \ + __u16 epoch, \ + __u32 tid, \ + __u64 sesid, \ + __u64 lease_key_low, \ + __u64 lease_key_high), \ + TP_ARGS(lease_state, flags, epoch, tid, sesid, lease_key_low, lease_key_high)) + +DEFINE_SMB3_LEASE_ENTER_EVENT(lease_break_enter); +/* Lease not found: reuse lease_enter payload (includes epoch and flags) */ +DEFINE_SMB3_LEASE_ENTER_EVENT(lease_not_found); DECLARE_EVENT_CLASS(smb3_lease_err_class, TP_PROTO(__u32 lease_state, @@ -1210,7 +1256,7 @@ DEFINE_EVENT(smb3_lease_err_class, smb3_##name, \ int rc), \ TP_ARGS(lease_state, tid, sesid, lease_key_low, lease_key_high, rc)) -DEFINE_SMB3_LEASE_ERR_EVENT(lease_err); +DEFINE_SMB3_LEASE_ERR_EVENT(lease_ack_err); DECLARE_EVENT_CLASS(smb3_connect_class, TP_PROTO(char *hostname, From 363947e39cfca1b9074642189cad598277ee9e67 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:10 -0500 Subject: [PATCH 04/25] smb: client: show negotiated cipher in DebugData jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Bharath SM commit 91be128b496c0de60a7dceb70d34935a29d38bbd Print the negotiated encryption cipher type in DebugData Signed-off-by: Bharath SM Acked-by: Paulo Alcantara (Red Hat) Signed-off-by: Steve French (cherry picked from commit 91be128b496c0de60a7dceb70d34935a29d38bbd) Signed-off-by: Jonathan Maple --- fs/smb/client/cifs_debug.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 9296b0b1534ff..e9ea1528394a2 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -347,6 +347,22 @@ static __always_inline const char *compression_alg_str(__le16 alg) } } +static __always_inline const char *cipher_alg_str(__le16 cipher) +{ + switch (cipher) { + case SMB2_ENCRYPTION_AES128_CCM: + return "AES128-CCM"; + case SMB2_ENCRYPTION_AES128_GCM: + return "AES128-GCM"; + case SMB2_ENCRYPTION_AES256_CCM: + return "AES256-CCM"; + case SMB2_ENCRYPTION_AES256_GCM: + return "AES256-GCM"; + default: + return "UNKNOWN"; + } +} + static int cifs_debug_data_proc_show(struct seq_file *m, void *v) { struct mid_q_entry *mid_entry; @@ -541,6 +557,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) else seq_puts(m, "disabled (not supported by this server)"); + /* Show negotiated encryption cipher, even if not required */ + seq_puts(m, "\nEncryption: "); + if (server->cipher_type) + seq_printf(m, "Negotiated cipher (%s)", cipher_alg_str(server->cipher_type)); + seq_printf(m, "\n\n\tSessions: "); i = 0; list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { @@ -578,12 +599,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v) /* dump session id helpful for use with network trace */ seq_printf(m, " SessionId: 0x%llx", ses->Suid); - if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) { + if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) seq_puts(m, " encrypted"); - /* can help in debugging to show encryption type */ - if (server->cipher_type == SMB2_ENCRYPTION_AES256_GCM) - seq_puts(m, "(gcm256)"); - } if (ses->sign) seq_puts(m, " signed"); From 48afafdf18935302f25f998ea41044cf07f5fbe4 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:11 -0500 Subject: [PATCH 05/25] smb: client: show lease state as R/H/W (or NONE) in open_files jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Bharath SM commit ac3ad9845b9faf9cf29a736eaac00703bc821ac1 Print the lease/oplock caching state for each open file as a compact string of letters: R (read), H (handle), W (write). Signed-off-by: Bharath SM Signed-off-by: Steve French (cherry picked from commit ac3ad9845b9faf9cf29a736eaac00703bc821ac1) Signed-off-by: Jonathan Maple --- fs/smb/client/cifs_debug.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index e9ea1528394a2..8df15104e6ad9 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -239,14 +239,18 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v) struct cifs_ses *ses; struct cifs_tcon *tcon; struct cifsFileInfo *cfile; + struct inode *inode; + struct cifsInodeInfo *cinode; + char lease[4]; + int n; seq_puts(m, "# Version:1\n"); seq_puts(m, "# Format:\n"); seq_puts(m, "# "); #ifdef CONFIG_CIFS_DEBUG2 - seq_printf(m, " \n"); + seq_puts(m, " \n"); #else - seq_printf(m, " \n"); + seq_puts(m, " \n"); #endif /* CIFS_DEBUG2 */ spin_lock(&cifs_tcp_ses_lock); list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { @@ -266,11 +270,30 @@ static int cifs_debug_files_proc_show(struct seq_file *m, void *v) cfile->pid, from_kuid(&init_user_ns, cfile->uid), cfile->dentry); + + /* Append lease/oplock caching state as RHW letters */ + inode = d_inode(cfile->dentry); + n = 0; + if (inode) { + cinode = CIFS_I(inode); + if (CIFS_CACHE_READ(cinode)) + lease[n++] = 'R'; + if (CIFS_CACHE_HANDLE(cinode)) + lease[n++] = 'H'; + if (CIFS_CACHE_WRITE(cinode)) + lease[n++] = 'W'; + } + lease[n] = '\0'; + seq_puts(m, " "); + if (n) + seq_printf(m, "%s", lease); + else + seq_puts(m, "NONE"); + #ifdef CONFIG_CIFS_DEBUG2 - seq_printf(m, " %llu\n", cfile->fid.mid); -#else + seq_printf(m, " %llu", cfile->fid.mid); +#endif /* CONFIG_CIFS_DEBUG2 */ seq_printf(m, "\n"); -#endif /* CIFS_DEBUG2 */ } spin_unlock(&tcon->open_file_lock); } From bbd8fcf3e9f69b9f6b79591e9f0f148131009cfc Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:11 -0500 Subject: [PATCH 06/25] smb: client: add drop_dir_cache module parameter to invalidate cached dirents jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Bharath SM commit dde6667fa3c8f52ec4b8afd487749e47d032d833 Add write-only /sys/module/cifs/parameters/drop_dir_cache. Writing a non-zero value iterates all tcons and calls invalidate_all_cached_dirs() to drop cached directory entries. This is useful to force a dirent cache drop across mounts for debugging and testing purpose. Signed-off-by: Bharath SM Signed-off-by: Steve French (cherry picked from commit dde6667fa3c8f52ec4b8afd487749e47d032d833) Signed-off-by: Jonathan Maple --- fs/smb/client/cifsfs.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index 37ba5b4880e09..f3d988546cd84 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -121,6 +121,44 @@ unsigned int dir_cache_timeout = 30; module_param(dir_cache_timeout, uint, 0644); MODULE_PARM_DESC(dir_cache_timeout, "Number of seconds to cache directory contents for which we have a lease. Default: 30 " "Range: 1 to 65000 seconds, 0 to disable caching dir contents"); + +/* + * Write-only module parameter to drop all cached directory entries across + * all CIFS mounts. Echo a non-zero value to trigger. + */ +static void cifs_drop_all_dir_caches(void) +{ + struct TCP_Server_Info *server; + struct cifs_ses *ses; + struct cifs_tcon *tcon; + + spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + if (cifs_ses_exiting(ses)) + continue; + list_for_each_entry(tcon, &ses->tcon_list, tcon_list) + invalidate_all_cached_dirs(tcon); + } + } + spin_unlock(&cifs_tcp_ses_lock); +} + +static int cifs_param_set_drop_dir_cache(const char *val, const struct kernel_param *kp) +{ + bool bv; + int rc = kstrtobool(val, &bv); + + if (rc) + return rc; + if (bv) + cifs_drop_all_dir_caches(); + return 0; +} + +module_param_call(drop_dir_cache, cifs_param_set_drop_dir_cache, NULL, NULL, 0200); +MODULE_PARM_DESC(drop_dir_cache, "Write 1 to drop all cached directory entries across all CIFS mounts"); + #ifdef CONFIG_CIFS_STATS2 unsigned int slow_rsp_threshold = 1; module_param(slow_rsp_threshold, uint, 0644); From d93acfe1a79a554d2869aa70dbc4d98fa0a0020a Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:11 -0500 Subject: [PATCH 07/25] smb: client: account smb directory cache usage and per-tcon totals jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Bharath SM commit 63eb8bd6c81d84a23fdc18fffd604e3ea38bb96c Add lightweight accounting for directory lease cache usage to aid debugging and limiting cache size in future. Track per-directory entry/byte counts and maintain per-tcon aggregates. Also expose the totals in /proc/fs/cifs/open_dirs. Signed-off-by: Bharath SM Signed-off-by: Steve French (cherry picked from commit 63eb8bd6c81d84a23fdc18fffd604e3ea38bb96c) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 18 +++++++++++++++++ fs/smb/client/cached_dir.h | 9 +++++++++ fs/smb/client/cifs_debug.c | 8 +++++++- fs/smb/client/cifsfs.c | 2 ++ fs/smb/client/readdir.c | 40 +++++++++++++++++++++++++------------- 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 29dfdebb2fa08..c3efd42661e43 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -696,6 +696,21 @@ static void free_cached_dir(struct cached_fid *cfid) kfree(dirent); } + /* adjust tcon-level counters and reset per-dir accounting */ + if (cfid->cfids) { + if (cfid->dirents.entries_count) + atomic_long_sub((long)cfid->dirents.entries_count, + &cfid->cfids->total_dirents_entries); + if (cfid->dirents.bytes_used) { + atomic64_sub((long long)cfid->dirents.bytes_used, + &cfid->cfids->total_dirents_bytes); + atomic64_sub((long long)cfid->dirents.bytes_used, + &cifs_dircache_bytes_used); + } + } + cfid->dirents.entries_count = 0; + cfid->dirents.bytes_used = 0; + kfree(cfid->path); cfid->path = NULL; kfree(cfid); @@ -791,6 +806,9 @@ struct cached_fids *init_cached_dirs(void) queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout * HZ); + atomic_long_set(&cfids->total_dirents_entries, 0); + atomic64_set(&cfids->total_dirents_bytes, 0); + return cfids; } diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index 46b5a2fdf15b5..c98f029433115 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -27,6 +27,9 @@ struct cached_dirents { struct mutex de_mutex; loff_t pos; /* Expected ctx->pos */ struct list_head entries; + /* accounting for cached entries in this directory */ + unsigned long entries_count; + unsigned long bytes_used; }; struct cached_fid { @@ -62,8 +65,14 @@ struct cached_fids { struct list_head dying; struct work_struct invalidation_work; struct delayed_work laundromat_work; + /* aggregate accounting for all cached dirents under this tcon */ + atomic_long_t total_dirents_entries; + atomic64_t total_dirents_bytes; }; +/* Module-wide directory cache accounting (defined in cifsfs.c) */ +extern atomic64_t cifs_dircache_bytes_used; /* bytes across all mounts */ + extern struct cached_fids *init_cached_dirs(void); extern void free_cached_dirs(struct cached_fids *cfids); extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c index 8df15104e6ad9..5a89605af1f1e 100644 --- a/fs/smb/client/cifs_debug.c +++ b/fs/smb/client/cifs_debug.c @@ -330,7 +330,10 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v) if (!cfids) continue; spin_lock(&cfids->cfid_list_lock); /* check lock ordering */ - seq_printf(m, "Num entries: %d\n", cfids->num_entries); + seq_printf(m, "Num entries: %d, cached_dirents: %lu entries, %llu bytes\n", + cfids->num_entries, + (unsigned long)atomic_long_read(&cfids->total_dirents_entries), + (unsigned long long)atomic64_read(&cfids->total_dirents_bytes)); list_for_each_entry(cfid, &cfids->entries, entry) { seq_printf(m, "0x%x 0x%llx 0x%llx %s", tcon->tid, @@ -341,6 +344,9 @@ static int cifs_debug_dirs_proc_show(struct seq_file *m, void *v) seq_printf(m, "\tvalid file info"); if (cfid->dirents.is_valid) seq_printf(m, ", valid dirents"); + if (!list_empty(&cfid->dirents.entries)) + seq_printf(m, ", dirents: %lu entries, %lu bytes", + cfid->dirents.entries_count, cfid->dirents.bytes_used); seq_printf(m, "\n"); } spin_unlock(&cfids->cfid_list_lock); diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index f3d988546cd84..d3409baf358e5 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -121,6 +121,8 @@ unsigned int dir_cache_timeout = 30; module_param(dir_cache_timeout, uint, 0644); MODULE_PARM_DESC(dir_cache_timeout, "Number of seconds to cache directory contents for which we have a lease. Default: 30 " "Range: 1 to 65000 seconds, 0 to disable caching dir contents"); +/* Module-wide total cached dirents (in bytes) across all tcons */ +atomic64_t cifs_dircache_bytes_used = ATOMIC64_INIT(0); /* * Write-only module parameter to drop all cached directory entries across diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index 7bf3214117a91..7e194d2352517 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -873,39 +873,42 @@ static void finished_cached_dirents_count(struct cached_dirents *cde, cde->is_valid = 1; } -static void add_cached_dirent(struct cached_dirents *cde, - struct dir_context *ctx, - const char *name, int namelen, - struct cifs_fattr *fattr, - struct file *file) +static bool add_cached_dirent(struct cached_dirents *cde, + struct dir_context *ctx, const char *name, + int namelen, struct cifs_fattr *fattr, + struct file *file) { struct cached_dirent *de; if (cde->file != file) - return; + return false; if (cde->is_valid || cde->is_failed) - return; + return false; if (ctx->pos != cde->pos) { cde->is_failed = 1; - return; + return false; } de = kzalloc(sizeof(*de), GFP_ATOMIC); if (de == NULL) { cde->is_failed = 1; - return; + return false; } de->namelen = namelen; de->name = kstrndup(name, namelen, GFP_ATOMIC); if (de->name == NULL) { kfree(de); cde->is_failed = 1; - return; + return false; } de->pos = ctx->pos; memcpy(&de->fattr, fattr, sizeof(struct cifs_fattr)); list_add_tail(&de->entry, &cde->entries); + /* update accounting */ + cde->entries_count++; + cde->bytes_used += sizeof(*de) + (size_t)namelen + 1; + return true; } static bool cifs_dir_emit(struct dir_context *ctx, @@ -914,7 +917,8 @@ static bool cifs_dir_emit(struct dir_context *ctx, struct cached_fid *cfid, struct file *file) { - bool rc; + size_t delta_bytes = 0; + bool rc, added = false; ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); rc = dir_emit(ctx, name, namelen, ino, fattr->cf_dtype); @@ -922,10 +926,20 @@ static bool cifs_dir_emit(struct dir_context *ctx, return rc; if (cfid) { + /* Cost of this entry */ + delta_bytes = sizeof(struct cached_dirent) + (size_t)namelen + 1; + mutex_lock(&cfid->dirents.de_mutex); - add_cached_dirent(&cfid->dirents, ctx, name, namelen, - fattr, file); + added = add_cached_dirent(&cfid->dirents, ctx, name, namelen, + fattr, file); mutex_unlock(&cfid->dirents.de_mutex); + + if (added) { + /* per-tcon then global for consistency with free path */ + atomic64_add((long long)delta_bytes, &cfid->cfids->total_dirents_bytes); + atomic_long_inc(&cfid->cfids->total_dirents_entries); + atomic64_add((long long)delta_bytes, &cifs_dircache_bytes_used); + } } return rc; From 5acf366dcb0d92908cc03062accc9fae42b64101 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:11 -0500 Subject: [PATCH 08/25] smb: client: ensure open_cached_dir_by_dentry() only returns valid cfid jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Steve French commit a365f2c049b3846640234bc25e4f8c46abea6c98 open_cached_dir_by_dentry() was exposing an invalid cached directory to callers. The validity check outside the function was exclusively based on cfid->time. Add validity check before returning success and introduce is_valid_cached_dir() helper for consistent checks across the code. Signed-off-by: Henrique Carvalho Reviwed-by: Enzo Matsumiya Signed-off-by: Steve French (cherry picked from commit a365f2c049b3846640234bc25e4f8c46abea6c98) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 9 +++++---- fs/smb/client/cached_dir.h | 6 ++++++ fs/smb/client/dir.c | 2 +- fs/smb/client/inode.c | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index c3efd42661e43..ce6b5f6fc42a3 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -36,9 +36,8 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids, * fully cached or it may be in the process of * being deleted due to a lease break. */ - if (!cfid->time || !cfid->has_lease) { + if (!is_valid_cached_dir(cfid)) return NULL; - } kref_get(&cfid->refcount); return cfid; } @@ -193,7 +192,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, * Otherwise, it is either a new entry or laundromat worker removed it * from @cfids->entries. Caller will put last reference if the latter. */ - if (cfid->has_lease && cfid->time) { + if (is_valid_cached_dir(cfid)) { cfid->last_access_time = jiffies; spin_unlock(&cfids->cfid_list_lock); *ret_cfid = cfid; @@ -232,7 +231,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, list_for_each_entry(parent_cfid, &cfids->entries, entry) { if (parent_cfid->dentry == dentry->d_parent) { cifs_dbg(FYI, "found a parent cached file handle\n"); - if (parent_cfid->has_lease && parent_cfid->time) { + if (is_valid_cached_dir(parent_cfid)) { lease_flags |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE; memcpy(pfid->parent_lease_key, @@ -419,6 +418,8 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, spin_lock(&cfids->cfid_list_lock); list_for_each_entry(cfid, &cfids->entries, entry) { if (dentry && cfid->dentry == dentry) { + if (!is_valid_cached_dir(cfid)) + break; cifs_dbg(FYI, "found a cached file handle by dentry\n"); kref_get(&cfid->refcount); *ret_cfid = cfid; diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index c98f029433115..9210caf801645 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -73,6 +73,12 @@ struct cached_fids { /* Module-wide directory cache accounting (defined in cifsfs.c) */ extern atomic64_t cifs_dircache_bytes_used; /* bytes across all mounts */ +static inline bool +is_valid_cached_dir(struct cached_fid *cfid) +{ + return cfid->time && cfid->has_lease; +} + extern struct cached_fids *init_cached_dirs(void); extern void free_cached_dirs(struct cached_fids *cfids); extern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index bc890c9d366cd..1179224abfb4e 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -322,7 +322,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned list_for_each_entry(parent_cfid, &tcon->cfids->entries, entry) { if (parent_cfid->dentry == direntry->d_parent) { cifs_dbg(FYI, "found a parent cached file handle\n"); - if (parent_cfid->has_lease && parent_cfid->time) { + if (is_valid_cached_dir(parent_cfid)) { lease_flags |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET_LE; memcpy(fid->parent_lease_key, diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 161d32a1a5651..ceac71cf86a3e 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -2701,7 +2701,7 @@ cifs_dentry_needs_reval(struct dentry *dentry) return true; if (!open_cached_dir_by_dentry(tcon, dentry->d_parent, &cfid)) { - if (cfid->time && cifs_i->time > cfid->time) { + if (cifs_i->time > cfid->time) { close_cached_dir(cfid); return false; } From ff1b206ed815bfcbcbafbd8a00118a66db39b3e7 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:12 -0500 Subject: [PATCH 09/25] smb: client: update cfid->last_access_time in open_cached_dir_by_dentry() jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 5676398315b73f21d6a4e2d36606ce94e8afc79e open_cached_dir_by_dentry() was missing an update of cfid->last_access_time to jiffies, similar to what open_cached_dir() has. Add it to the function. Signed-off-by: Henrique Carvalho Reviewed-by: Enzo Matsumiya Signed-off-by: Steve French (cherry picked from commit 5676398315b73f21d6a4e2d36606ce94e8afc79e) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index ce6b5f6fc42a3..9e261d372d656 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -423,6 +423,7 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, cifs_dbg(FYI, "found a cached file handle by dentry\n"); kref_get(&cfid->refcount); *ret_cfid = cfid; + cfid->last_access_time = jiffies; spin_unlock(&cfids->cfid_list_lock); return 0; } From fd294e008dde69e240872e3d33eb3fb5e577c6ee Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:12 -0500 Subject: [PATCH 10/25] smb: client: remove unused fid_lock jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 17ef15fa80cf3b60b6f82ea1d88fa499d5495994 The fid_lock in struct cached_fid does not currently provide any real synchronization. Previously, it had the intention to prevent a double release of the dentry, but every change to cfid->dentry is already protected either by cfid_list_lock (while the entry is in the list) or happens after the cfid has been removed (so no other thread should find it). Since there is no scenario in which fid_lock prevents any race, it is vestigial and can be removed along with its associated spin_lock()/spin_unlock() calls. Signed-off-by: Henrique Carvalho Reviewed-by: Enzo Matsumiya Signed-off-by: Steve French (cherry picked from commit 17ef15fa80cf3b60b6f82ea1d88fa499d5495994) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 17 +++-------------- fs/smb/client/cached_dir.h | 1 - 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 9e261d372d656..82e59eb8c0894 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -523,10 +523,9 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) spin_unlock(&cifs_sb->tlink_tree_lock); goto done; } - spin_lock(&cfid->fid_lock); + tmp_list->dentry = cfid->dentry; cfid->dentry = NULL; - spin_unlock(&cfid->fid_lock); list_add_tail(&tmp_list->entry, &entry); } @@ -609,14 +608,9 @@ static void cached_dir_put_work(struct work_struct *work) { struct cached_fid *cfid = container_of(work, struct cached_fid, put_work); - struct dentry *dentry; - - spin_lock(&cfid->fid_lock); - dentry = cfid->dentry; + dput(cfid->dentry); cfid->dentry = NULL; - spin_unlock(&cfid->fid_lock); - dput(dentry); queue_work(serverclose_wq, &cfid->close_work); } @@ -674,7 +668,6 @@ static struct cached_fid *init_cached_dir(const char *path) INIT_LIST_HEAD(&cfid->entry); INIT_LIST_HEAD(&cfid->dirents.entries); mutex_init(&cfid->dirents.de_mutex); - spin_lock_init(&cfid->fid_lock); kref_init(&cfid->refcount); return cfid; } @@ -741,7 +734,6 @@ static void cfids_laundromat_worker(struct work_struct *work) { struct cached_fids *cfids; struct cached_fid *cfid, *q; - struct dentry *dentry; LIST_HEAD(entry); cfids = container_of(work, struct cached_fids, laundromat_work.work); @@ -768,12 +760,9 @@ static void cfids_laundromat_worker(struct work_struct *work) list_for_each_entry_safe(cfid, q, &entry, entry) { list_del(&cfid->entry); - spin_lock(&cfid->fid_lock); - dentry = cfid->dentry; + dput(cfid->dentry); cfid->dentry = NULL; - spin_unlock(&cfid->fid_lock); - dput(dentry); if (cfid->is_open) { spin_lock(&cifs_tcp_ses_lock); ++cfid->tcon->tc_count; diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index 9210caf801645..31339dc327192 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -44,7 +44,6 @@ struct cached_fid { unsigned long last_access_time; /* jiffies of when last accessed */ struct kref refcount; struct cifs_fid fid; - spinlock_t fid_lock; struct cifs_tcon *tcon; struct dentry *dentry; struct work_struct put_work; From 54c3a0b1a3fe9971d542d3aca67b0aa842179e07 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:12 -0500 Subject: [PATCH 11/25] smb: client: remove pointless cfid->has_lease check jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 2f6a4af028dbb392d55b261cafcb922dd7b7ffea open_cached_dir() will only return a valid cfid, which has both has_lease = true and time != 0. Remove the pointless check of cfid->has_lease right after open_cached_dir() returns no error. Signed-off-by: Henrique Carvalho Reviewed-by: Enzo Matsumiya Signed-off-by: Steve French (cherry picked from commit 2f6a4af028dbb392d55b261cafcb922dd7b7ffea) Signed-off-by: Jonathan Maple --- fs/smb/client/smb2ops.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index f2e0a4c44883a..2633597686651 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -945,11 +945,8 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, rc = open_cached_dir(xid, tcon, full_path, cifs_sb, true, &cfid); if (!rc) { - if (cfid->has_lease) { - close_cached_dir(cfid); - return 0; - } close_cached_dir(cfid); + return 0; } utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); From 634eb37c792c8753ec0fbca5e287c47f4b77afde Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:13 -0500 Subject: [PATCH 12/25] smb: client: short-circuit in open_cached_dir_by_dentry() if !dentry jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 55580ad027a6764b7b1ee75f537d67811a06307f When dentry is NULL, the current code acquires the spinlock and traverses the entire list, but the condition (dentry && cfid->dentry == dentry) ensures no match will ever be found. Return -ENOENT early in this case, avoiding unnecessary lock acquisition and list traversal. Signed-off-by: Henrique Carvalho Signed-off-by: Steve French (cherry picked from commit 55580ad027a6764b7b1ee75f537d67811a06307f) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 82e59eb8c0894..74c4b3e488390 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -415,9 +415,12 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, if (cfids == NULL) return -EOPNOTSUPP; + if (!dentry) + return -ENOENT; + spin_lock(&cfids->cfid_list_lock); list_for_each_entry(cfid, &cfids->entries, entry) { - if (dentry && cfid->dentry == dentry) { + if (cfid->dentry == dentry) { if (!is_valid_cached_dir(cfid)) break; cifs_dbg(FYI, "found a cached file handle by dentry\n"); From 39d47c05d5b03730fc0a336fc5f77a418472b020 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:13 -0500 Subject: [PATCH 13/25] smb: client: short-circuit negative lookups when parent dir is fully cached jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 316025335a2d41dc71c47abf6eb9a41987e94c0a When the parent directory has a valid and complete cached enumeration we can assume that negative dentries are not present in the directory, thus we can return without issuing a request. This reduces traffic for common ENOENT when the directory entries are cached. Signed-off-by: Henrique Carvalho Signed-off-by: Steve French (cherry picked from commit 316025335a2d41dc71c47abf6eb9a41987e94c0a) Signed-off-by: Jonathan Maple --- fs/smb/client/dir.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 1179224abfb4e..0c351e40bb0a3 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -683,6 +683,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, const char *full_path; void *page; int retry_count = 0; + struct cached_fid *cfid = NULL; xid = get_xid(); @@ -722,6 +723,28 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, cifs_dbg(FYI, "non-NULL inode in lookup\n"); } else { cifs_dbg(FYI, "NULL inode in lookup\n"); + + /* + * We can only rely on negative dentries having the same + * spelling as the cached dirent if case insensitivity is + * forced on mount. + * + * XXX: if servers correctly announce Case Sensitivity Search + * on GetInfo of FileFSAttributeInformation, then we can take + * correct action even if case insensitive is not forced on + * mount. + */ + if (pTcon->nocase && !open_cached_dir_by_dentry(pTcon, direntry->d_parent, &cfid)) { + /* + * dentry is negative and parent is fully cached: + * we can assume file does not exist + */ + if (cfid->dirents.is_valid) { + close_cached_dir(cfid); + goto out; + } + close_cached_dir(cfid); + } } cifs_dbg(FYI, "Full path: %s inode = 0x%p\n", full_path, d_inode(direntry)); @@ -755,6 +778,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, } newInode = ERR_PTR(rc); } + +out: free_dentry_path(page); cifs_put_tlink(tlink); free_xid(xid); @@ -764,7 +789,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, static int cifs_d_revalidate(struct dentry *direntry, unsigned int flags) { - struct inode *inode; + struct inode *inode = NULL; + struct cached_fid *cfid; int rc; if (flags & LOOKUP_RCU) @@ -811,6 +837,21 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) return 1; } + } else { + struct cifs_sb_info *cifs_sb = CIFS_SB(dir->i_sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + + if (!open_cached_dir_by_dentry(tcon, direntry->d_parent, &cfid)) { + /* + * dentry is negative and parent is fully cached: + * we can assume file does not exist + */ + if (cfid->dirents.is_valid) { + close_cached_dir(cfid); + return 1; + } + close_cached_dir(cfid); + } } /* From 52cd4fc891ebe3fbd2a772d80139bd3fd63f9d39 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:13 -0500 Subject: [PATCH 14/25] smb client: fix bug with newly created file in cached dir jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Bharath SM commit aa12118dbcfe659697567c9daa0eac2c71e3fd37 Test generic/637 spotted a problem with create of a new file in a cached directory (by the same client) could cause cases where the new file does not show up properly in ls on that client until the lease times out. Fixes: 037e1bae588e ("smb: client: use ParentLeaseKey in cifs_do_create") Cc: stable@vger.kernel.org Signed-off-by: Bharath SM Signed-off-by: Steve French (cherry picked from commit aa12118dbcfe659697567c9daa0eac2c71e3fd37) Signed-off-by: Jonathan Maple --- fs/smb/client/dir.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 0c351e40bb0a3..70b4170d9cc0e 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -329,6 +329,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned parent_cfid->fid.lease_key, SMB2_LEASE_KEY_SIZE); parent_cfid->dirents.is_valid = false; + parent_cfid->dirents.is_failed = true; } break; } From 282e66b82743b2606764c9d1acd70c94505d454d Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:13 -0500 Subject: [PATCH 15/25] smb: client: remove cfids_invalidation_worker jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Enzo Matsumiya commit 7ae6152b78316319b9c935eb17c863fbebf54ea6 We can do the same cleanup on laundromat. On invalidate_all_cached_dirs(), run laundromat worker with 0 timeout and flush it for immediate + sync cleanup. Signed-off-by: Enzo Matsumiya Signed-off-by: Steve French (cherry picked from commit 7ae6152b78316319b9c935eb17c863fbebf54ea6) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 37 +++++++++---------------------------- fs/smb/client/cached_dir.h | 1 - 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 74c4b3e488390..b76481e4bfebf 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -561,8 +561,8 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) /* * Mark all the cfids as closed, and move them to the cfids->dying list. - * They'll be cleaned up later by cfids_invalidation_worker. Take - * a reference to each cfid during this process. + * They'll be cleaned up by laundromat. Take a reference to each cfid + * during this process. */ spin_lock(&cfids->cfid_list_lock); list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { @@ -579,12 +579,11 @@ void invalidate_all_cached_dirs(struct cifs_tcon *tcon) } else kref_get(&cfid->refcount); } - /* - * Queue dropping of the dentries once locks have been dropped - */ - if (!list_empty(&cfids->dying)) - queue_work(cfid_put_wq, &cfids->invalidation_work); spin_unlock(&cfids->cfid_list_lock); + + /* run laundromat unconditionally now as there might have been previously queued work */ + mod_delayed_work(cfid_put_wq, &cfids->laundromat_work, 0); + flush_delayed_work(&cfids->laundromat_work); } static void @@ -714,25 +713,6 @@ static void free_cached_dir(struct cached_fid *cfid) kfree(cfid); } -static void cfids_invalidation_worker(struct work_struct *work) -{ - struct cached_fids *cfids = container_of(work, struct cached_fids, - invalidation_work); - struct cached_fid *cfid, *q; - LIST_HEAD(entry); - - spin_lock(&cfids->cfid_list_lock); - /* move cfids->dying to the local list */ - list_cut_before(&entry, &cfids->dying, &cfids->dying); - spin_unlock(&cfids->cfid_list_lock); - - list_for_each_entry_safe(cfid, q, &entry, entry) { - list_del(&cfid->entry); - /* Drop the ref-count acquired in invalidate_all_cached_dirs */ - kref_put(&cfid->refcount, smb2_close_cached_fid); - } -} - static void cfids_laundromat_worker(struct work_struct *work) { struct cached_fids *cfids; @@ -742,6 +722,9 @@ static void cfids_laundromat_worker(struct work_struct *work) cfids = container_of(work, struct cached_fids, laundromat_work.work); spin_lock(&cfids->cfid_list_lock); + /* move cfids->dying to the local list */ + list_cut_before(&entry, &cfids->dying, &cfids->dying); + list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { if (cfid->last_access_time && time_after(jiffies, cfid->last_access_time + HZ * dir_cache_timeout)) { @@ -795,7 +778,6 @@ struct cached_fids *init_cached_dirs(void) INIT_LIST_HEAD(&cfids->entries); INIT_LIST_HEAD(&cfids->dying); - INIT_WORK(&cfids->invalidation_work, cfids_invalidation_worker); INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker); queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout * HZ); @@ -819,7 +801,6 @@ void free_cached_dirs(struct cached_fids *cfids) return; cancel_delayed_work_sync(&cfids->laundromat_work); - cancel_work_sync(&cfids->invalidation_work); spin_lock(&cfids->cfid_list_lock); list_for_each_entry_safe(cfid, q, &cfids->entries, entry) { diff --git a/fs/smb/client/cached_dir.h b/fs/smb/client/cached_dir.h index 31339dc327192..1e383db7c3374 100644 --- a/fs/smb/client/cached_dir.h +++ b/fs/smb/client/cached_dir.h @@ -62,7 +62,6 @@ struct cached_fids { int num_entries; struct list_head entries; struct list_head dying; - struct work_struct invalidation_work; struct delayed_work laundromat_work; /* aggregate accounting for all cached dirents under this tcon */ atomic_long_t total_dirents_entries; From 22f9fa5e4334615121855099f1c91b5cb0c8436d Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:14 -0500 Subject: [PATCH 16/25] cifs: parse_dfs_referrals: prevent oob on malformed input jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Eugene Korenevsky commit 6447b0e355562a1ff748c4a2ffb89aae7e84d2c9 Malicious SMB server can send invalid reply to FSCTL_DFS_GET_REFERRALS - reply smaller than sizeof(struct get_dfs_referral_rsp) - reply with number of referrals smaller than NumberOfReferrals in the header Processing of such replies will cause oob. Return -EINVAL error on such replies to prevent oob-s. Signed-off-by: Eugene Korenevsky Cc: stable@vger.kernel.org Suggested-by: Nathan Chancellor Acked-by: Paulo Alcantara (Red Hat) Signed-off-by: Steve French (cherry picked from commit 6447b0e355562a1ff748c4a2ffb89aae7e84d2c9) Signed-off-by: Jonathan Maple --- fs/smb/client/misc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index dda6dece802ad..e10123d8cd7d9 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -916,6 +916,14 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size, char *data_end; struct dfs_referral_level_3 *ref; + if (rsp_size < sizeof(*rsp)) { + cifs_dbg(VFS | ONCE, + "%s: header is malformed (size is %u, must be %zu)\n", + __func__, rsp_size, sizeof(*rsp)); + rc = -EINVAL; + goto parse_DFS_referrals_exit; + } + *num_of_nodes = le16_to_cpu(rsp->NumberOfReferrals); if (*num_of_nodes < 1) { @@ -925,6 +933,15 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size, goto parse_DFS_referrals_exit; } + if (sizeof(*rsp) + *num_of_nodes * sizeof(REFERRAL3) > rsp_size) { + cifs_dbg(VFS | ONCE, + "%s: malformed buffer (size is %u, must be at least %zu)\n", + __func__, rsp_size, + sizeof(*rsp) + *num_of_nodes * sizeof(REFERRAL3)); + rc = -EINVAL; + goto parse_DFS_referrals_exit; + } + ref = (struct dfs_referral_level_3 *) &(rsp->referrals); if (ref->VersionNumber != cpu_to_le16(3)) { cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n", From 397fa1a9c7aac43ad35e7a866f96916d8204d356 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:14 -0500 Subject: [PATCH 17/25] smb: client: Fix refcount leak for cifs_sb_tlink jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Shuhao Fu commit c2b77f42205ef485a647f62082c442c1cd69d3fc Fix three refcount inconsistency issues related to `cifs_sb_tlink`. Comments for `cifs_sb_tlink` state that `cifs_put_tlink()` needs to be called after successful calls to `cifs_sb_tlink()`. Three calls fail to update refcount accordingly, leading to possible resource leaks. Fixes: 8ceb98437946 ("CIFS: Move rename to ops struct") Fixes: 2f1afe25997f ("cifs: Use smb 2 - 3 and cifsacl mount options getacl functions") Fixes: 366ed846df60 ("cifs: Use smb 2 - 3 and cifsacl mount options setacl function") Cc: stable@vger.kernel.org Signed-off-by: Shuhao Fu Signed-off-by: Steve French (cherry picked from commit c2b77f42205ef485a647f62082c442c1cd69d3fc) Signed-off-by: Jonathan Maple --- fs/smb/client/inode.c | 6 ++++-- fs/smb/client/smb2ops.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index ceac71cf86a3e..b35439742c9cb 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -2431,8 +2431,10 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, tcon = tlink_tcon(tlink); server = tcon->ses->server; - if (!server->ops->rename) - return -ENOSYS; + if (!server->ops->rename) { + rc = -ENOSYS; + goto do_rename_exit; + } /* try path-based rename first */ rc = server->ops->rename(xid, tcon, from_dentry, diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 2633597686651..98d192dcdca9a 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -3117,8 +3117,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); if (!utf16_path) { rc = -ENOMEM; - free_xid(xid); - return ERR_PTR(rc); + goto put_tlink; } oparms = (struct cifs_open_parms) { @@ -3150,6 +3149,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); } +put_tlink: cifs_put_tlink(tlink); free_xid(xid); @@ -3190,8 +3190,7 @@ set_smb2_acl(struct smb_ntsd *pnntsd, __u32 acllen, utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); if (!utf16_path) { rc = -ENOMEM; - free_xid(xid); - return rc; + goto put_tlink; } oparms = (struct cifs_open_parms) { @@ -3212,6 +3211,7 @@ set_smb2_acl(struct smb_ntsd *pnntsd, __u32 acllen, SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); } +put_tlink: cifs_put_tlink(tlink); free_xid(xid); return rc; From 4bc6253dccbf08d1f26c086c19fbbcea5ed63f72 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:14 -0500 Subject: [PATCH 18/25] smb: client: fix potential cfid UAF in smb2_query_info_compound jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 5c76f9961c170552c1d07c830b5e145475151600 When smb2_query_info_compound() retries, a previously allocated cfid may have been freed in the first attempt. Because cfid wasn't reset on replay, later cleanup could act on a stale pointer, leading to a potential use-after-free. Reinitialize cfid to NULL under the replay label. Example trace (trimmed): refcount_t: underflow; use-after-free. WARNING: CPU: 1 PID: 11224 at ../lib/refcount.c:28 refcount_warn_saturate+0x9c/0x110 [...] RIP: 0010:refcount_warn_saturate+0x9c/0x110 [...] Call Trace: smb2_query_info_compound+0x29c/0x5c0 [cifs f90b72658819bd21c94769b6a652029a07a7172f] ? step_into+0x10d/0x690 ? __legitimize_path+0x28/0x60 smb2_queryfs+0x6a/0xf0 [cifs f90b72658819bd21c94769b6a652029a07a7172f] smb311_queryfs+0x12d/0x140 [cifs f90b72658819bd21c94769b6a652029a07a7172f] ? kmem_cache_alloc+0x18a/0x340 ? getname_flags+0x46/0x1e0 cifs_statfs+0x9f/0x2b0 [cifs f90b72658819bd21c94769b6a652029a07a7172f] statfs_by_dentry+0x67/0x90 vfs_statfs+0x16/0xd0 user_statfs+0x54/0xa0 __do_sys_statfs+0x20/0x50 do_syscall_64+0x58/0x80 Cc: stable@kernel.org Fixes: 4f1fffa237692 ("cifs: commands that are retried should have replay flag set") Reviewed-by: Paulo Alcantara (Red Hat) Acked-by: Shyam Prasad N Reviewed-by: Enzo Matsumiya Signed-off-by: Henrique Carvalho Signed-off-by: Steve French (cherry picked from commit 5c76f9961c170552c1d07c830b5e145475151600) Signed-off-by: Jonathan Maple --- fs/smb/client/smb2ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 98d192dcdca9a..25e5d26094338 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -2704,11 +2704,12 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid fid; int rc; __le16 *utf16_path; - struct cached_fid *cfid = NULL; + struct cached_fid *cfid; int retries = 0, cur_sleep = 1; replay_again: /* reinitialize for possible replay */ + cfid = NULL; flags = CIFS_CP_CREATE_CLOSE_OP; oplock = SMB2_OPLOCK_LEVEL_NONE; server = cifs_pick_channel(ses); From 00ecbe7d5cb722895f38494724671cacb6392140 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:15 -0500 Subject: [PATCH 19/25] smb: client: fix potential UAF in smb2_close_cached_fid() jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Henrique Carvalho commit 734e99623c5b65bf2c03e35978a0b980ebc3c2f8 find_or_create_cached_dir() could grab a new reference after kref_put() had seen the refcount drop to zero but before cfid_list_lock is acquired in smb2_close_cached_fid(), leading to use-after-free. Switch to kref_put_lock() so cfid_release() is called with cfid_list_lock held, closing that gap. Fixes: ebe98f1447bb ("cifs: enable caching of directories for which a lease is held") Cc: stable@vger.kernel.org Reported-by: Jay Shin Reviewed-by: Paulo Alcantara (Red Hat) Signed-off-by: Henrique Carvalho Signed-off-by: Steve French (cherry picked from commit 734e99623c5b65bf2c03e35978a0b980ebc3c2f8) Signed-off-by: Jonathan Maple --- fs/smb/client/cached_dir.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index b76481e4bfebf..fd0947ee56b03 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -387,11 +387,11 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, * lease. Release one here, and the second below. */ cfid->has_lease = false; - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } spin_unlock(&cfids->cfid_list_lock); - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } else { *ret_cfid = cfid; atomic_inc(&tcon->num_remote_opens); @@ -437,12 +437,14 @@ int open_cached_dir_by_dentry(struct cifs_tcon *tcon, static void smb2_close_cached_fid(struct kref *ref) +__releases(&cfid->cfids->cfid_list_lock) { struct cached_fid *cfid = container_of(ref, struct cached_fid, refcount); int rc; - spin_lock(&cfid->cfids->cfid_list_lock); + lockdep_assert_held(&cfid->cfids->cfid_list_lock); + if (cfid->on_list) { list_del(&cfid->entry); cfid->on_list = false; @@ -477,7 +479,7 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon, spin_lock(&cfid->cfids->cfid_list_lock); if (cfid->has_lease) { cfid->has_lease = false; - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } spin_unlock(&cfid->cfids->cfid_list_lock); close_cached_dir(cfid); @@ -486,7 +488,7 @@ void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon, void close_cached_dir(struct cached_fid *cfid) { - kref_put(&cfid->refcount, smb2_close_cached_fid); + kref_put_lock(&cfid->refcount, smb2_close_cached_fid, &cfid->cfids->cfid_list_lock); } /* @@ -595,7 +597,7 @@ cached_dir_offload_close(struct work_struct *work) WARN_ON(cfid->on_list); - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close); } @@ -761,7 +763,7 @@ static void cfids_laundromat_worker(struct work_struct *work) * Drop the ref-count from above, either the lease-ref (if there * was one) or the extra one acquired. */ - kref_put(&cfid->refcount, smb2_close_cached_fid); + close_cached_dir(cfid); } queue_delayed_work(cfid_put_wq, &cfids->laundromat_work, dir_cache_timeout * HZ); From d297418a8978a19bbcc30aa73003dd94a99dcd71 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:15 -0500 Subject: [PATCH 20/25] smb: client: fix refcount leak in smb2_set_path_attr jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Shuhao Fu commit b540de9e3b4fab3b9e10f30714a6f5c1b2a50ec3 Fix refcount leak in `smb2_set_path_attr` when path conversion fails. Function `cifs_get_writable_path` returns `cfile` with its reference counter `cfile->count` increased on success. Function `smb2_compound_op` would decrease the reference counter for `cfile`, as stated in its comment. By calling `smb2_rename_path`, the reference counter of `cfile` would leak if `cifs_convert_path_to_utf16` fails in `smb2_set_path_attr`. Fixes: 8de9e86c67ba ("cifs: create a helper to find a writeable handle by path name") Acked-by: Henrique Carvalho Signed-off-by: Shuhao Fu Signed-off-by: Steve French (cherry picked from commit b540de9e3b4fab3b9e10f30714a6f5c1b2a50ec3) Signed-off-by: Jonathan Maple --- fs/smb/client/smb2inode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 0985db9f86e51..8b8da827e51ee 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -1294,6 +1294,8 @@ static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, smb2_to_name = cifs_convert_path_to_utf16(to_name, cifs_sb); if (smb2_to_name == NULL) { rc = -ENOMEM; + if (cfile) + cifsFileInfo_put(cfile); goto smb2_rename_path; } in_iov.iov_base = smb2_to_name; From eab08074e898708bfba40589454f60c505d9ccf8 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:15 -0500 Subject: [PATCH 21/25] vmalloc: add for_each_vmap_node() helper jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Uladzislau Rezki (Sony) commit 4318255091eab6722bea3816bdee09ac7db68035 To simplify iteration over vmap-nodes, add the for_each_vmap_node() macro that iterates over all nodes in a system. It tends to simplify the code. Link: https://lkml.kernel.org/r/20250408151549.77937-1-urezki@gmail.com Signed-off-by: Uladzislau Rezki (Sony) Cc: Christop Hellwig Signed-off-by: Andrew Morton (cherry picked from commit 4318255091eab6722bea3816bdee09ac7db68035) Signed-off-by: Jonathan Maple --- mm/vmalloc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 5c88d0e90c209..2fad0d3b789f4 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -900,6 +900,11 @@ static struct vmap_node *vmap_nodes = &single; static __read_mostly unsigned int nr_vmap_nodes = 1; static __read_mostly unsigned int vmap_zone_size = 1; +/* A simple iterator over all vmap-nodes. */ +#define for_each_vmap_node(vn) \ + for ((vn) = &vmap_nodes[0]; \ + (vn) < &vmap_nodes[nr_vmap_nodes]; (vn)++) + static inline unsigned int addr_to_node_id(unsigned long addr) { From f7ef4016dfcd3a87ebf01a90df1ae23d1e8ec4bc Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:15 -0500 Subject: [PATCH 22/25] vmalloc: switch to for_each_vmap_node() helper jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Uladzislau Rezki (Sony) commit ce906d7679e1f1feab54bdddac4d39df846d663a There are places which can be updated easily to use the helper to iterate over all vmap-nodes. This is what this patch does. The aim is to improve readability and simplify the code. [akpm@linux-foundation.org: fix build warning] Link: https://lkml.kernel.org/r/20250408151549.77937-2-urezki@gmail.com Signed-off-by: Uladzislau Rezki (Sony) Cc: Christop Hellwig Signed-off-by: Andrew Morton (cherry picked from commit ce906d7679e1f1feab54bdddac4d39df846d663a) Signed-off-by: Jonathan Maple --- mm/vmalloc.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 2fad0d3b789f4..012c386c3be5f 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1061,12 +1061,11 @@ find_vmap_area_exceed_addr_lock(unsigned long addr, struct vmap_area **va) { unsigned long va_start_lowest; struct vmap_node *vn; - int i; repeat: - for (i = 0, va_start_lowest = 0; i < nr_vmap_nodes; i++) { - vn = &vmap_nodes[i]; + va_start_lowest = 0; + for_each_vmap_node(vn) { spin_lock(&vn->busy.lock); *va = __find_vmap_area_exceed_addr(addr, &vn->busy.root); @@ -4951,11 +4950,8 @@ static void show_purge_info(struct seq_file *m) { struct vmap_node *vn; struct vmap_area *va; - int i; - - for (i = 0; i < nr_vmap_nodes; i++) { - vn = &vmap_nodes[i]; + for_each_vmap_node(vn) { spin_lock(&vn->lazy.lock); list_for_each_entry(va, &vn->lazy.head, list) { seq_printf(m, "0x%pK-0x%pK %7ld unpurged vm_area\n", @@ -4971,11 +4967,8 @@ static int vmalloc_info_show(struct seq_file *m, void *p) struct vmap_node *vn; struct vmap_area *va; struct vm_struct *v; - int i; - - for (i = 0; i < nr_vmap_nodes; i++) { - vn = &vmap_nodes[i]; + for_each_vmap_node(vn) { spin_lock(&vn->busy.lock); list_for_each_entry(va, &vn->busy.head, list) { if (!va->vm) { @@ -5096,7 +5089,7 @@ static void __init vmap_init_free_space(void) static void vmap_init_nodes(void) { struct vmap_node *vn; - int i, n; + int i; #if BITS_PER_LONG == 64 /* @@ -5113,7 +5106,7 @@ static void vmap_init_nodes(void) * set of cores. Therefore a per-domain purging is supposed to * be added as well as a per-domain balancing. */ - n = clamp_t(unsigned int, num_possible_cpus(), 1, 128); + int n = clamp_t(unsigned int, num_possible_cpus(), 1, 128); if (n > 1) { vn = kmalloc_array(n, sizeof(*vn), GFP_NOWAIT | __GFP_NOWARN); @@ -5128,8 +5121,7 @@ static void vmap_init_nodes(void) } #endif - for (n = 0; n < nr_vmap_nodes; n++) { - vn = &vmap_nodes[n]; + for_each_vmap_node(vn) { vn->busy.root = RB_ROOT; INIT_LIST_HEAD(&vn->busy.head); spin_lock_init(&vn->busy.lock); @@ -5150,15 +5142,13 @@ static void vmap_init_nodes(void) static unsigned long vmap_node_shrink_count(struct shrinker *shrink, struct shrink_control *sc) { - unsigned long count; + unsigned long count = 0; struct vmap_node *vn; - int i, j; - - for (count = 0, i = 0; i < nr_vmap_nodes; i++) { - vn = &vmap_nodes[i]; + int i; - for (j = 0; j < MAX_VA_SIZE_PAGES; j++) - count += READ_ONCE(vn->pool[j].len); + for_each_vmap_node(vn) { + for (i = 0; i < MAX_VA_SIZE_PAGES; i++) + count += READ_ONCE(vn->pool[i].len); } return count ? count : SHRINK_EMPTY; @@ -5167,10 +5157,10 @@ vmap_node_shrink_count(struct shrinker *shrink, struct shrink_control *sc) static unsigned long vmap_node_shrink_scan(struct shrinker *shrink, struct shrink_control *sc) { - int i; + struct vmap_node *vn; - for (i = 0; i < nr_vmap_nodes; i++) - decay_va_pool_node(&vmap_nodes[i], true); + for_each_vmap_node(vn) + decay_va_pool_node(vn, true); return SHRINK_STOP; } From f82d4fc141f0b52bb0f90711e7b677522f438db4 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:16 -0500 Subject: [PATCH 23/25] vmalloc: use for_each_vmap_node() in purge-vmap-area jira KERNEL-558 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Uladzislau Rezki (Sony) commit 24c76f37ab3fb2f3a202eaa678334b216f8bd161 Update a __purge_vmap_area_lazy() to use introduced helper. This is last place in vmalloc code. Also this patch introduces an extra function which is node_to_id() that converts a vmap_node pointer to an index in array. __purge_vmap_area_lazy() requires that extra function. Link: https://lkml.kernel.org/r/20250408151549.77937-3-urezki@gmail.com Signed-off-by: Uladzislau Rezki (Sony) Cc: Christop Hellwig Signed-off-by: Andrew Morton (cherry picked from commit 24c76f37ab3fb2f3a202eaa678334b216f8bd161) Signed-off-by: Jonathan Maple --- mm/vmalloc.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 012c386c3be5f..859b89617aea8 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -923,6 +923,19 @@ id_to_node(unsigned int id) return &vmap_nodes[id % nr_vmap_nodes]; } +static inline unsigned int +node_to_id(struct vmap_node *node) +{ + /* Pointer arithmetic. */ + unsigned int id = node - vmap_nodes; + + if (likely(id < nr_vmap_nodes)) + return id; + + WARN_ONCE(1, "An address 0x%p is out-of-bounds.\n", node); + return 0; +} + /* * We use the value 0 to represent "no node", that is why * an encoded value will be the node-id incremented by 1. @@ -2259,9 +2272,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end, */ purge_nodes = CPU_MASK_NONE; - for (i = 0; i < nr_vmap_nodes; i++) { - vn = &vmap_nodes[i]; - + for_each_vmap_node(vn) { INIT_LIST_HEAD(&vn->purge_list); vn->skip_populate = full_pool_decay; decay_va_pool_node(vn, full_pool_decay); @@ -2280,7 +2291,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end, end = max(end, list_last_entry(&vn->purge_list, struct vmap_area, list)->va_end); - cpumask_set_cpu(i, &purge_nodes); + cpumask_set_cpu(node_to_id(vn), &purge_nodes); } nr_purge_nodes = cpumask_weight(&purge_nodes); From 21d7e25f117ee91e776df42f5030ae7c3935b890 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:16 -0500 Subject: [PATCH 24/25] mm/vmalloc: fix data race in show_numa_info() jira KERNEL-558 cve CVE-2025-38383 Rebuild_History Non-Buildable kernel-6.12.0-124.29.1.el10_1 commit-author Jeongjun Park commit 5c5f0468d172ddec2e333d738d2a1f85402cf0bc The following data-race was found in show_numa_info(): ================================================================== BUG: KCSAN: data-race in vmalloc_info_show / vmalloc_info_show read to 0xffff88800971fe30 of 4 bytes by task 8289 on cpu 0: show_numa_info mm/vmalloc.c:4936 [inline] vmalloc_info_show+0x5a8/0x7e0 mm/vmalloc.c:5016 seq_read_iter+0x373/0xb40 fs/seq_file.c:230 proc_reg_read_iter+0x11e/0x170 fs/proc/inode.c:299 .... write to 0xffff88800971fe30 of 4 bytes by task 8287 on cpu 1: show_numa_info mm/vmalloc.c:4934 [inline] vmalloc_info_show+0x38f/0x7e0 mm/vmalloc.c:5016 seq_read_iter+0x373/0xb40 fs/seq_file.c:230 proc_reg_read_iter+0x11e/0x170 fs/proc/inode.c:299 .... value changed: 0x0000008f -> 0x00000000 ================================================================== According to this report,there is a read/write data-race because m->private is accessible to multiple CPUs. To fix this, instead of allocating the heap in proc_vmalloc_init() and passing the heap address to m->private, vmalloc_info_show() should allocate the heap. Link: https://lkml.kernel.org/r/20250508165620.15321-1-aha310510@gmail.com Fixes: 8e1d743f2c26 ("mm: vmalloc: support multiple nodes in vmallocinfo") Signed-off-by: Jeongjun Park Suggested-by: Eric Dumazet Suggested-by: Andrew Morton Reviewed-by: "Uladzislau Rezki (Sony)" Signed-off-by: Andrew Morton (cherry picked from commit 5c5f0468d172ddec2e333d738d2a1f85402cf0bc) Signed-off-by: Jonathan Maple --- mm/vmalloc.c | 63 +++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 859b89617aea8..b3ae891588084 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -3115,7 +3115,7 @@ static void clear_vm_uninitialized_flag(struct vm_struct *vm) /* * Before removing VM_UNINITIALIZED, * we should make sure that vm has proper values. - * Pair with smp_rmb() in show_numa_info(). + * Pair with smp_rmb() in vread_iter() and vmalloc_info_show(). */ smp_wmb(); vm->flags &= ~VM_UNINITIALIZED; @@ -4933,28 +4933,29 @@ bool vmalloc_dump_obj(void *object) #endif #ifdef CONFIG_PROC_FS -static void show_numa_info(struct seq_file *m, struct vm_struct *v) -{ - if (IS_ENABLED(CONFIG_NUMA)) { - unsigned int nr, *counters = m->private; - unsigned int step = 1U << vm_area_page_order(v); - if (!counters) - return; +/* + * Print number of pages allocated on each memory node. + * + * This function can only be called if CONFIG_NUMA is enabled + * and VM_UNINITIALIZED bit in v->flags is disabled. + */ +static void show_numa_info(struct seq_file *m, struct vm_struct *v, + unsigned int *counters) +{ + unsigned int nr; + unsigned int step = 1U << vm_area_page_order(v); - if (v->flags & VM_UNINITIALIZED) - return; - /* Pair with smp_wmb() in clear_vm_uninitialized_flag() */ - smp_rmb(); + if (!counters) + return; - memset(counters, 0, nr_node_ids * sizeof(unsigned int)); + memset(counters, 0, nr_node_ids * sizeof(unsigned int)); - for (nr = 0; nr < v->nr_pages; nr += step) - counters[page_to_nid(v->pages[nr])] += step; - for_each_node_state(nr, N_HIGH_MEMORY) - if (counters[nr]) - seq_printf(m, " N%u=%u", nr, counters[nr]); - } + for (nr = 0; nr < v->nr_pages; nr += step) + counters[page_to_nid(v->pages[nr])] += step; + for_each_node_state(nr, N_HIGH_MEMORY) + if (counters[nr]) + seq_printf(m, " N%u=%u", nr, counters[nr]); } static void show_purge_info(struct seq_file *m) @@ -4978,6 +4979,10 @@ static int vmalloc_info_show(struct seq_file *m, void *p) struct vmap_node *vn; struct vmap_area *va; struct vm_struct *v; + unsigned int *counters; + + if (IS_ENABLED(CONFIG_NUMA)) + counters = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL); for_each_vmap_node(vn) { spin_lock(&vn->busy.lock); @@ -4992,6 +4997,11 @@ static int vmalloc_info_show(struct seq_file *m, void *p) } v = va->vm; + if (v->flags & VM_UNINITIALIZED) + continue; + + /* Pair with smp_wmb() in clear_vm_uninitialized_flag() */ + smp_rmb(); seq_printf(m, "0x%pK-0x%pK %7ld", v->addr, v->addr + v->size, v->size); @@ -5026,7 +5036,9 @@ static int vmalloc_info_show(struct seq_file *m, void *p) if (is_vmalloc_addr(v->pages)) seq_puts(m, " vpages"); - show_numa_info(m, v); + if (IS_ENABLED(CONFIG_NUMA)) + show_numa_info(m, v, counters); + seq_putc(m, '\n'); } spin_unlock(&vn->busy.lock); @@ -5036,19 +5048,14 @@ static int vmalloc_info_show(struct seq_file *m, void *p) * As a final step, dump "unpurged" areas. */ show_purge_info(m); + if (IS_ENABLED(CONFIG_NUMA)) + kfree(counters); return 0; } static int __init proc_vmalloc_init(void) { - void *priv_data = NULL; - - if (IS_ENABLED(CONFIG_NUMA)) - priv_data = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL); - - proc_create_single_data("vmallocinfo", - 0400, NULL, vmalloc_info_show, priv_data); - + proc_create_single("vmallocinfo", 0400, NULL, vmalloc_info_show); return 0; } module_init(proc_vmalloc_init); From 8224a053ff60aa27fd4baf7d6c1fb6cde3075083 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Fri, 30 Jan 2026 18:00:33 -0500 Subject: [PATCH 25/25] Rebuild rocky10_1 with kernel-6.12.0-124.29.1.el10_1 Rebuild_History BUILDABLE Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% Number of commits in upstream range v6.12~1..kernel-mainline: 93416 Number of commits in rpm: 28 Number of commits matched with upstream: 24 (85.71%) Number of commits in upstream but not in rpm: 93392 Number of commits NOT found in upstream: 4 (14.29%) Rebuilding Kernel on Branch rocky10_1_rebuild_kernel-6.12.0-124.29.1.el10_1 for kernel-6.12.0-124.29.1.el10_1 Clean Cherry Picks: 24 (100.00%) Empty Cherry Picks: 0 (0.00%) _______________________________ Full Details Located here: ciq/ciq_backports/kernel-6.12.0-124.29.1.el10_1/rebuild.details.txt Includes: * git commit header above * Empty Commits with upstream SHA * RPM ChangeLog Entries that could not be matched Individual Empty Commit failures contained in the same containing directory. The git message for empty commits will have the path for the failed commit. File names are the first 8 characters of the upstream SHA --- ...1.el10_1 => COPYING-6.12.0-124.29.1.el10_1 | 0 Makefile.rhelver | 2 +- .../rebuild.details.txt | 20 +++++++++++++ .../kernel-6.12.0-aarch64-64k-debug.config | 4 +-- configs/kernel-6.12.0-aarch64-64k.config | 4 +-- configs/kernel-6.12.0-aarch64-debug.config | 4 +-- .../kernel-6.12.0-aarch64-rt-64k-debug.config | 4 +-- configs/kernel-6.12.0-aarch64-rt-64k.config | 4 +-- configs/kernel-6.12.0-aarch64-rt-debug.config | 4 +-- configs/kernel-6.12.0-aarch64-rt.config | 4 +-- configs/kernel-6.12.0-aarch64.config | 4 +-- configs/kernel-6.12.0-ppc64le-debug.config | 4 +-- configs/kernel-6.12.0-ppc64le.config | 4 +-- configs/kernel-6.12.0-riscv64-debug.config | 4 +-- configs/kernel-6.12.0-riscv64.config | 4 +-- configs/kernel-6.12.0-s390x-debug.config | 4 +-- configs/kernel-6.12.0-s390x-zfcpdump.config | 4 +-- configs/kernel-6.12.0-s390x.config | 4 +-- configs/kernel-6.12.0-x86_64-debug.config | 4 +-- configs/kernel-6.12.0-x86_64-rt-debug.config | 4 +-- configs/kernel-6.12.0-x86_64-rt.config | 4 +-- configs/kernel-6.12.0-x86_64.config | 4 +-- fs/smb/client/dir.c | 2 +- redhat/kernel.changelog-10.1 | 28 +++++++++++++++++++ uki-addons.sbat | 4 +-- uki.sbat | 4 +-- 26 files changed, 92 insertions(+), 44 deletions(-) rename COPYING-6.12.0-124.28.1.el10_1 => COPYING-6.12.0-124.29.1.el10_1 (100%) create mode 100644 ciq/ciq_backports/kernel-6.12.0-124.29.1.el10_1/rebuild.details.txt diff --git a/COPYING-6.12.0-124.28.1.el10_1 b/COPYING-6.12.0-124.29.1.el10_1 similarity index 100% rename from COPYING-6.12.0-124.28.1.el10_1 rename to COPYING-6.12.0-124.29.1.el10_1 diff --git a/Makefile.rhelver b/Makefile.rhelver index 0d558c2f2f646..add841228a689 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 1 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 124.28.1 +RHEL_RELEASE = 124.29.1 # # RHEL_REBASE_NUM diff --git a/ciq/ciq_backports/kernel-6.12.0-124.29.1.el10_1/rebuild.details.txt b/ciq/ciq_backports/kernel-6.12.0-124.29.1.el10_1/rebuild.details.txt new file mode 100644 index 0000000000000..c7dee2feef589 --- /dev/null +++ b/ciq/ciq_backports/kernel-6.12.0-124.29.1.el10_1/rebuild.details.txt @@ -0,0 +1,20 @@ +Rebuild_History BUILDABLE +Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% +Number of commits in upstream range v6.12~1..kernel-mainline: 93416 +Number of commits in rpm: 28 +Number of commits matched with upstream: 24 (85.71%) +Number of commits in upstream but not in rpm: 93392 +Number of commits NOT found in upstream: 4 (14.29%) + +Rebuilding Kernel on Branch rocky10_1_rebuild_kernel-6.12.0-124.29.1.el10_1 for kernel-6.12.0-124.29.1.el10_1 +Clean Cherry Picks: 24 (100.00%) +Empty Cherry Picks: 0 (0.00%) +_______________________________ + +__EMPTY COMMITS__________________________ + +__CHANGES NOT IN UPSTREAM________________ +Add partial riscv64 support for build root' +Provide basic VisionFive 2 support' +Patch MMU for riscv64' +gitlab-ci: use rhel10.1 builder image diff --git a/configs/kernel-6.12.0-aarch64-64k-debug.config b/configs/kernel-6.12.0-aarch64-64k-debug.config index 976f7ddcc1fa1..89c63ec931d57 100644 --- a/configs/kernel-6.12.0-aarch64-64k-debug.config +++ b/configs/kernel-6.12.0-aarch64-64k-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-64k.config b/configs/kernel-6.12.0-aarch64-64k.config index fc1423961a733..2c31913a36ffd 100644 --- a/configs/kernel-6.12.0-aarch64-64k.config +++ b/configs/kernel-6.12.0-aarch64-64k.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-debug.config b/configs/kernel-6.12.0-aarch64-debug.config index eba77102fc2a5..897ec5ee1ca2a 100644 --- a/configs/kernel-6.12.0-aarch64-debug.config +++ b/configs/kernel-6.12.0-aarch64-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt-64k-debug.config b/configs/kernel-6.12.0-aarch64-rt-64k-debug.config index 36a9ea924e736..f9a446a620d3b 100644 --- a/configs/kernel-6.12.0-aarch64-rt-64k-debug.config +++ b/configs/kernel-6.12.0-aarch64-rt-64k-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt-64k.config b/configs/kernel-6.12.0-aarch64-rt-64k.config index a94f969fd853d..da134a98df4b9 100644 --- a/configs/kernel-6.12.0-aarch64-rt-64k.config +++ b/configs/kernel-6.12.0-aarch64-rt-64k.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt-debug.config b/configs/kernel-6.12.0-aarch64-rt-debug.config index a8003d73aed0e..a54e5e6e98e19 100644 --- a/configs/kernel-6.12.0-aarch64-rt-debug.config +++ b/configs/kernel-6.12.0-aarch64-rt-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt.config b/configs/kernel-6.12.0-aarch64-rt.config index dc5ad05892136..1cd5fe06c54cf 100644 --- a/configs/kernel-6.12.0-aarch64-rt.config +++ b/configs/kernel-6.12.0-aarch64-rt.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64.config b/configs/kernel-6.12.0-aarch64.config index 2d579b0dbaeef..d128a41b44560 100644 --- a/configs/kernel-6.12.0-aarch64.config +++ b/configs/kernel-6.12.0-aarch64.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-ppc64le-debug.config b/configs/kernel-6.12.0-ppc64le-debug.config index ce940a7303a4f..ccfa3eca8218d 100644 --- a/configs/kernel-6.12.0-ppc64le-debug.config +++ b/configs/kernel-6.12.0-ppc64le-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-ppc64le.config b/configs/kernel-6.12.0-ppc64le.config index ec814991e2f15..bd9863680037a 100644 --- a/configs/kernel-6.12.0-ppc64le.config +++ b/configs/kernel-6.12.0-ppc64le.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-riscv64-debug.config b/configs/kernel-6.12.0-riscv64-debug.config index f674761392764..7e32eee0b294c 100644 --- a/configs/kernel-6.12.0-riscv64-debug.config +++ b/configs/kernel-6.12.0-riscv64-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-riscv64.config b/configs/kernel-6.12.0-riscv64.config index 71b88b3cf4fd4..48594fde160c2 100644 --- a/configs/kernel-6.12.0-riscv64.config +++ b/configs/kernel-6.12.0-riscv64.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-s390x-debug.config b/configs/kernel-6.12.0-s390x-debug.config index 6c5d8bc4344aa..d68176a104b7a 100644 --- a/configs/kernel-6.12.0-s390x-debug.config +++ b/configs/kernel-6.12.0-s390x-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-s390x-zfcpdump.config b/configs/kernel-6.12.0-s390x-zfcpdump.config index 1a49ef6c638bf..dedb67d608ad3 100644 --- a/configs/kernel-6.12.0-s390x-zfcpdump.config +++ b/configs/kernel-6.12.0-s390x-zfcpdump.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-s390x.config b/configs/kernel-6.12.0-s390x.config index 1323e612ec7e5..8d435b5d4830a 100644 --- a/configs/kernel-6.12.0-s390x.config +++ b/configs/kernel-6.12.0-s390x.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-debug.config b/configs/kernel-6.12.0-x86_64-debug.config index fa3044c4ab3ba..94d09a557b775 100644 --- a/configs/kernel-6.12.0-x86_64-debug.config +++ b/configs/kernel-6.12.0-x86_64-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-rt-debug.config b/configs/kernel-6.12.0-x86_64-rt-debug.config index 4df603849d15e..ebf9dd7915a3b 100644 --- a/configs/kernel-6.12.0-x86_64-rt-debug.config +++ b/configs/kernel-6.12.0-x86_64-rt-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-rt.config b/configs/kernel-6.12.0-x86_64-rt.config index b01bf080db1b3..ce4a536a71663 100644 --- a/configs/kernel-6.12.0-x86_64-rt.config +++ b/configs/kernel-6.12.0-x86_64-rt.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64.config b/configs/kernel-6.12.0-x86_64.config index c3fa4c155bd38..00afa86d9d1ea 100644 --- a/configs/kernel-6.12.0-x86_64.config +++ b/configs/kernel-6.12.0-x86_64.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=0 -CONFIG_RUSTC_LLVM_VERSION=0 +CONFIG_RUSTC_VERSION=107600 +CONFIG_RUSTC_LLVM_VERSION=170006 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index 70b4170d9cc0e..6831ad2fa2114 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -839,7 +839,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) return 1; } } else { - struct cifs_sb_info *cifs_sb = CIFS_SB(dir->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(d_inode(direntry->d_parent)->i_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); if (!open_cached_dir_by_dentry(tcon, direntry->d_parent, &cfid)) { diff --git a/redhat/kernel.changelog-10.1 b/redhat/kernel.changelog-10.1 index 9b6ab1e22e2a7..5028b7f7f4fb8 100644 --- a/redhat/kernel.changelog-10.1 +++ b/redhat/kernel.changelog-10.1 @@ -1,3 +1,31 @@ +* Sat Jan 10 2026 CKI KWF Bot [6.12.0-124.29.1.el10_1] +- gitlab-ci: use rhel10.1 builder image (Michael Hofmann) +- mm/vmalloc: fix data race in show_numa_info() (Waiman Long) [RHEL-137997] {CVE-2025-38383} +- vmalloc: use for_each_vmap_node() in purge-vmap-area (Waiman Long) [RHEL-137997] +- vmalloc: switch to for_each_vmap_node() helper (Waiman Long) [RHEL-137997] +- vmalloc: add for_each_vmap_node() helper (Waiman Long) [RHEL-137997] +- smb: client: fix refcount leak in smb2_set_path_attr (Paulo Alcantara) [RHEL-128581] +- smb: client: fix potential UAF in smb2_close_cached_fid() (Paulo Alcantara) [RHEL-128581] +- smb: client: fix potential cfid UAF in smb2_query_info_compound (Paulo Alcantara) [RHEL-128581] +- smb: client: Fix refcount leak for cifs_sb_tlink (Paulo Alcantara) [RHEL-128581] +- cifs: parse_dfs_referrals: prevent oob on malformed input (Paulo Alcantara) [RHEL-128581] +- smb: client: remove cfids_invalidation_worker (Paulo Alcantara) [RHEL-128581] +- smb client: fix bug with newly created file in cached dir (Paulo Alcantara) [RHEL-128581] +- smb: client: short-circuit negative lookups when parent dir is fully cached (Paulo Alcantara) [RHEL-128581] +- smb: client: short-circuit in open_cached_dir_by_dentry() if !dentry (Paulo Alcantara) [RHEL-128581] +- smb: client: remove pointless cfid->has_lease check (Paulo Alcantara) [RHEL-128581] +- smb: client: remove unused fid_lock (Paulo Alcantara) [RHEL-128581] +- smb: client: update cfid->last_access_time in open_cached_dir_by_dentry() (Paulo Alcantara) [RHEL-128581] +- smb: client: ensure open_cached_dir_by_dentry() only returns valid cfid (Paulo Alcantara) [RHEL-128581] +- smb: client: account smb directory cache usage and per-tcon totals (Paulo Alcantara) [RHEL-128581] +- smb: client: add drop_dir_cache module parameter to invalidate cached dirents (Paulo Alcantara) [RHEL-128581] +- smb: client: show lease state as R/H/W (or NONE) in open_files (Paulo Alcantara) [RHEL-128581] +- smb: client: show negotiated cipher in DebugData (Paulo Alcantara) [RHEL-128581] +- smb: client: add new tracepoint to trace lease break notification (Paulo Alcantara) [RHEL-128581] +- smb: client: Fix NULL pointer dereference in cifs_debug_dirs_proc_show() (Paulo Alcantara) [RHEL-128581] +- coredump: Only sort VMAs when core_sort_vma sysctl is set (Herton R. Krzesinski) [RHEL-113364] +Resolves: RHEL-113364, RHEL-128581, RHEL-137997 + * Wed Jan 07 2026 CKI KWF Bot [6.12.0-124.28.1.el10_1] - libceph: fix potential use-after-free in have_mon_and_osd_map() (CKI Backport Bot) [RHEL-137403] {CVE-2025-68285} Resolves: RHEL-137403 diff --git a/uki-addons.sbat b/uki-addons.sbat index 891e47a18f918..2c7cc053d3361 100644 --- a/uki-addons.sbat +++ b/uki-addons.sbat @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -kernel-uki-virt-addons.rhel,1,Red Hat,kernel-uki-virt-addons,6.12.0-124.28.1.el10_1.x86_64,mailto:secalert@redhat.com -kernel-uki-virt-addons.rocky,1,RESF,kernel-uki-virt-addons,6.12.0-124.28.1.el10_1.x86_64,mailto:security@rockylinux.org +kernel-uki-virt-addons.rhel,1,Red Hat,kernel-uki-virt-addons,6.12.0-124.29.1.el10_1.x86_64,mailto:secalert@redhat.com +kernel-uki-virt-addons.rocky,1,RESF,kernel-uki-virt-addons,6.12.0-124.29.1.el10_1.x86_64,mailto:security@rockylinux.org diff --git a/uki.sbat b/uki.sbat index ec2a2e28db86a..96a828721eb06 100644 --- a/uki.sbat +++ b/uki.sbat @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -kernel-uki-virt.rhel,1,Red Hat,kernel-uki-virt,6.12.0-124.28.1.el10_1.x86_64,mailto:secalert@redhat.com -kernel-uki-virt.rocky,1,RESF,kernel-uki-virt,6.12.0-124.28.1.el10_1.x86_64,mailto:security@rockylinux.org +kernel-uki-virt.rhel,1,Red Hat,kernel-uki-virt,6.12.0-124.29.1.el10_1.x86_64,mailto:secalert@redhat.com +kernel-uki-virt.rocky,1,RESF,kernel-uki-virt,6.12.0-124.29.1.el10_1.x86_64,mailto:security@rockylinux.org