From d5fec48956cd44268599f64f7a8825a0a84c77e5 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Wed, 22 Apr 2015 01:54:25 +0000 Subject: [PATCH] Support file verification in MAC. * Add VCREAT flag to indicate when a new file is being created * Add VVERIFY to indicate verification is required * Both VCREAT and VVERIFY are only passed on the MAC method vnode_check_open and are removed from the accmode after * Add O_VERIFY flag to rtld open of objects * Add 'v' flag to __sflags to set O_VERIFY flag. Submitted by: Steve Kiernan Obtained from: Juniper Networks, Inc. GitHub Pull Request: https://github.com/freebsd/freebsd/pull/27 Relnotes: yes --- lib/libc/stdio/flags.c | 4 ++++ libexec/rtld-elf/rtld.c | 4 ++-- sys/kern/vfs_vnops.c | 6 ++++++ sys/sys/fcntl.h | 4 ++++ sys/sys/vnode.h | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/libc/stdio/flags.c b/lib/libc/stdio/flags.c index b7552a43804c..9eed6d7dc8c7 100644 --- a/lib/libc/stdio/flags.c +++ b/lib/libc/stdio/flags.c @@ -97,6 +97,10 @@ __sflags(const char *mode, int *optr) /* set close-on-exec */ o |= O_CLOEXEC; break; + case 'v': + /* verify */ + o |= O_VERIFY; + break; default: known = 0; break; diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 78f823c35d08..b0704747ae7b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -2165,7 +2165,7 @@ load_object(const char *name, int fd_u, const Obj_Entry *refobj, int flags) * To avoid a race, we open the file and use fstat() rather than * using stat(). */ - if ((fd = open(path, O_RDONLY | O_CLOEXEC)) == -1) { + if ((fd = open(path, O_RDONLY | O_CLOEXEC | O_VERIFY)) == -1) { _rtld_error("Cannot open \"%s\"", path); free(path); return (NULL); @@ -2855,7 +2855,7 @@ search_library_pathfds(const char *name, const char *path, int *fdp) dirfd = parse_libdir(fdstr); if (dirfd < 0) break; - fd = __sys_openat(dirfd, name, O_RDONLY | O_CLOEXEC); + fd = __sys_openat(dirfd, name, O_RDONLY | O_CLOEXEC | O_VERIFY); if (fd >= 0) { *fdp = fd; len = strlen(fdstr) + strlen(name) + 3; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index ed4ad4d18f13..01d448edf698 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -306,9 +306,15 @@ vn_open_vnode(struct vnode *vp, int fmode, struct ucred *cred, if ((fmode & O_APPEND) && (fmode & FWRITE)) accmode |= VAPPEND; #ifdef MAC + if (fmode & O_CREAT) + accmode |= VCREAT; + if (fmode & O_VERIFY) + accmode |= VVERIFY; error = mac_vnode_check_open(cred, vp, accmode); if (error) return (error); + + accmode &= ~(VCREAT | VVERIFY); #endif if ((fmode & O_CREAT) == 0) { if (accmode & VWRITE) { diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h index 85db07f3ba10..5793229334bf 100644 --- a/sys/sys/fcntl.h +++ b/sys/sys/fcntl.h @@ -129,6 +129,10 @@ typedef __pid_t pid_t; #define O_CLOEXEC 0x00100000 #endif +#if __BSD_VISIBLE +#define O_VERIFY 0x00200000 /* open only after verification */ +#endif + /* * XXX missing O_DSYNC, O_RSYNC. */ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index e1f912e7ffec..d70aa579c1b1 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -336,6 +336,8 @@ struct vattr { #define VWRITE_ACL 000040000000 /* change ACL and/or file mode */ #define VWRITE_OWNER 000100000000 /* change file owner */ #define VSYNCHRONIZE 000200000000 /* not used */ +#define VCREAT 000400000000 /* creating new file */ +#define VVERIFY 001000000000 /* verification required */ /* * Permissions that were traditionally granted only to the file owner.