diff options
| author | ZhangGuoDong <zhangguodong@kylinos.cn> | 2026-07-31 11:50:06 +0000 |
|---|---|---|
| committer | Namjae Jeon <linkinjeon@kernel.org> | 2026-08-17 15:00:58 +0900 |
| commit | db97f3763727d652112ae70038d4e17b3ce277bb (patch) | |
| tree | 3aec12afb247f33b1a91887e0d6fd769ef5734c6 | |
| parent | bef46b604732d83f8da29f782868de4d25bf972c (diff) | |
| download | linux-db97f3763727d652112ae70038d4e17b3ce277bb.tar.gz linux-db97f3763727d652112ae70038d4e17b3ce277bb.zip | |
smb/server: abort initialization when proc setup fails
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 <zhangguodong@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
| -rw-r--r-- | fs/smb/server/misc.h | 4 | ||||
| -rw-r--r-- | fs/smb/server/proc.c | 13 | ||||
| -rw-r--r-- | 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(); |
