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:
Augustin Cavalier
2026-01-07 14:02:46 -05:00
parent a75b98ed11
commit ac46a180d8
+6 -2
View File
@@ -5431,8 +5431,10 @@ open_vnode(struct vnode* vnode, int openMode, bool kernel)
/*!
Calls fs_open() on the given vnode and returns a new
file descriptor for it
Creates a new regular file and returns a new 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
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 ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
return B_LINK_LIMIT;
if (S_ISDIR(vnode->Type()))
return B_IS_A_DIRECTORY;
int fd = open_vnode(vnode.Get(), openMode & ~O_CREAT, kernel);
// on success keep the vnode reference for the FD