]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ksmbd: fix potential circular locking issue in smb2_set_ea()
authorNamjae Jeon <linkinjeon@kernel.org>
Sun, 21 Jan 2024 14:30:30 +0000 (23:30 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Feb 2024 07:54:26 +0000 (08:54 +0100)
[ Upstream commit 6fc0a265e1b932e5e97a038f99e29400a93baad0 ]

smb2_set_ea() can be called in parent inode lock range.
So add get_write argument to smb2_set_ea() not to call nested
mnt_want_write().

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ksmbd/smb2pdu.c

index 92ea42876e75c842cbb8203afd325b26fc8e2bf0..bae4df83004e07c2fec33dc0f870e7ea78dec7cb 100644 (file)
@@ -2323,11 +2323,12 @@ out:
  * @eabuf:     set info command buffer
  * @buf_len:   set info command buffer length
  * @path:      dentry path for get ea
+ * @get_write: get write access to a mount
  *
  * Return:     0 on success, otherwise error
  */
 static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len,
-                      const struct path *path)
+                      const struct path *path, bool get_write)
 {
        struct user_namespace *user_ns = mnt_user_ns(path->mnt);
        char *attr_name = NULL, *value;
@@ -3012,7 +3013,7 @@ int smb2_open(struct ksmbd_work *work)
 
                        rc = smb2_set_ea(&ea_buf->ea,
                                         le32_to_cpu(ea_buf->ccontext.DataLength),
-                                        &path);
+                                        &path, false);
                        if (rc == -EOPNOTSUPP)
                                rc = 0;
                        else if (rc)
@@ -5994,7 +5995,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
                        return -EINVAL;
 
                return smb2_set_ea((struct smb2_ea_info *)req->Buffer,
-                                  buf_len, &fp->filp->f_path);
+                                  buf_len, &fp->filp->f_path, true);
        }
        case FILE_POSITION_INFORMATION:
        {