From 6e2242fc935e4c6dec8a2356490357761e7f4aeb Mon Sep 17 00:00:00 2001 From: jsg Date: Wed, 8 Apr 2026 12:08:25 +0000 Subject: [PATCH] Error with EISDIR when calling open(2) with O_CREAT when the last component of the path is an existing directory and O_DIRECTORY is not specified. This is required by recent versions of POSIX. We previously did not return an error. Flagged by Sortix os-test. committing on behalf of daniel@, partly based on FreeBSD changes ok guenther@ jsg@ deraadt@ --- lib/libc/sys/open.2 | 12 +++++++++++- sys/kern/vfs_vnops.c | 6 +++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2 index 20f0c426b66..560e7345960 100644 --- a/lib/libc/sys/open.2 +++ b/lib/libc/sys/open.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: open.2,v 1.57 2026/04/08 11:36:40 jsg Exp $ +.\" $OpenBSD: open.2,v 1.58 2026/04/08 12:08:25 jsg Exp $ .\" $NetBSD: open.2,v 1.8 1995/02/27 12:35:14 cgd Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 @@ -297,6 +297,16 @@ flag was specified and the target is a symbolic link. .It Bq Er EISDIR The named file is a directory, and the arguments specify it is to be opened for writing. +.It Bq Er EISDIR +The named file is a directory, and the flags specified +.Dv O_CREAT +without +.Dv O_DIRECTORY . +If +.Dv O_EXCL +is also specified, see +.Er EEXIST +which is returned instead. .It Bq Er EINVAL The .Fa flags diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index bcf07bc983a..9cb0ecf6420 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_vnops.c,v 1.126 2026/04/08 11:32:24 jsg Exp $ */ +/* $OpenBSD: vfs_vnops.c,v 1.127 2026/04/08 12:08:25 jsg Exp $ */ /* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */ /* @@ -134,6 +134,10 @@ vn_open(struct nameidata *ndp, int fmode, int cmode) error = EEXIST; goto bad; } + if (vp->v_type == VDIR) { + error = EISDIR; + goto bad; + } fmode &= ~O_CREAT; } } else {