]> Git Repo - linux.git/commitdiff
ksmbd: fix open failure from block and char device file
authorNamjae Jeon <[email protected]>
Tue, 24 Sep 2024 13:39:29 +0000 (22:39 +0900)
committerSteve French <[email protected]>
Thu, 26 Sep 2024 02:33:19 +0000 (21:33 -0500)
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 <[email protected]>
Signed-off-by: Steve French <[email protected]>
fs/smb/server/smb2pdu.c

index 72af3ab40b5c391db1dabf2f45e101cd979a0066..7460089c186f08241b0b2c823e99578fdff7e01e 100644 (file)
@@ -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)) {
This page took 0.055256 seconds and 4 git commands to generate.