diff options
author | Namjae Jeon <linkinjeon@kernel.org> | 2024-09-24 22:39:29 +0900 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2024-09-25 21:33:19 -0500 |
commit | 8e2f6a0e2dc9db663b4ba2225822e7a3c4047bfb (patch) | |
tree | 588d66ae752bbddabea44189a94c164d61082e35 /fs/smb | |
parent | d782d6e1d9078d6b82f8468dd6421050165e7d75 (diff) |
ksmbd: fix open failure from block and char device file
char/block device file can't be opened with dentry_open() if device driver
is not loaded. Use O_PATH flags for fake opening file to handle it if file
is a block or char file.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb')
-rw-r--r-- | fs/smb/server/smb2pdu.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 72af3ab40b5c..7460089c186f 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2052,18 +2052,20 @@ out_err1: * @access: file access flags * @disposition: file disposition flags * @may_flags: set with MAY_ flags - * @is_dir: is creating open flags for directory + * @coptions: file creation options + * @mode: file mode * * Return: file open flags */ static int smb2_create_open_flags(bool file_present, __le32 access, __le32 disposition, int *may_flags, - bool is_dir) + __le32 coptions, + umode_t mode) { int oflags = O_NONBLOCK | O_LARGEFILE; - if (is_dir) { + if (coptions & FILE_DIRECTORY_FILE_LE || S_ISDIR(mode)) { access &= ~FILE_WRITE_DESIRE_ACCESS_LE; ksmbd_debug(SMB, "Discard write access to a directory\n"); } @@ -2080,7 +2082,7 @@ static int smb2_create_open_flags(bool file_present, __le32 access, *may_flags = MAY_OPEN | MAY_READ; } - if (access == FILE_READ_ATTRIBUTES_LE) + if (access == FILE_READ_ATTRIBUTES_LE || S_ISBLK(mode) || S_ISCHR(mode)) oflags |= O_PATH; if (file_present) { @@ -3175,8 +3177,8 @@ int smb2_open(struct ksmbd_work *work) open_flags = smb2_create_open_flags(file_present, daccess, req->CreateDisposition, &may_flags, - req->CreateOptions & FILE_DIRECTORY_FILE_LE || - (file_present && S_ISDIR(d_inode(path.dentry)->i_mode))); + req->CreateOptions, + file_present ? d_inode(path.dentry)->i_mode : 0); if (!test_tree_conn_flag(tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) { if (open_flags & (O_CREAT | O_TRUNC)) { |