From bffc34c94b9bb194423065f77bdaa0ff7778439c Mon Sep 17 00:00:00 2001 From: YanWQ-monad Date: Wed, 10 Jul 2024 22:17:08 +0800 Subject: [PATCH] Don't check access mode if the file is being created --- kernel/aster-nix/src/fs/fs_resolver.rs | 19 ++++++++++--------- .../aster-nix/src/fs/inode_handle/dyn_cap.rs | 10 ++++++++++ .../blocklists.exfat/open_create_test | 4 ++++ test/syscall_test/blocklists/open_create_test | 4 ---- 4 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 test/syscall_test/blocklists.exfat/open_create_test diff --git a/kernel/aster-nix/src/fs/fs_resolver.rs b/kernel/aster-nix/src/fs/fs_resolver.rs index 3dd8aa9c..ec6f6f38 100644 --- a/kernel/aster-nix/src/fs/fs_resolver.rs +++ b/kernel/aster-nix/src/fs/fs_resolver.rs @@ -70,7 +70,7 @@ impl FsResolver { let follow_tail_link = !(creation_flags.contains(CreationFlags::O_NOFOLLOW) || creation_flags.contains(CreationFlags::O_CREAT) && creation_flags.contains(CreationFlags::O_EXCL)); - let dentry = match self.lookup_inner(path, follow_tail_link) { + let inode_handle = match self.lookup_inner(path, follow_tail_link) { Ok(dentry) => { let inode = dentry.inode(); if inode.type_() == InodeType::SymLink @@ -92,7 +92,11 @@ impl FsResolver { "O_DIRECTORY is specified but file is not a directory" ); } - dentry + + if creation_flags.contains(CreationFlags::O_TRUNC) { + dentry.resize(0)?; + } + InodeHandle::new(dentry, access_mode, status_flags)? } Err(e) if e.error() == Errno::ENOENT @@ -109,17 +113,14 @@ impl FsResolver { if !dir_dentry.mode()?.is_writable() { return_errno_with_message!(Errno::EACCES, "file cannot be created"); } - dir_dentry.new_fs_child(&file_name, InodeType::File, inode_mode)? + + let dentry = dir_dentry.new_fs_child(&file_name, InodeType::File, inode_mode)?; + // Don't check access mode for newly created file + InodeHandle::new_unchecked_access(dentry, access_mode, status_flags)? } Err(e) => return Err(e), }; - if creation_flags.contains(CreationFlags::O_TRUNC) { - dentry.resize(0)?; - } - - let inode_handle = InodeHandle::new(dentry, access_mode, status_flags)?; - Ok(inode_handle) } diff --git a/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs b/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs index e2a416dd..2d872da6 100644 --- a/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs +++ b/kernel/aster-nix/src/fs/inode_handle/dyn_cap.rs @@ -19,6 +19,16 @@ impl InodeHandle { if access_mode.is_writable() && !inode.mode()?.is_writable() { return_errno_with_message!(Errno::EACCES, "File is not writable"); } + + Self::new_unchecked_access(dentry, access_mode, status_flags) + } + + pub fn new_unchecked_access( + dentry: Arc, + access_mode: AccessMode, + status_flags: StatusFlags, + ) -> Result { + let inode = dentry.inode(); if access_mode.is_writable() && inode.type_() == InodeType::Dir { return_errno_with_message!(Errno::EISDIR, "Directory cannot open to write"); } diff --git a/test/syscall_test/blocklists.exfat/open_create_test b/test/syscall_test/blocklists.exfat/open_create_test new file mode 100644 index 00000000..da3b635d --- /dev/null +++ b/test/syscall_test/blocklists.exfat/open_create_test @@ -0,0 +1,4 @@ +CreateTest.ChmodReadToWriteBetweenOpens_NoRandomSave +CreateTest.ChmodWriteToReadBetweenOpens_NoRandomSave +CreateTest.CreateWithReadFlagNotAllowedByMode_NoRandomSave +CreateTest.CreateWithWriteFlagNotAllowedByMode_NoRandomSave diff --git a/test/syscall_test/blocklists/open_create_test b/test/syscall_test/blocklists/open_create_test index d2dc2462..3a3f8b73 100644 --- a/test/syscall_test/blocklists/open_create_test +++ b/test/syscall_test/blocklists/open_create_test @@ -3,7 +3,3 @@ CreateTest.CreatWithOTrunc CreateTest.CreatDirWithOTruncAndReadOnly CreateTest.CreateFailsOnUnpermittedDir CreateTest.CreateFailsOnDirWithoutWritePerms -CreateTest.ChmodReadToWriteBetweenOpens_NoRandomSave -CreateTest.ChmodWriteToReadBetweenOpens_NoRandomSave -CreateTest.CreateWithReadFlagNotAllowedByMode_NoRandomSave -CreateTest.CreateWithWriteFlagNotAllowedByMode_NoRandomSave \ No newline at end of file