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
/*