]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: fail share config requests when path allocation fails
authorShuhao Fu <sfual@cse.ust.hk>
Wed, 29 Apr 2026 08:59:56 +0000 (16:59 +0800)
committerSteve French <stfrench@microsoft.com>
Sat, 2 May 2026 02:49:35 +0000 (21:49 -0500)
Non-pipe shares must have a duplicated backing path before they can be
published. share_config_request() currently calls kstrndup() for that
path, but if the allocation fails it leaves ret unchanged. If veto list
parsing succeeds and share->name exists, the partially built share is
still inserted into the global share table with share->path left NULL.

A later share-root SMB2 create uses tree_conn->share_conf->path as the
lookup root. If the share was published with path == NULL, that request
passes a NULL pathname into do_getname_kernel()/strlen() and can crash
the ksmbd worker.

Set ret = -ENOMEM when path duplication fails so the incomplete share is
destroyed before publication.

Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/server/mgmt/share_config.c

index 53f44ff4d376f3e4bc11fff5abfc6bebee90b41b..6f97f8d39657cd294d14faced62a0a9043f9d881 100644 (file)
@@ -167,7 +167,10 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
 
                share->path = kstrndup(ksmbd_share_config_path(resp), path_len,
                                      KSMBD_DEFAULT_GFP);
-               if (share->path) {
+               if (!share->path) {
+                       ret = -ENOMEM;
+               } else {
+                       ret = 0;
                        share->path_sz = strlen(share->path);
                        while (share->path_sz > 1 &&
                               share->path[share->path_sz - 1] == '/')
@@ -179,9 +182,10 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work,
                share->force_directory_mode = resp->force_directory_mode;
                share->force_uid = resp->force_uid;
                share->force_gid = resp->force_gid;
-               ret = parse_veto_list(share,
-                                     KSMBD_SHARE_CONFIG_VETO_LIST(resp),
-                                     resp->veto_list_sz);
+               if (!ret)
+                       ret = parse_veto_list(share,
+                                             KSMBD_SHARE_CONFIG_VETO_LIST(resp),
+                                             resp->veto_list_sz);
                if (!ret && share->path) {
                        if (__ksmbd_override_fsids(work, share)) {
                                kill_share(share);