[PATCH 4/6] smb/server: abort initialization when proc setup fails
ZhangGuoDong <[email protected]> Fri, 31 Jul 2026 11:50:06 +0000
| Newsgroups | org.kernel.vger.linux-cifs |
|---|---|
| Message-ID | <[email protected]> |
From: ZhangGuoDong <[email protected]> ksmbd_server_init() calls ksmbd_proc_init() before creating the remaining proc entries and server subsystems. ksmbd_proc_init() tears down partial state on a procfs or percpu_counter allocation failure, but returns void, so ksmbd_server_init() continues as if the counters were usable. Once userspace starts the server, server_ctrl_handle_init() calls ksmbd_proc_reset(), which reaches percpu_counter_set() with a NULL per-CPU counters pointer on SMP systems. The later ksmbd_proc_create() calls also receive a NULL parent and may create entries in the /proc root; ksmbd_proc_cleanup() cannot remove those entries because ksmbd_proc_fs is NULL. Fixes: b38f99c1217a ("ksmbd: add procfs interface for runtime monitoring and statistics") Signed-off-by: ZhangGuoDong <[email protected]> Reviewed-by: ChenXiaoSong <[email protected]> --- fs/smb/server/misc.h | 4 ++-- fs/smb/server/proc.c | 13 ++++++++----- fs/smb/server/server.c | 4 +++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/smb/server/misc.h b/fs/smb/server/misc.h index 680375a966c5..1faaddd0f5f7 100644 --- a/fs/smb/server/misc.h +++ b/fs/smb/server/misc.h @@ -43,7 +43,7 @@ struct ksmbd_const_name { const char *name; }; -void ksmbd_proc_init(void); +int ksmbd_proc_init(void); void ksmbd_proc_cleanup(void); void ksmbd_proc_reset(void); struct proc_dir_entry *ksmbd_proc_create(const char *name, @@ -56,7 +56,7 @@ void ksmbd_proc_show_flag_names(struct seq_file *m, const char *ksmbd_proc_const_name(const struct ksmbd_const_name *table, int count, unsigned int const_value); #else -static inline void ksmbd_proc_init(void) {} +static inline int ksmbd_proc_init(void) { return 0; } static inline void ksmbd_proc_cleanup(void) {} static inline void ksmbd_proc_reset(void) {} #endif diff --git a/fs/smb/server/proc.c b/fs/smb/server/proc.c index 1bf4e00dee34..826353ed0553 100644 --- a/fs/smb/server/proc.c +++ b/fs/smb/server/proc.c @@ -239,14 +239,14 @@ void ksmbd_proc_reset(void) percpu_counter_set(&ksmbd_counters.counters[i], 0); } -void ksmbd_proc_init(void) +int ksmbd_proc_init(void) { int i; - int retval; + int retval = -ENOMEM; ksmbd_proc_fs = proc_mkdir("fs/ksmbd", NULL); if (!ksmbd_proc_fs) - return; + return retval; if (!proc_mkdir_mode("sessions", 0400, ksmbd_proc_fs)) goto err_out; @@ -257,11 +257,14 @@ void ksmbd_proc_init(void) goto err_out; } - if (!ksmbd_proc_create("server", proc_show_ksmbd_stats, NULL)) + if (!ksmbd_proc_create("server", proc_show_ksmbd_stats, NULL)) { + retval = -ENOMEM; goto err_out; + } ksmbd_proc_reset(); - return; + return 0; err_out: ksmbd_proc_cleanup(); + return retval; } diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c index 18c20a669307..19630ac53235 100644 --- a/fs/smb/server/server.c +++ b/fs/smb/server/server.c @@ -620,7 +620,9 @@ static int __init ksmbd_server_init(void) return ret; } - ksmbd_proc_init(); + ret = ksmbd_proc_init(); + if (ret) + goto err_unregister; create_proc_sessions(); create_proc_shares(); -- 2.54.0