kernel/fs: Check if the existing node is a directory in create_vnode.
Otherwise, calling open(O_CREAT) on a path that exists but is a directory will succeed. Fixes Sortix os-test open-tmpdir-rdonly-creat. (Interestingly many other OSes also fail this test; only Linux, FreeBSD, Solaris, and Sortix, and now also Haiku, properly return EISDIR.) While at it, fix the doc comment, which appears to have been copied from open_vnode.
This commit is contained in:
@@ -5431,8 +5431,10 @@ open_vnode(struct vnode* vnode, int openMode, bool kernel)
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Calls fs_open() on the given vnode and returns a new
|
Creates a new regular file and returns a new file descriptor for it.
|
||||||
file descriptor for it
|
|
||||||
|
If O_EXCL is not specified and an entry already exists at the path,
|
||||||
|
then that entry will be opened and returned instead.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
create_vnode(struct vnode* directory, const char* name, int openMode,
|
create_vnode(struct vnode* directory, const char* name, int openMode,
|
||||||
@@ -5498,6 +5500,8 @@ create_vnode(struct vnode* directory, const char* name, int openMode,
|
|||||||
if (!create) {
|
if (!create) {
|
||||||
if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
|
if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
|
||||||
return B_LINK_LIMIT;
|
return B_LINK_LIMIT;
|
||||||
|
if (S_ISDIR(vnode->Type()))
|
||||||
|
return B_IS_A_DIRECTORY;
|
||||||
|
|
||||||
int fd = open_vnode(vnode.Get(), openMode & ~O_CREAT, kernel);
|
int fd = open_vnode(vnode.Get(), openMode & ~O_CREAT, kernel);
|
||||||
// on success keep the vnode reference for the FD
|
// on success keep the vnode reference for the FD
|
||||||
|
|||||||
Reference in New Issue
Block a user