[PATCH AUTOSEL 6.1 52/53] ksmbd: fix potential circular locking issue in smb2_set_ea()

From: Sasha Levin
Date: Mon Jan 22 2024 - 11:13:00 EST


From: Namjae Jeon <linkinjeon@xxxxxxxxxx>

[ 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@xxxxxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
fs/smb/server/smb2pdu.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 6e5ed0ac578a..8d4e2c666c34 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2309,11 +2309,12 @@ static noinline int create_smb2_pipe(struct ksmbd_work *work)
* @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;
@@ -3001,7 +3002,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)
@@ -5990,7 +5991,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:
{
--
2.43.0