kernel/fs: Check O_DIRECTORY in the VFS, not filesystems.
Just like O_NOFOLLOW. Also drop the now-redundant checks from all filesystems. At least some filesystem hooks (FIFOs in particular, see #19879) did not check this, so this fixes them.
This commit is contained in:
@@ -1346,8 +1346,6 @@ bfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
|
||||
// any data from it.
|
||||
if (inode->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory())
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t status = inode->CheckPermissions(open_mode_to_access(openMode));
|
||||
if (status != B_OK)
|
||||
|
||||
@@ -461,8 +461,6 @@ exfat_open(fs_volume* /*_volume*/, fs_vnode* _node, int openMode,
|
||||
// any data from it.
|
||||
if (inode->IsDirectory() && (openMode & O_RWMASK) != 0)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory())
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t status = inode->CheckPermissions(open_mode_to_access(openMode));
|
||||
if (status != B_OK)
|
||||
|
||||
@@ -523,8 +523,6 @@ Inode::Create(Transaction& transaction, Inode* parent, const char* name,
|
||||
|
||||
if (inode->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory())
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
if (inode->CheckPermissions(open_mode_to_access(openMode)) != B_OK)
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
@@ -1125,8 +1125,6 @@ ext2_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
|
||||
// any data from it.
|
||||
if (inode->IsDirectory() && (openMode & O_RWMASK) != 0)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory())
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t status = inode->CheckPermissions(open_mode_to_access(openMode));
|
||||
if (status != B_OK)
|
||||
|
||||
@@ -2177,8 +2177,6 @@ dosfs_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
|
||||
// any data from it.
|
||||
if (bsdNode->v_type == VDIR && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && bsdNode->v_type != VDIR)
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
if ((bsdVolume->mnt_flag & MNT_RDONLY) != 0 || (fatNode->de_Attributes & ATTR_READONLY) != 0)
|
||||
openMode = (openMode & ~O_RWMASK) | O_RDONLY;
|
||||
|
||||
@@ -511,16 +511,11 @@ fs_read_stat(fs_volume* _volume, fs_vnode* _node, struct stat* st)
|
||||
static status_t
|
||||
fs_open(fs_volume* /*_volume*/, fs_vnode* _node, int openMode, void** /*cookie*/)
|
||||
{
|
||||
iso9660_inode* node = (iso9660_inode*)_node->private_node;
|
||||
|
||||
// Do not allow any of the write-like open modes to get by
|
||||
if ((openMode & O_RWMASK) == O_WRONLY || (openMode & O_RWMASK) == O_RDWR
|
||||
|| (openMode & O_TRUNC) != 0 || (openMode & O_CREAT) != 0)
|
||||
return EROFS;
|
||||
|
||||
if ((openMode & O_DIRECTORY) != 0 && (node->flags & ISO_IS_DIR) == 0)
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -573,9 +573,6 @@ OverlayInode::Open(int openMode, void **_cookie)
|
||||
if (!fHasStat)
|
||||
_PopulateStat();
|
||||
|
||||
if ((openMode & O_DIRECTORY) != 0 && !S_ISDIR(fStat.st_mode))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
open_cookie *cookie = (open_cookie *)malloc(sizeof(open_cookie));
|
||||
if (cookie == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@@ -829,8 +829,6 @@ nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
|
||||
|
||||
if (inode->Type() == S_IFDIR && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && inode->Type() != S_IFDIR)
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
if (inode->Type() == S_IFDIR || inode->Type() == S_IFLNK) {
|
||||
*_cookie = NULL;
|
||||
|
||||
@@ -816,8 +816,6 @@ fs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
|
||||
// opening a directory read-only is allowed (but no data can be read)
|
||||
if ((node->mode & S_IFDIR) != 0 && (openMode & O_RWMASK) != 0)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && (node->mode & S_IFDIR) == 0)
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t status = fs_access(_volume, _node, open_mode_to_access(openMode));
|
||||
if (status != B_OK)
|
||||
|
||||
@@ -423,8 +423,6 @@ packagefs_open(fs_volume* fsVolume, fs_vnode* fsNode, int openMode,
|
||||
// check the open mode and permissions
|
||||
if (S_ISDIR(node->Mode()) && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !S_ISDIR(node->Mode()))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
if ((openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_NOT_ALLOWED;
|
||||
|
||||
@@ -964,8 +964,6 @@ ramfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
|
||||
// directory can be opened read-only
|
||||
if (node->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY)
|
||||
error = B_IS_A_DIRECTORY;
|
||||
if (error == B_OK && (openMode & O_DIRECTORY) != 0 && !node->IsDirectory())
|
||||
error = B_NOT_A_DIRECTORY;
|
||||
|
||||
int accessMode = open_mode_to_access(openMode);
|
||||
// check open mode against permissions
|
||||
|
||||
@@ -265,8 +265,6 @@ ufs2_open(fs_volume * _volume, fs_vnode *_node, int openMode,
|
||||
// any data from it.
|
||||
if (inode->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory())
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t status = inode->CheckPermissions(open_mode_to_access(openMode)
|
||||
| (openMode & O_TRUNC ? W_OK : 0));
|
||||
|
||||
@@ -1115,8 +1115,6 @@ devfs_open(fs_volume* _volume, fs_vnode* _vnode, int openMode,
|
||||
|
||||
if (S_ISDIR(vnode->stream.type) && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !S_ISDIR(vnode->stream.type))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
cookie = (struct devfs_cookie*)malloc(sizeof(struct devfs_cookie));
|
||||
if (cookie == NULL)
|
||||
|
||||
@@ -600,8 +600,6 @@ rootfs_open(fs_volume* _volume, fs_vnode* _v, int openMode, void** _cookie)
|
||||
|
||||
if (S_ISDIR(vnode->stream.type) && (openMode & O_RWMASK) != O_RDONLY)
|
||||
return B_IS_A_DIRECTORY;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !S_ISDIR(vnode->stream.type))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t status = rootfs_check_permissions(vnode, open_mode_to_access(openMode));
|
||||
if (status != B_OK)
|
||||
|
||||
@@ -5414,6 +5414,8 @@ check_open_mode(struct vnode* vnode, int openMode)
|
||||
|
||||
if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
|
||||
return B_LINK_LIMIT;
|
||||
if ((openMode & O_DIRECTORY) != 0 && !S_ISDIR(vnode->Type()))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -555,9 +555,6 @@ open_file(Volume* volume, Node* node, int openMode, Transaction& transaction,
|
||||
return B_IS_A_DIRECTORY;
|
||||
}
|
||||
|
||||
if ((openMode & O_DIRECTORY) != 0 && !S_ISDIR(node->Mode()))
|
||||
return B_NOT_A_DIRECTORY;
|
||||
|
||||
status_t error = check_access(node, accessFlags);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
Reference in New Issue
Block a user