public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	patches@lists.linux.dev, Namjae Jeon <linkinjeon@kernel.org>,
	Steve French <stfrench@microsoft.com>
Subject: [PATCH 5.15 087/159] ksmbd: fix racy issue from using ->d_parent and ->d_name
Date: Wed, 20 Dec 2023 17:09:12 +0100	[thread overview]
Message-ID: <20231220160935.429249358@linuxfoundation.org> (raw)
In-Reply-To: <20231220160931.251686445@linuxfoundation.org>

5.15-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Namjae Jeon <linkinjeon@kernel.org>

[ Upstream commit 74d7970febf7e9005375aeda0df821d2edffc9f7 ]

Al pointed out that ksmbd has racy issue from using ->d_parent and ->d_name
in ksmbd_vfs_unlink and smb2_vfs_rename(). and use new lock_rename_child()
to lock stable parent while underlying rename racy.
Introduce vfs_path_parent_lookup helper to avoid out of share access and
export vfs functions like the following ones to use
vfs_path_parent_lookup().
 - rename __lookup_hash() to lookup_one_qstr_excl().
 - export lookup_one_qstr_excl().
 - export getname_kernel() and putname().

vfs_path_parent_lookup() is used for parent lookup of destination file
using absolute pathname given from FILE_RENAME_INFORMATION request.

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    |  147 +++-------------
 fs/ksmbd/vfs.c        |  439 +++++++++++++++++++++-----------------------------
 fs/ksmbd/vfs.h        |   19 --
 fs/ksmbd/vfs_cache.c  |    5 
 fs/namei.c            |   57 +++++-
 include/linux/namei.h |    6 
 6 files changed, 285 insertions(+), 388 deletions(-)

--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -2456,7 +2456,7 @@ static int smb2_creat(struct ksmbd_work
 			return rc;
 	}
 
-	rc = ksmbd_vfs_kern_path(work, name, 0, path, 0);
+	rc = ksmbd_vfs_kern_path_locked(work, name, 0, path, 0);
 	if (rc) {
 		pr_err("cannot get linux path (%s), err = %d\n",
 		       name, rc);
@@ -2744,8 +2744,10 @@ int smb2_open(struct ksmbd_work *work)
 		goto err_out1;
 	}
 
-	rc = ksmbd_vfs_kern_path(work, name, LOOKUP_NO_SYMLINKS, &path, 1);
+	rc = ksmbd_vfs_kern_path_locked(work, name, LOOKUP_NO_SYMLINKS, &path, 1);
 	if (!rc) {
+		file_present = true;
+
 		if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE) {
 			/*
 			 * If file exists with under flags, return access
@@ -2754,7 +2756,6 @@ int smb2_open(struct ksmbd_work *work)
 			if (req->CreateDisposition == FILE_OVERWRITE_IF_LE ||
 			    req->CreateDisposition == FILE_OPEN_IF_LE) {
 				rc = -EACCES;
-				path_put(&path);
 				goto err_out;
 			}
 
@@ -2762,26 +2763,23 @@ int smb2_open(struct ksmbd_work *work)
 				ksmbd_debug(SMB,
 					    "User does not have write permission\n");
 				rc = -EACCES;
-				path_put(&path);
 				goto err_out;
 			}
 		} else if (d_is_symlink(path.dentry)) {
 			rc = -EACCES;
-			path_put(&path);
 			goto err_out;
 		}
-	}
 
-	if (rc) {
+		file_present = true;
+		user_ns = mnt_user_ns(path.mnt);
+	} else {
 		if (rc != -ENOENT)
 			goto err_out;
 		ksmbd_debug(SMB, "can not get linux path for %s, rc = %d\n",
 			    name, rc);
 		rc = 0;
-	} else {
-		file_present = true;
-		user_ns = mnt_user_ns(path.mnt);
 	}
+
 	if (stream_name) {
 		if (req->CreateOptions & FILE_DIRECTORY_FILE_LE) {
 			if (s_type == DATA_STREAM) {
@@ -2909,8 +2907,9 @@ int smb2_open(struct ksmbd_work *work)
 
 			if ((daccess & FILE_DELETE_LE) ||
 			    (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE)) {
-				rc = ksmbd_vfs_may_delete(user_ns,
-							  path.dentry);
+				rc = inode_permission(user_ns,
+						      d_inode(path.dentry->d_parent),
+						      MAY_EXEC | MAY_WRITE);
 				if (rc)
 					goto err_out;
 			}
@@ -3281,10 +3280,13 @@ int smb2_open(struct ksmbd_work *work)
 	}
 
 err_out:
-	if (file_present || created)
-		path_put(&path);
+	if (file_present || created) {
+		inode_unlock(d_inode(path.dentry->d_parent));
+		dput(path.dentry);
+	}
 	ksmbd_revert_fsids(work);
 err_out1:
+
 	if (rc) {
 		if (rc == -EINVAL)
 			rsp->hdr.Status = STATUS_INVALID_PARAMETER;
@@ -5426,44 +5428,19 @@ int smb2_echo(struct ksmbd_work *work)
 
 static int smb2_rename(struct ksmbd_work *work,
 		       struct ksmbd_file *fp,
-		       struct user_namespace *user_ns,
 		       struct smb2_file_rename_info *file_info,
 		       struct nls_table *local_nls)
 {
 	struct ksmbd_share_config *share = fp->tcon->share_conf;
-	char *new_name = NULL, *abs_oldname = NULL, *old_name = NULL;
-	char *pathname = NULL;
-	struct path path;
-	bool file_present = true;
-	int rc;
+	char *new_name = NULL;
+	int rc, flags = 0;
 
 	ksmbd_debug(SMB, "setting FILE_RENAME_INFO\n");
-	pathname = kmalloc(PATH_MAX, GFP_KERNEL);
-	if (!pathname)
-		return -ENOMEM;
-
-	abs_oldname = file_path(fp->filp, pathname, PATH_MAX);
-	if (IS_ERR(abs_oldname)) {
-		rc = -EINVAL;
-		goto out;
-	}
-	old_name = strrchr(abs_oldname, '/');
-	if (old_name && old_name[1] != '\0') {
-		old_name++;
-	} else {
-		ksmbd_debug(SMB, "can't get last component in path %s\n",
-			    abs_oldname);
-		rc = -ENOENT;
-		goto out;
-	}
-
 	new_name = smb2_get_name(file_info->FileName,
 				 le32_to_cpu(file_info->FileNameLength),
 				 local_nls);
-	if (IS_ERR(new_name)) {
-		rc = PTR_ERR(new_name);
-		goto out;
-	}
+	if (IS_ERR(new_name))
+		return PTR_ERR(new_name);
 
 	if (strchr(new_name, ':')) {
 		int s_type;
@@ -5489,7 +5466,7 @@ static int smb2_rename(struct ksmbd_work
 		if (rc)
 			goto out;
 
-		rc = ksmbd_vfs_setxattr(user_ns,
+		rc = ksmbd_vfs_setxattr(file_mnt_user_ns(fp->filp),
 					fp->filp->f_path.dentry,
 					xattr_stream_name,
 					NULL, 0, 0);
@@ -5504,47 +5481,18 @@ static int smb2_rename(struct ksmbd_work
 	}
 
 	ksmbd_debug(SMB, "new name %s\n", new_name);
-	rc = ksmbd_vfs_kern_path(work, new_name, LOOKUP_NO_SYMLINKS, &path, 1);
-	if (rc) {
-		if (rc != -ENOENT)
-			goto out;
-		file_present = false;
-	} else {
-		path_put(&path);
-	}
-
 	if (ksmbd_share_veto_filename(share, new_name)) {
 		rc = -ENOENT;
 		ksmbd_debug(SMB, "Can't rename vetoed file: %s\n", new_name);
 		goto out;
 	}
 
-	if (file_info->ReplaceIfExists) {
-		if (file_present) {
-			rc = ksmbd_vfs_remove_file(work, new_name);
-			if (rc) {
-				if (rc != -ENOTEMPTY)
-					rc = -EINVAL;
-				ksmbd_debug(SMB, "cannot delete %s, rc %d\n",
-					    new_name, rc);
-				goto out;
-			}
-		}
-	} else {
-		if (file_present &&
-		    strncmp(old_name, path.dentry->d_name.name, strlen(old_name))) {
-			rc = -EEXIST;
-			ksmbd_debug(SMB,
-				    "cannot rename already existing file\n");
-			goto out;
-		}
-	}
+	if (!file_info->ReplaceIfExists)
+		flags = RENAME_NOREPLACE;
 
-	rc = ksmbd_vfs_fp_rename(work, fp, new_name);
+	rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags);
 out:
-	kfree(pathname);
-	if (!IS_ERR(new_name))
-		kfree(new_name);
+	kfree(new_name);
 	return rc;
 }
 
@@ -5584,18 +5532,17 @@ static int smb2_create_link(struct ksmbd
 	}
 
 	ksmbd_debug(SMB, "target name is %s\n", target_name);
-	rc = ksmbd_vfs_kern_path(work, link_name, LOOKUP_NO_SYMLINKS, &path, 0);
+	rc = ksmbd_vfs_kern_path_locked(work, link_name, LOOKUP_NO_SYMLINKS,
+					&path, 0);
 	if (rc) {
 		if (rc != -ENOENT)
 			goto out;
 		file_present = false;
-	} else {
-		path_put(&path);
 	}
 
 	if (file_info->ReplaceIfExists) {
 		if (file_present) {
-			rc = ksmbd_vfs_remove_file(work, link_name);
+			rc = ksmbd_vfs_remove_file(work, &path);
 			if (rc) {
 				rc = -EINVAL;
 				ksmbd_debug(SMB, "cannot delete %s\n",
@@ -5615,6 +5562,10 @@ static int smb2_create_link(struct ksmbd
 	if (rc)
 		rc = -EINVAL;
 out:
+	if (file_present) {
+		inode_unlock(d_inode(path.dentry->d_parent));
+		path_put(&path);
+	}
 	if (!IS_ERR(link_name))
 		kfree(link_name);
 	kfree(pathname);
@@ -5792,12 +5743,6 @@ static int set_rename_info(struct ksmbd_
 			   struct smb2_file_rename_info *rename_info,
 			   unsigned int buf_len)
 {
-	struct user_namespace *user_ns;
-	struct ksmbd_file *parent_fp;
-	struct dentry *parent;
-	struct dentry *dentry = fp->filp->f_path.dentry;
-	int ret;
-
 	if (!(fp->daccess & FILE_DELETE_LE)) {
 		pr_err("no right to delete : 0x%x\n", fp->daccess);
 		return -EACCES;
@@ -5807,32 +5752,10 @@ static int set_rename_info(struct ksmbd_
 			le32_to_cpu(rename_info->FileNameLength))
 		return -EINVAL;
 
-	user_ns = file_mnt_user_ns(fp->filp);
-	if (ksmbd_stream_fd(fp))
-		goto next;
+	if (!le32_to_cpu(rename_info->FileNameLength))
+		return -EINVAL;
 
-	parent = dget_parent(dentry);
-	ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
-	if (ret) {
-		dput(parent);
-		return ret;
-	}
-
-	parent_fp = ksmbd_lookup_fd_inode(d_inode(parent));
-	inode_unlock(d_inode(parent));
-	dput(parent);
-
-	if (parent_fp) {
-		if (parent_fp->daccess & FILE_DELETE_LE) {
-			pr_err("parent dir is opened with delete access\n");
-			ksmbd_fd_put(work, parent_fp);
-			return -ESHARE;
-		}
-		ksmbd_fd_put(work, parent_fp);
-	}
-next:
-	return smb2_rename(work, fp, user_ns, rename_info,
-			   work->conn->local_nls);
+	return smb2_rename(work, fp, rename_info, work->conn->local_nls);
 }
 
 static int set_file_disposition_info(struct ksmbd_file *fp,
--- a/fs/ksmbd/vfs.c
+++ b/fs/ksmbd/vfs.c
@@ -18,6 +18,7 @@
 #include <linux/vmalloc.h>
 #include <linux/sched/xacct.h>
 #include <linux/crc32c.h>
+#include <linux/namei.h>
 
 #include "glob.h"
 #include "oplock.h"
@@ -35,19 +36,6 @@
 #include "mgmt/user_session.h"
 #include "mgmt/user_config.h"
 
-static char *extract_last_component(char *path)
-{
-	char *p = strrchr(path, '/');
-
-	if (p && p[1] != '\0') {
-		*p = '\0';
-		p++;
-	} else {
-		p = NULL;
-	}
-	return p;
-}
-
 static void ksmbd_vfs_inherit_owner(struct ksmbd_work *work,
 				    struct inode *parent_inode,
 				    struct inode *inode)
@@ -61,65 +49,77 @@ static void ksmbd_vfs_inherit_owner(stru
 
 /**
  * ksmbd_vfs_lock_parent() - lock parent dentry if it is stable
- *
- * the parent dentry got by dget_parent or @parent could be
- * unstable, we try to lock a parent inode and lookup the
- * child dentry again.
- *
- * the reference count of @parent isn't incremented.
  */
-int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent,
-			  struct dentry *child)
+int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child)
 {
-	struct dentry *dentry;
-	int ret = 0;
-
 	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
-	dentry = lookup_one(user_ns, child->d_name.name, parent,
-			    child->d_name.len);
-	if (IS_ERR(dentry)) {
-		ret = PTR_ERR(dentry);
-		goto out_err;
-	}
-
-	if (dentry != child) {
-		ret = -ESTALE;
-		dput(dentry);
-		goto out_err;
+	if (child->d_parent != parent) {
+		inode_unlock(d_inode(parent));
+		return -ENOENT;
 	}
 
-	dput(dentry);
 	return 0;
-out_err:
-	inode_unlock(d_inode(parent));
-	return ret;
 }
 
-int ksmbd_vfs_may_delete(struct user_namespace *user_ns,
-			 struct dentry *dentry)
-{
-	struct dentry *parent;
-	int ret;
+static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
+					char *pathname, unsigned int flags,
+					struct path *path)
+{
+	struct qstr last;
+	struct filename *filename;
+	struct path *root_share_path = &share_conf->vfs_path;
+	int err, type;
+	struct path parent_path;
+	struct dentry *d;
+
+	if (pathname[0] == '\0') {
+		pathname = share_conf->path;
+		root_share_path = NULL;
+	} else {
+		flags |= LOOKUP_BENEATH;
+	}
 
-	parent = dget_parent(dentry);
-	ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
-	if (ret) {
-		dput(parent);
-		return ret;
+	filename = getname_kernel(pathname);
+	if (IS_ERR(filename))
+		return PTR_ERR(filename);
+
+	err = vfs_path_parent_lookup(filename, flags,
+				     &parent_path, &last, &type,
+				     root_share_path);
+	putname(filename);
+	if (err)
+		return err;
+
+	if (unlikely(type != LAST_NORM)) {
+		path_put(&parent_path);
+		return -ENOENT;
 	}
 
-	ret = inode_permission(user_ns, d_inode(parent),
-			       MAY_EXEC | MAY_WRITE);
+	inode_lock_nested(parent_path.dentry->d_inode, I_MUTEX_PARENT);
+	d = lookup_one_qstr_excl(&last, parent_path.dentry, 0);
+	if (IS_ERR(d))
+		goto err_out;
 
-	inode_unlock(d_inode(parent));
-	dput(parent);
-	return ret;
+	if (d_is_negative(d)) {
+		dput(d);
+		goto err_out;
+	}
+
+	path->dentry = d;
+	path->mnt = share_conf->vfs_path.mnt;
+	path_put(&parent_path);
+
+	return 0;
+
+err_out:
+	inode_unlock(parent_path.dentry->d_inode);
+	path_put(&parent_path);
+	return -ENOENT;
 }
 
 int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
 				   struct dentry *dentry, __le32 *daccess)
 {
-	struct dentry *parent;
 	int ret = 0;
 
 	*daccess = cpu_to_le32(FILE_READ_ATTRIBUTES | READ_CONTROL);
@@ -136,18 +136,9 @@ int ksmbd_vfs_query_maximal_access(struc
 	if (!inode_permission(user_ns, d_inode(dentry), MAY_OPEN | MAY_EXEC))
 		*daccess |= FILE_EXECUTE_LE;
 
-	parent = dget_parent(dentry);
-	ret = ksmbd_vfs_lock_parent(user_ns, parent, dentry);
-	if (ret) {
-		dput(parent);
-		return ret;
-	}
-
-	if (!inode_permission(user_ns, d_inode(parent), MAY_EXEC | MAY_WRITE))
+	if (!inode_permission(user_ns, d_inode(dentry->d_parent), MAY_EXEC | MAY_WRITE))
 		*daccess |= FILE_DELETE_LE;
 
-	inode_unlock(d_inode(parent));
-	dput(parent);
 	return ret;
 }
 
@@ -580,54 +571,32 @@ int ksmbd_vfs_fsync(struct ksmbd_work *w
  *
  * Return:	0 on success, otherwise error
  */
-int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name)
+int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
 {
 	struct user_namespace *user_ns;
-	struct path path;
-	struct dentry *parent;
+	struct dentry *parent = path->dentry->d_parent;
 	int err;
 
 	if (ksmbd_override_fsids(work))
 		return -ENOMEM;
 
-	err = ksmbd_vfs_kern_path(work, name, LOOKUP_NO_SYMLINKS, &path, false);
-	if (err) {
-		ksmbd_debug(VFS, "can't get %s, err %d\n", name, err);
-		ksmbd_revert_fsids(work);
-		return err;
-	}
-
-	user_ns = mnt_user_ns(path.mnt);
-	parent = dget_parent(path.dentry);
-	err = ksmbd_vfs_lock_parent(user_ns, parent, path.dentry);
-	if (err) {
-		dput(parent);
-		path_put(&path);
-		ksmbd_revert_fsids(work);
-		return err;
-	}
-
-	if (!d_inode(path.dentry)->i_nlink) {
+	if (!d_inode(path->dentry)->i_nlink) {
 		err = -ENOENT;
 		goto out_err;
 	}
 
-	if (S_ISDIR(d_inode(path.dentry)->i_mode)) {
-		err = vfs_rmdir(user_ns, d_inode(parent), path.dentry);
+	user_ns = mnt_user_ns(path->mnt);
+	if (S_ISDIR(d_inode(path->dentry)->i_mode)) {
+		err = vfs_rmdir(user_ns, d_inode(parent), path->dentry);
 		if (err && err != -ENOTEMPTY)
-			ksmbd_debug(VFS, "%s: rmdir failed, err %d\n", name,
-				    err);
+			ksmbd_debug(VFS, "rmdir failed, err %d\n", err);
 	} else {
-		err = vfs_unlink(user_ns, d_inode(parent), path.dentry, NULL);
+		err = vfs_unlink(user_ns, d_inode(parent), path->dentry, NULL);
 		if (err)
-			ksmbd_debug(VFS, "%s: unlink failed, err %d\n", name,
-				    err);
+			ksmbd_debug(VFS, "unlink failed, err %d\n", err);
 	}
 
 out_err:
-	inode_unlock(d_inode(parent));
-	dput(parent);
-	path_put(&path);
 	ksmbd_revert_fsids(work);
 	return err;
 }
@@ -686,149 +655,114 @@ out1:
 	return err;
 }
 
-static int ksmbd_validate_entry_in_use(struct dentry *src_dent)
+int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
+		     char *newname, int flags)
 {
-	struct dentry *dst_dent;
-
-	spin_lock(&src_dent->d_lock);
-	list_for_each_entry(dst_dent, &src_dent->d_subdirs, d_child) {
-		struct ksmbd_file *child_fp;
+	struct dentry *old_parent, *new_dentry, *trap;
+	struct dentry *old_child = old_path->dentry;
+	struct path new_path;
+	struct qstr new_last;
+	struct renamedata rd;
+	struct filename *to;
+	struct ksmbd_share_config *share_conf = work->tcon->share_conf;
+	struct ksmbd_file *parent_fp;
+	int new_type;
+	int err, lookup_flags = LOOKUP_NO_SYMLINKS;
 
-		if (d_really_is_negative(dst_dent))
-			continue;
+	if (ksmbd_override_fsids(work))
+		return -ENOMEM;
 
-		child_fp = ksmbd_lookup_fd_inode(d_inode(dst_dent));
-		if (child_fp) {
-			spin_unlock(&src_dent->d_lock);
-			ksmbd_debug(VFS, "Forbid rename, sub file/dir is in use\n");
-			return -EACCES;
-		}
+	to = getname_kernel(newname);
+	if (IS_ERR(to)) {
+		err = PTR_ERR(to);
+		goto revert_fsids;
 	}
-	spin_unlock(&src_dent->d_lock);
 
-	return 0;
-}
-
-static int __ksmbd_vfs_rename(struct ksmbd_work *work,
-			      struct user_namespace *src_user_ns,
-			      struct dentry *src_dent_parent,
-			      struct dentry *src_dent,
-			      struct user_namespace *dst_user_ns,
-			      struct dentry *dst_dent_parent,
-			      struct dentry *trap_dent,
-			      char *dst_name)
-{
-	struct dentry *dst_dent;
-	int err;
+retry:
+	err = vfs_path_parent_lookup(to, lookup_flags | LOOKUP_BENEATH,
+				     &new_path, &new_last, &new_type,
+				     &share_conf->vfs_path);
+	if (err)
+		goto out1;
 
-	if (!work->tcon->posix_extensions) {
-		err = ksmbd_validate_entry_in_use(src_dent);
-		if (err)
-			return err;
+	if (old_path->mnt != new_path.mnt) {
+		err = -EXDEV;
+		goto out2;
 	}
 
-	if (d_really_is_negative(src_dent_parent))
-		return -ENOENT;
-	if (d_really_is_negative(dst_dent_parent))
-		return -ENOENT;
-	if (d_really_is_negative(src_dent))
-		return -ENOENT;
-	if (src_dent == trap_dent)
-		return -EINVAL;
+	trap = lock_rename_child(old_child, new_path.dentry);
 
-	if (ksmbd_override_fsids(work))
-		return -ENOMEM;
+	old_parent = dget(old_child->d_parent);
+	if (d_unhashed(old_child)) {
+		err = -EINVAL;
+		goto out3;
+	}
 
-	dst_dent = lookup_one(dst_user_ns, dst_name, dst_dent_parent,
-			      strlen(dst_name));
-	err = PTR_ERR(dst_dent);
-	if (IS_ERR(dst_dent)) {
-		pr_err("lookup failed %s [%d]\n", dst_name, err);
-		goto out;
+	parent_fp = ksmbd_lookup_fd_inode(d_inode(old_child->d_parent));
+	if (parent_fp) {
+		if (parent_fp->daccess & FILE_DELETE_LE) {
+			pr_err("parent dir is opened with delete access\n");
+			err = -ESHARE;
+			ksmbd_fd_put(work, parent_fp);
+			goto out3;
+		}
+		ksmbd_fd_put(work, parent_fp);
 	}
 
-	err = -ENOTEMPTY;
-	if (dst_dent != trap_dent && !d_really_is_positive(dst_dent)) {
-		struct renamedata rd = {
-			.old_mnt_userns	= src_user_ns,
-			.old_dir	= d_inode(src_dent_parent),
-			.old_dentry	= src_dent,
-			.new_mnt_userns	= dst_user_ns,
-			.new_dir	= d_inode(dst_dent_parent),
-			.new_dentry	= dst_dent,
-		};
-		err = vfs_rename(&rd);
+	new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry,
+					  lookup_flags | LOOKUP_RENAME_TARGET);
+	if (IS_ERR(new_dentry)) {
+		err = PTR_ERR(new_dentry);
+		goto out3;
 	}
-	if (err)
-		pr_err("vfs_rename failed err %d\n", err);
-	if (dst_dent)
-		dput(dst_dent);
-out:
-	ksmbd_revert_fsids(work);
-	return err;
-}
 
-int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
-			char *newname)
-{
-	struct user_namespace *user_ns;
-	struct path dst_path;
-	struct dentry *src_dent_parent, *dst_dent_parent;
-	struct dentry *src_dent, *trap_dent, *src_child;
-	char *dst_name;
-	int err;
+	if (d_is_symlink(new_dentry)) {
+		err = -EACCES;
+		goto out4;
+	}
 
-	dst_name = extract_last_component(newname);
-	if (!dst_name) {
-		dst_name = newname;
-		newname = "";
+	if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry)) {
+		err = -EEXIST;
+		goto out4;
 	}
 
-	src_dent_parent = dget_parent(fp->filp->f_path.dentry);
-	src_dent = fp->filp->f_path.dentry;
-
-	err = ksmbd_vfs_kern_path(work, newname,
-				  LOOKUP_NO_SYMLINKS | LOOKUP_DIRECTORY,
-				  &dst_path, false);
-	if (err) {
-		ksmbd_debug(VFS, "Cannot get path for %s [%d]\n", newname, err);
-		goto out;
+	if (old_child == trap) {
+		err = -EINVAL;
+		goto out4;
 	}
-	dst_dent_parent = dst_path.dentry;
 
-	trap_dent = lock_rename(src_dent_parent, dst_dent_parent);
-	dget(src_dent);
-	dget(dst_dent_parent);
-	user_ns = file_mnt_user_ns(fp->filp);
-	src_child = lookup_one(user_ns, src_dent->d_name.name, src_dent_parent,
-			       src_dent->d_name.len);
-	if (IS_ERR(src_child)) {
-		err = PTR_ERR(src_child);
-		goto out_lock;
-	}
-
-	if (src_child != src_dent) {
-		err = -ESTALE;
-		dput(src_child);
-		goto out_lock;
-	}
-	dput(src_child);
-
-	err = __ksmbd_vfs_rename(work,
-				 user_ns,
-				 src_dent_parent,
-				 src_dent,
-				 mnt_user_ns(dst_path.mnt),
-				 dst_dent_parent,
-				 trap_dent,
-				 dst_name);
-out_lock:
-	dput(src_dent);
-	dput(dst_dent_parent);
-	unlock_rename(src_dent_parent, dst_dent_parent);
-	path_put(&dst_path);
-out:
-	dput(src_dent_parent);
+	if (new_dentry == trap) {
+		err = -ENOTEMPTY;
+		goto out4;
+	}
+
+	rd.old_mnt_userns	= mnt_user_ns(old_path->mnt),
+	rd.old_dir		= d_inode(old_parent),
+	rd.old_dentry		= old_child,
+	rd.new_mnt_userns	= mnt_user_ns(new_path.mnt),
+	rd.new_dir		= new_path.dentry->d_inode,
+	rd.new_dentry		= new_dentry,
+	rd.flags		= flags,
+	err = vfs_rename(&rd);
+	if (err)
+		ksmbd_debug(VFS, "vfs_rename failed err %d\n", err);
+
+out4:
+	dput(new_dentry);
+out3:
+	dput(old_parent);
+	unlock_rename(old_parent, new_path.dentry);
+out2:
+	path_put(&new_path);
+
+	if (retry_estale(err, lookup_flags)) {
+		lookup_flags |= LOOKUP_REVAL;
+		goto retry;
+	}
+out1:
+	putname(to);
+revert_fsids:
+	ksmbd_revert_fsids(work);
 	return err;
 }
 
@@ -1079,14 +1013,16 @@ int ksmbd_vfs_remove_xattr(struct user_n
 	return vfs_removexattr(user_ns, dentry, attr_name);
 }
 
-int ksmbd_vfs_unlink(struct user_namespace *user_ns,
-		     struct dentry *dir, struct dentry *dentry)
+int ksmbd_vfs_unlink(struct file *filp)
 {
 	int err = 0;
+	struct dentry *dir, *dentry = filp->f_path.dentry;
+	struct user_namespace *user_ns = file_mnt_user_ns(filp);
 
-	err = ksmbd_vfs_lock_parent(user_ns, dir, dentry);
+	dir = dget_parent(dentry);
+	err = ksmbd_vfs_lock_parent(dir, dentry);
 	if (err)
-		return err;
+		goto out;
 	dget(dentry);
 
 	if (S_ISDIR(d_inode(dentry)->i_mode))
@@ -1098,6 +1034,8 @@ int ksmbd_vfs_unlink(struct user_namespa
 	inode_unlock(d_inode(dir));
 	if (err)
 		ksmbd_debug(VFS, "failed to delete, err %d\n", err);
+out:
+	dput(dir);
 
 	return err;
 }
@@ -1202,7 +1140,7 @@ static int ksmbd_vfs_lookup_in_dir(const
 }
 
 /**
- * ksmbd_vfs_kern_path() - lookup a file and get path info
+ * ksmbd_vfs_kern_path_locked() - lookup a file and get path info
  * @name:	file path that is relative to share
  * @flags:	lookup flags
  * @path:	if lookup succeed, return path info
@@ -1210,24 +1148,20 @@ static int ksmbd_vfs_lookup_in_dir(const
  *
  * Return:	0 on success, otherwise error
  */
-int ksmbd_vfs_kern_path(struct ksmbd_work *work, char *name,
-			unsigned int flags, struct path *path, bool caseless)
+int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
+			       unsigned int flags, struct path *path,
+			       bool caseless)
 {
 	struct ksmbd_share_config *share_conf = work->tcon->share_conf;
 	int err;
+	struct path parent_path;
 
-	flags |= LOOKUP_BENEATH;
-	err = vfs_path_lookup(share_conf->vfs_path.dentry,
-			      share_conf->vfs_path.mnt,
-			      name,
-			      flags,
-			      path);
+	err = ksmbd_vfs_path_lookup_locked(share_conf, name, flags, path);
 	if (!err)
-		return 0;
+		return err;
 
 	if (caseless) {
 		char *filepath;
-		struct path parent;
 		size_t path_len, remain_len;
 
 		filepath = kstrdup(name, GFP_KERNEL);
@@ -1237,10 +1171,10 @@ int ksmbd_vfs_kern_path(struct ksmbd_wor
 		path_len = strlen(filepath);
 		remain_len = path_len;
 
-		parent = share_conf->vfs_path;
-		path_get(&parent);
+		parent_path = share_conf->vfs_path;
+		path_get(&parent_path);
 
-		while (d_can_lookup(parent.dentry)) {
+		while (d_can_lookup(parent_path.dentry)) {
 			char *filename = filepath + path_len - remain_len;
 			char *next = strchrnul(filename, '/');
 			size_t filename_len = next - filename;
@@ -1249,12 +1183,11 @@ int ksmbd_vfs_kern_path(struct ksmbd_wor
 			if (filename_len == 0)
 				break;
 
-			err = ksmbd_vfs_lookup_in_dir(&parent, filename,
+			err = ksmbd_vfs_lookup_in_dir(&parent_path, filename,
 						      filename_len,
 						      work->conn->um);
-			path_put(&parent);
 			if (err)
-				goto out;
+				goto out2;
 
 			next[0] = '\0';
 
@@ -1262,23 +1195,31 @@ int ksmbd_vfs_kern_path(struct ksmbd_wor
 					      share_conf->vfs_path.mnt,
 					      filepath,
 					      flags,
-					      &parent);
+					      path);
 			if (err)
-				goto out;
-			else if (is_last) {
-				*path = parent;
-				goto out;
-			}
+				goto out2;
+			else if (is_last)
+				goto out1;
+			path_put(&parent_path);
+			parent_path = *path;
 
 			next[0] = '/';
 			remain_len -= filename_len + 1;
 		}
 
-		path_put(&parent);
 		err = -EINVAL;
-out:
+out2:
+		path_put(&parent_path);
+out1:
 		kfree(filepath);
 	}
+
+	if (!err) {
+		err = ksmbd_vfs_lock_parent(parent_path.dentry, path->dentry);
+		if (err)
+			dput(path->dentry);
+		path_put(&parent_path);
+	}
 	return err;
 }
 
--- a/fs/ksmbd/vfs.h
+++ b/fs/ksmbd/vfs.h
@@ -110,9 +110,7 @@ struct ksmbd_kstat {
 	__le32			file_attributes;
 };
 
-int ksmbd_vfs_lock_parent(struct user_namespace *user_ns, struct dentry *parent,
-			  struct dentry *child);
-int ksmbd_vfs_may_delete(struct user_namespace *user_ns, struct dentry *dentry);
+int ksmbd_vfs_lock_parent(struct dentry *parent, struct dentry *child);
 int ksmbd_vfs_query_maximal_access(struct user_namespace *user_ns,
 				   struct dentry *dentry, __le32 *daccess);
 int ksmbd_vfs_create(struct ksmbd_work *work, const char *name, umode_t mode);
@@ -123,12 +121,12 @@ int ksmbd_vfs_write(struct ksmbd_work *w
 		    char *buf, size_t count, loff_t *pos, bool sync,
 		    ssize_t *written);
 int ksmbd_vfs_fsync(struct ksmbd_work *work, u64 fid, u64 p_id);
-int ksmbd_vfs_remove_file(struct ksmbd_work *work, char *name);
+int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path);
 int ksmbd_vfs_link(struct ksmbd_work *work,
 		   const char *oldname, const char *newname);
 int ksmbd_vfs_getattr(const struct path *path, struct kstat *stat);
-int ksmbd_vfs_fp_rename(struct ksmbd_work *work, struct ksmbd_file *fp,
-			char *newname);
+int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
+		     char *newname, int flags);
 int ksmbd_vfs_truncate(struct ksmbd_work *work,
 		       struct ksmbd_file *fp, loff_t size);
 struct srv_copychunk;
@@ -155,9 +153,9 @@ int ksmbd_vfs_xattr_stream_name(char *st
 				size_t *xattr_stream_name_size, int s_type);
 int ksmbd_vfs_remove_xattr(struct user_namespace *user_ns,
 			   struct dentry *dentry, char *attr_name);
-int ksmbd_vfs_kern_path(struct ksmbd_work *work,
-			char *name, unsigned int flags, struct path *path,
-			bool caseless);
+int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
+			       unsigned int flags, struct path *path,
+			       bool caseless);
 struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
 					  const char *name,
 					  unsigned int flags,
@@ -170,8 +168,7 @@ struct file_allocated_range_buffer;
 int ksmbd_vfs_fqar_lseek(struct ksmbd_file *fp, loff_t start, loff_t length,
 			 struct file_allocated_range_buffer *ranges,
 			 unsigned int in_count, unsigned int *out_count);
-int ksmbd_vfs_unlink(struct user_namespace *user_ns,
-		     struct dentry *dir, struct dentry *dentry);
+int ksmbd_vfs_unlink(struct file *filp);
 void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat);
 int ksmbd_vfs_fill_dentry_attrs(struct ksmbd_work *work,
 				struct user_namespace *user_ns,
--- a/fs/ksmbd/vfs_cache.c
+++ b/fs/ksmbd/vfs_cache.c
@@ -243,7 +243,6 @@ void ksmbd_release_inode_hash(void)
 
 static void __ksmbd_inode_close(struct ksmbd_file *fp)
 {
-	struct dentry *dir, *dentry;
 	struct ksmbd_inode *ci = fp->f_ci;
 	int err;
 	struct file *filp;
@@ -262,11 +261,9 @@ static void __ksmbd_inode_close(struct k
 	if (atomic_dec_and_test(&ci->m_count)) {
 		write_lock(&ci->m_lock);
 		if (ci->m_flags & (S_DEL_ON_CLS | S_DEL_PENDING)) {
-			dentry = filp->f_path.dentry;
-			dir = dentry->d_parent;
 			ci->m_flags &= ~(S_DEL_ON_CLS | S_DEL_PENDING);
 			write_unlock(&ci->m_lock);
-			ksmbd_vfs_unlink(file_mnt_user_ns(filp), dir, dentry);
+			ksmbd_vfs_unlink(filp);
 			write_lock(&ci->m_lock);
 		}
 		write_unlock(&ci->m_lock);
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -252,6 +252,7 @@ getname_kernel(const char * filename)
 
 	return result;
 }
+EXPORT_SYMBOL(getname_kernel);
 
 void putname(struct filename *name)
 {
@@ -269,6 +270,7 @@ void putname(struct filename *name)
 	} else
 		__putname(name);
 }
+EXPORT_SYMBOL(putname);
 
 /**
  * check_acl - perform ACL permission checking
@@ -1539,8 +1541,9 @@ static struct dentry *lookup_dcache(cons
  * when directory is guaranteed to have no in-lookup children
  * at all.
  */
-static struct dentry *__lookup_hash(const struct qstr *name,
-		struct dentry *base, unsigned int flags)
+struct dentry *lookup_one_qstr_excl(const struct qstr *name,
+				    struct dentry *base,
+				    unsigned int flags)
 {
 	struct dentry *dentry = lookup_dcache(name, base, flags);
 	struct dentry *old;
@@ -1564,6 +1567,7 @@ static struct dentry *__lookup_hash(cons
 	}
 	return dentry;
 }
+EXPORT_SYMBOL(lookup_one_qstr_excl);
 
 static struct dentry *lookup_fast(struct nameidata *nd,
 				  struct inode **inode,
@@ -2508,16 +2512,17 @@ static int path_parentat(struct nameidat
 }
 
 /* Note: this does not consume "name" */
-static int filename_parentat(int dfd, struct filename *name,
-			     unsigned int flags, struct path *parent,
-			     struct qstr *last, int *type)
+static int __filename_parentat(int dfd, struct filename *name,
+			       unsigned int flags, struct path *parent,
+			       struct qstr *last, int *type,
+			       const struct path *root)
 {
 	int retval;
 	struct nameidata nd;
 
 	if (IS_ERR(name))
 		return PTR_ERR(name);
-	set_nameidata(&nd, dfd, name, NULL);
+	set_nameidata(&nd, dfd, name, root);
 	retval = path_parentat(&nd, flags | LOOKUP_RCU, parent);
 	if (unlikely(retval == -ECHILD))
 		retval = path_parentat(&nd, flags, parent);
@@ -2532,6 +2537,13 @@ static int filename_parentat(int dfd, st
 	return retval;
 }
 
+static int filename_parentat(int dfd, struct filename *name,
+			     unsigned int flags, struct path *parent,
+			     struct qstr *last, int *type)
+{
+	return __filename_parentat(dfd, name, flags, parent, last, type, NULL);
+}
+
 /* does lookup, returns the object with parent locked */
 static struct dentry *__kern_path_locked(struct filename *name, struct path *path)
 {
@@ -2547,7 +2559,7 @@ static struct dentry *__kern_path_locked
 		return ERR_PTR(-EINVAL);
 	}
 	inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
-	d = __lookup_hash(&last, path->dentry, 0);
+	d = lookup_one_qstr_excl(&last, path->dentry, 0);
 	if (IS_ERR(d)) {
 		inode_unlock(path->dentry->d_inode);
 		path_put(path);
@@ -2576,6 +2588,24 @@ int kern_path(const char *name, unsigned
 EXPORT_SYMBOL(kern_path);
 
 /**
+ * vfs_path_parent_lookup - lookup a parent path relative to a dentry-vfsmount pair
+ * @filename: filename structure
+ * @flags: lookup flags
+ * @parent: pointer to struct path to fill
+ * @last: last component
+ * @type: type of the last component
+ * @root: pointer to struct path of the base directory
+ */
+int vfs_path_parent_lookup(struct filename *filename, unsigned int flags,
+			   struct path *parent, struct qstr *last, int *type,
+			   const struct path *root)
+{
+	return  __filename_parentat(AT_FDCWD, filename, flags, parent, last,
+				    type, root);
+}
+EXPORT_SYMBOL(vfs_path_parent_lookup);
+
+/**
  * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
  * @dentry:  pointer to dentry of the base directory
  * @mnt: pointer to vfs mount of the base directory
@@ -3809,7 +3839,8 @@ static struct dentry *filename_create(in
 	if (last.name[last.len] && !want_dir)
 		create_flags = 0;
 	inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
-	dentry = __lookup_hash(&last, path->dentry, reval_flag | create_flags);
+	dentry = lookup_one_qstr_excl(&last, path->dentry,
+				      reval_flag | create_flags);
 	if (IS_ERR(dentry))
 		goto unlock;
 
@@ -4170,7 +4201,7 @@ retry:
 		goto exit2;
 
 	inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
-	dentry = __lookup_hash(&last, path.dentry, lookup_flags);
+	dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto exit3;
@@ -4304,7 +4335,7 @@ retry:
 		goto exit2;
 retry_deleg:
 	inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
-	dentry = __lookup_hash(&last, path.dentry, lookup_flags);
+	dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags);
 	error = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
 		struct user_namespace *mnt_userns;
@@ -4878,7 +4909,8 @@ retry:
 retry_deleg:
 	trap = lock_rename(new_path.dentry, old_path.dentry);
 
-	old_dentry = __lookup_hash(&old_last, old_path.dentry, lookup_flags);
+	old_dentry = lookup_one_qstr_excl(&old_last, old_path.dentry,
+					  lookup_flags);
 	error = PTR_ERR(old_dentry);
 	if (IS_ERR(old_dentry))
 		goto exit3;
@@ -4886,7 +4918,8 @@ retry_deleg:
 	error = -ENOENT;
 	if (d_is_negative(old_dentry))
 		goto exit4;
-	new_dentry = __lookup_hash(&new_last, new_path.dentry, lookup_flags | target_flags);
+	new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry,
+					  lookup_flags | target_flags);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
 		goto exit4;
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -57,12 +57,18 @@ static inline int user_path_at(int dfd,
 	return user_path_at_empty(dfd, name, flags, path, NULL);
 }
 
+struct dentry *lookup_one_qstr_excl(const struct qstr *name,
+				    struct dentry *base,
+				    unsigned int flags);
 extern int kern_path(const char *, unsigned, struct path *);
 
 extern struct dentry *kern_path_create(int, const char *, struct path *, unsigned int);
 extern struct dentry *user_path_create(int, const char __user *, struct path *, unsigned int);
 extern void done_path_create(struct path *, struct dentry *);
 extern struct dentry *kern_path_locked(const char *, struct path *);
+int vfs_path_parent_lookup(struct filename *filename, unsigned int flags,
+			   struct path *parent, struct qstr *last, int *type,
+			   const struct path *root);
 int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *,
 		    unsigned int, struct path *);
 



  parent reply	other threads:[~2023-12-20 16:14 UTC|newest]

Thread overview: 169+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-20 16:07 [PATCH 5.15 000/159] 5.15.145-rc1 review Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 001/159] ksmbd: use ksmbd_req_buf_next() in ksmbd_verify_smb_message() Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 002/159] ksmdb: use cmd helper variable in smb2_get_ksmbd_tcon() Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 003/159] ksmbd: Remove redundant flush_workqueue() calls Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 004/159] ksmbd: remove md4 leftovers Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 005/159] ksmbd: remove smb2_buf_length in smb2_hdr Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 006/159] ksmbd: remove smb2_buf_length in smb2_transform_hdr Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 007/159] ksmbd: change LeaseKey data type to u8 array Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 008/159] ksmbd: use oid registry functions to decode OIDs Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 009/159] ksmbd: Remove unused parameter from smb2_get_name() Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 010/159] ksmbd: Remove unused fields from ksmbd_file struct definition Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 011/159] ksmbd: set both ipv4 and ipv6 in FSCTL_QUERY_NETWORK_INTERFACE_INFO Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 012/159] ksmbd: Fix buffer_check_err() kernel-doc comment Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 013/159] ksmbd: Fix smb2_set_info_file() " Greg Kroah-Hartman
2023-12-20 16:07 ` [PATCH 5.15 014/159] ksmbd: Delete an invalid argument description in smb2_populate_readdir_entry() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 015/159] ksmbd: Fix smb2_get_name() kernel-doc comment Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 016/159] ksmbd: register ksmbd ib client with ib_register_client() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 017/159] ksmbd: set 445 port to smbdirect port by default Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 018/159] ksmbd: smbd: call rdma_accept() under CM handler Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 019/159] ksmbd: smbd: create MR pool Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 020/159] ksmbd: smbd: change the default maximum read/write, receive size Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 021/159] ksmbd: add smb-direct shutdown Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 022/159] ksmbd: smbd: fix missing clients memory region invalidation Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 023/159] ksmbd: smbd: validate buffer descriptor structures Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 024/159] ksmbd: add support for key exchange Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 025/159] ksmbd: use netif_is_bridge_port Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 026/159] ksmbd: store fids as opaque u64 integers Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 027/159] ksmbd: shorten experimental warning on loading the module Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 028/159] ksmbd: Remove a redundant zeroing of memory Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 029/159] ksmbd: replace usage of found with dedicated list iterator variable Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 030/159] smb3: fix ksmbd bigendian bug in oplock break, and move its struct to smbfs_common Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 031/159] ksmbd: remove filename in ksmbd_file Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 032/159] ksmbd: validate length in smb2_write() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 033/159] ksmbd: smbd: change prototypes of RDMA read/write related functions Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 034/159] ksmbd: smbd: introduce read/write credits for RDMA read/write Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 035/159] ksmbd: smbd: simplify tracking pending packets Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 036/159] ksmbd: smbd: change the return value of get_sg_list Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 037/159] ksmbd: smbd: handle multiple Buffer descriptors Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 038/159] ksmbd: fix wrong smbd max read/write size check Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 039/159] ksmbd: Fix some kernel-doc comments Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 040/159] ksmbd: smbd: fix connection dropped issue Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 041/159] ksmbd: smbd: relax the count of sges required Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 042/159] ksmbd: smbd: Remove useless license text when SPDX-License-Identifier is already used Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 043/159] ksmbd: remove duplicate flag set in smb2_write Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 044/159] ksmbd: remove unused ksmbd_share_configs_cleanup function Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 045/159] ksmbd: use wait_event instead of schedule_timeout() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 046/159] ksmbd: request update to stale share config Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 047/159] ksmbd: remove unnecessary generic_fillattr in smb2_open Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 048/159] ksmbd: dont open-code file_path() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 049/159] ksmbd: dont open-code %pD Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 050/159] ksmbd: constify struct path Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 051/159] ksmbd: remove generic_fillattr use in smb2_open() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 052/159] ksmbd: casefold utf-8 share names and fix ascii lowercase conversion Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 053/159] ksmbd: change security id to the one samba used for posix extension Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 054/159] ksmbd: set file permission mode to match Samba server posix extension behavior Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 055/159] ksmbd: fill sids in SMB_FIND_FILE_POSIX_INFO response Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 056/159] ksmbd: fix encryption failure issue for session logoff response Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 057/159] ksmbd: set NTLMSSP_NEGOTIATE_SEAL flag to challenge blob Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 058/159] ksmbd: decrease the number of SMB3 smbdirect server SGEs Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 059/159] ksmbd: reduce server smbdirect max send/receive segment sizes Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 060/159] ksmbd: hide socket error message when ipv6 config is disable Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 061/159] ksmbd: make utf-8 file name comparison work in __caseless_lookup() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 062/159] ksmbd: call ib_drain_qp when disconnected Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 063/159] ksmbd: validate share name from share config response Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 064/159] ksmbd: replace one-element arrays with flexible-array members Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 065/159] ksmbd: set SMB2_SESSION_FLAG_ENCRYPT_DATA when enforcing data encryption for this share Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 066/159] ksmbd: use F_SETLK when unlocking a file Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 067/159] ksmbd: Fix resource leak in smb2_lock() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 068/159] ksmbd: Convert to use sysfs_emit()/sysfs_emit_at() APIs Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 069/159] ksmbd: send proper error response in smb2_tree_connect() Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 070/159] ksmbd: Implements sess->ksmbd_chann_list as xarray Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 071/159] ksmbd: Implements sess->rpc_handle_list " Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 072/159] ksmbd: fix typo, syncronous->synchronous Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 073/159] ksmbd: Remove duplicated codes Greg Kroah-Hartman
2023-12-20 16:08 ` [PATCH 5.15 074/159] ksmbd: update Kconfig to note Kerberos support and fix indentation Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 075/159] ksmbd: Fix spelling mistake "excceed" -> "exceeded" Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 076/159] ksmbd: Fix parameter name and comment mismatch Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 077/159] ksmbd: fix possible memory leak in smb2_lock() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 078/159] ksmbd: fix wrong signingkey creation when encryption is AES256 Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 079/159] ksmbd: remove unused is_char_allowed function Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 080/159] ksmbd: delete asynchronous work from list Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 081/159] ksmbd: fix slab-out-of-bounds in init_smb2_rsp_hdr Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 082/159] ksmbd: avoid out of bounds access in decode_preauth_ctxt() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 083/159] ksmbd: set NegotiateContextCount once instead of every inc Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 084/159] ksmbd: avoid duplicate negotiate ctx offset increments Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 085/159] ksmbd: remove unused compression negotiate ctx packing Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 086/159] fs: introduce lock_rename_child() helper Greg Kroah-Hartman
2023-12-20 16:09 ` Greg Kroah-Hartman [this message]
2023-12-20 16:09 ` [PATCH 5.15 088/159] ksmbd: fix racy issue from session setup and logoff Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 089/159] ksmbd: destroy expired sessions Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 090/159] ksmbd: block asynchronous requests when making a delay on session setup Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 091/159] ksmbd: fix racy issue from smb2 close and logoff with multichannel Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 092/159] ksmbd: fix racy issue under cocurrent smb2 tree disconnect Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 093/159] ksmbd: fix uninitialized pointer read in ksmbd_vfs_rename() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 094/159] ksmbd: fix uninitialized pointer read in smb2_create_link() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 095/159] ksmbd: fix multiple out-of-bounds read during context decoding Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 096/159] ksmbd: fix UAF issue from opinfo->conn Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 097/159] ksmbd: call putname after using the last component Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 098/159] ksmbd: fix out-of-bound read in deassemble_neg_contexts() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 099/159] ksmbd: fix out-of-bound read in parse_lease_state() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 100/159] ksmbd: fix posix_acls and acls dereferencing possible ERR_PTR() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 101/159] ksmbd: check the validation of pdu_size in ksmbd_conn_handler_loop Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 102/159] ksmbd: validate smb request protocol id Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 103/159] ksmbd: add mnt_want_write to ksmbd vfs functions Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 104/159] ksmbd: remove unused ksmbd_tree_conn_share function Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 105/159] ksmbd: use kzalloc() instead of __GFP_ZERO Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 106/159] ksmbd: return a literal instead of err in ksmbd_vfs_kern_path_locked() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 107/159] ksmbd: Change the return value of ksmbd_vfs_query_maximal_access to void Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 108/159] ksmbd: use kvzalloc instead of kvmalloc Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 109/159] ksmbd: Replace the ternary conditional operator with min() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 110/159] ksmbd: fix out of bounds read in smb2_sess_setup Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 111/159] ksmbd: add missing compound request handing in some commands Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 112/159] ksmbd: Use struct_size() helper in ksmbd_negotiate_smb_dialect() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 113/159] ksmbd: Replace one-element array with flexible-array member Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 114/159] ksmbd: Fix unsigned expression compared with zero Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 115/159] ksmbd: check if a mount point is crossed during path lookup Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 116/159] ksmbd: validate session id and tree id in compound request Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 117/159] ksmbd: fix out of bounds in init_smb2_rsp_hdr() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 118/159] ksmbd: switch to use kmemdup_nul() helper Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 119/159] ksmbd: add support for read compound Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 120/159] ksmbd: fix wrong interim response on compound Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 121/159] ksmbd: fix `force create mode and `force directory mode Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 122/159] ksmbd: reduce descriptor size if remaining bytes is less than request size Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 123/159] ksmbd: Fix one kernel-doc comment Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 124/159] ksmbd: fix slub overflow in ksmbd_decode_ntlmssp_auth_blob() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 125/159] ksmbd: add missing calling smb2_set_err_rsp() on error Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 126/159] ksmbd: remove experimental warning Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 127/159] ksmbd: remove unneeded mark_inode_dirty in set_info_sec() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 128/159] ksmbd: fix passing freed memory aux_payload_buf Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 129/159] ksmbd: return invalid parameter error response if smb2 request is invalid Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 130/159] ksmbd: check iov vector index in ksmbd_conn_write() Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 131/159] ksmbd: fix race condition between session lookup and expire Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 132/159] ksmbd: fix race condition with fp Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 133/159] ksmbd: fix race condition from parallel smb2 logoff requests Greg Kroah-Hartman
2023-12-20 16:09 ` [PATCH 5.15 134/159] ksmbd: fix race condition from parallel smb2 lock requests Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 135/159] ksmbd: fix race condition between tree conn lookup and disconnect Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 136/159] ksmbd: fix wrong error response status by using set_smb2_rsp_status() Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 137/159] ksmbd: fix Null pointer dereferences in ksmbd_update_fstate() Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 138/159] ksmbd: fix potential double free on smb2_read_pipe() error path Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 139/159] ksmbd: Remove unused field in ksmbd_user struct Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 140/159] ksmbd: reorganize ksmbd_iov_pin_rsp() Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 141/159] ksmbd: fix kernel-doc comment of ksmbd_vfs_setxattr() Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 142/159] ksmbd: fix recursive locking in vfs helpers Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 143/159] ksmbd: fix missing RDMA-capable flag for IPoIB device in ksmbd_rdma_capable_netdev() Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 144/159] ksmbd: add support for surrogate pair conversion Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 145/159] ksmbd: no need to wait for binded connection termination at logoff Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 146/159] ksmbd: fix kernel-doc comment of ksmbd_vfs_kern_path_locked() Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 147/159] ksmbd: handle malformed smb1 message Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 148/159] ksmbd: prevent memory leak on error return Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 149/159] ksmbd: fix possible deadlock in smb2_open Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 150/159] ksmbd: separately allocate ci per dentry Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 151/159] ksmbd: move oplock handling after unlock parent dir Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 152/159] ksmbd: release interim response after sending status pending response Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 153/159] ksmbd: move setting SMB2_FLAGS_ASYNC_COMMAND and AsyncId Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 154/159] ksmbd: dont update ->op_state as OPLOCK_STATE_NONE on error Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 155/159] Revert "drm/bridge: lt9611uxc: fix the race in the error path" Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 156/159] Revert "drm/bridge: lt9611uxc: Register and attach our DSI device at probe" Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 157/159] Revert "drm/bridge: lt9611uxc: Switch to devm MIPI-DSI helpers" Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 158/159] tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols Greg Kroah-Hartman
2023-12-20 16:10 ` [PATCH 5.15 159/159] kasan: disable kasan_non_canonical_hook() for HW tags Greg Kroah-Hartman
2023-12-20 19:31 ` [PATCH 5.15 000/159] 5.15.145-rc1 review Florian Fainelli
2023-12-20 19:38 ` Allen
2023-12-21  4:52 ` Shuah Khan
2023-12-21  5:41 ` Namjae Jeon
2023-12-21  6:48 ` Naresh Kamboju
2023-12-21  9:17 ` Ron Economos
2023-12-21 14:57 ` Guenter Roeck
2023-12-21 23:37 ` SeongJae Park
2023-12-22 13:28 ` Jon Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231220160935.429249358@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linkinjeon@kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=stable@vger.kernel.org \
    --cc=stfrench@microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox