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: b38f99c121 ("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>
This commit is contained in:
ZhangGuoDong 2026-07-31 11:50:06 +00:00 committed by Namjae Jeon
parent bef46b6047
commit db97f37637
3 changed files with 13 additions and 8 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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();