summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_acl_nfs4.c
diff options
context:
space:
mode:
authorjh <jh@FreeBSD.org>2010-08-30 16:30:18 +0000
committerjh <jh@FreeBSD.org>2010-08-30 16:30:18 +0000
commitc2cb836190c82be4859c68f5fabd199508638762 (patch)
tree74e3c2e0dd77b8186e54fea709c4eef6f29e2ae5 /sys/kern/subr_acl_nfs4.c
parent8505815b26f679d50f55f4ed16b1604f2d747b4e (diff)
downloadFreeBSD-src-c2cb836190c82be4859c68f5fabd199508638762.zip
FreeBSD-src-c2cb836190c82be4859c68f5fabd199508638762.tar.gz
execve(2) has a special check for file permissions: a file must have at
least one execute bit set, otherwise execve(2) will return EACCES even for an user with PRIV_VFS_EXEC privilege. Add the check also to vaccess(9), vaccess_acl_nfs4(9) and vaccess_acl_posix1e(9). This makes access(2) to better agree with execve(2). Because ZFS doesn't use vaccess(9) for VEXEC, add the check to zfs_freebsd_access() too. There may be other file systems which are not using vaccess*() functions and need to be handled separately. PR: kern/125009 Reviewed by: bde, trasz Approved by: pjd (ZFS part)
Diffstat (limited to 'sys/kern/subr_acl_nfs4.c')
-rw-r--r--sys/kern/subr_acl_nfs4.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c
index ec7ead9..5b2b086 100644
--- a/sys/kern/subr_acl_nfs4.c
+++ b/sys/kern/subr_acl_nfs4.c
@@ -162,6 +162,7 @@ vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
accmode_t priv_granted = 0;
int denied, explicitly_denied, access_mask, is_directory,
must_be_owner = 0;
+ mode_t file_mode;
KASSERT((accmode & ~(VEXEC | VWRITE | VREAD | VADMIN | VAPPEND |
VEXPLICIT_DENY | VREAD_NAMED_ATTRS | VWRITE_NAMED_ATTRS |
@@ -216,6 +217,17 @@ vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
denied = EPERM;
}
+ /*
+ * For VEXEC, ensure that at least one execute bit is set for
+ * non-directories. We have to check the mode here to stay
+ * consistent with execve(2). See the test in
+ * exec_check_permissions().
+ */
+ acl_nfs4_sync_mode_from_acl(&file_mode, aclp);
+ if (!denied && !is_directory && (accmode & VEXEC) &&
+ (file_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)
+ denied = EACCES;
+
if (!denied)
return (0);
@@ -236,8 +248,14 @@ vaccess_acl_nfs4(enum vtype type, uid_t file_uid, gid_t file_gid,
PRIV_VFS_LOOKUP, 0))
priv_granted |= VEXEC;
} else {
- if ((accmode & VEXEC) && !priv_check_cred(cred,
- PRIV_VFS_EXEC, 0))
+ /*
+ * Ensure that at least one execute bit is on. Otherwise,
+ * a privileged user will always succeed, and we don't want
+ * this to happen unless the file really is executable.
+ */
+ if ((accmode & VEXEC) && (file_mode &
+ (S_IXUSR | S_IXGRP | S_IXOTH)) != 0 &&
+ !priv_check_cred(cred, PRIV_VFS_EXEC, 0))
priv_granted |= VEXEC;
}
OpenPOWER on IntegriCloud