Subject: Addition to force open to open only regular files
To: None <tech-kern@netbsd.org>
From: Bill Studenmund <wrstuden@zembu.com>
List: tech-kern
Date: 11/10/2000 10:54:22
One of the things that came up in a recent security thread (how to use
HOSTALIASES safely in a set-uid program) was that it would be nice for
userland to be able to ask the kernel to only open a regular file. This
ability is important as it means that untrusted path names ($HOSTALIASES
for example) can't be used to open devices. Remember that some devices
have implicit behaviors on open. Like certain tape nodes imply reqinding
before open.

We want to be able to prevent that. We need to do it in the kernel,
though, as part of the open. Otherwise we have to do two name lookups, one
to see if the name is ok, and the next to open it. But that adds a race
condition..

So here are patches which add a new open flag, O_REG_FILE, and add a test
to the kernel after we've done the name lookup but before we've done the
VOP_OPEN() to make sure we really got a regular file.

Thoughts?

Take care,

Bill

Index: kern/vfs_vnops.c
===================================================================
RCS file: /home/cvsfiles/netbsd/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 vfs_vnops.c
--- vfs_vnops.c	2000/04/13 19:18:26	1.1.1.2
+++ vfs_vnops.c	2000/11/10 17:02:05
@@ -133,6 +133,10 @@
 		goto bad;
 	}
 	if ((fmode & O_CREAT) == 0) {
+		if ((fmode & FREGONLY) && (vp->v_type != VREG)) {
+			error = EOPNOTSUPP;
+			goto bad;
+		}
 		if (fmode & FREAD) {
 			if ((error = VOP_ACCESS(vp, VREAD, cred, p)) != 0)
 				goto bad;
Index: sys/fcntl.h
===================================================================
RCS file: /home/cvsfiles/netbsd/src/sys/sys/fcntl.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 fcntl.h
--- fcntl.h	2000/03/31 20:00:37	1.1.1.1
+++ fcntl.h	2000/11/10 17:02:05
@@ -107,6 +107,7 @@
 
 #if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)
 #define	O_ALT_IO	0x00040000	/* use alternate i/o semantics */
+#define	O_REG_ONLY	0x00080000	/* only open a plain file */
 #endif
 
 /* defined by POSIX 1003.1; BSD default, but required to be bitwise distinct */
@@ -120,7 +121,7 @@
 /* all bits settable during open(2) */
 #define	O_MASK		(O_ACCMODE|O_NONBLOCK|O_APPEND|O_SHLOCK|O_EXLOCK|\
 			 O_ASYNC|O_SYNC|O_CREAT|O_TRUNC|O_EXCL|O_DSYNC|\
-			 O_RSYNC|O_NOCTTY|O_ALT_IO)
+			 O_RSYNC|O_NOCTTY|O_ALT_IO|O_REG_ONLY)
 
 #define	FMARK		0x00001000	/* mark during gc() */
 #define	FDEFER		0x00002000	/* defer for next gc pass */
@@ -157,6 +158,7 @@
 #define	FDSYNC		O_DSYNC		/* kernel */
 #define	FRSYNC		O_RSYNC		/* kernel */
 #define	FALTIO		O_ALT_IO	/* kernel */
+#define	FREGONLY	O_REG_ONLY	/* kernel */
 #endif
 
 /*