diff options
author | Jaakko Heinonen <jh@FreeBSD.org> | 2010-08-30 16:30:18 +0000 |
---|---|---|
committer | Jaakko Heinonen <jh@FreeBSD.org> | 2010-08-30 16:30:18 +0000 |
commit | de478dd4b427a1f2c667af80784c58e5d73892e3 (patch) | |
tree | 74e3c2e0dd77b8186e54fea709c4eef6f29e2ae5 /sys/kern/subr_acl_nfs4.c | |
parent | e7fb66340e060b9837c228fde0b7155592cb42b2 (diff) | |
download | src-de478dd4b427a1f2c667af80784c58e5d73892e3.tar.gz src-de478dd4b427a1f2c667af80784c58e5d73892e3.zip |
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)
Notes
Notes:
svn path=/head/; revision=212002
Diffstat (limited to 'sys/kern/subr_acl_nfs4.c')
-rw-r--r-- | sys/kern/subr_acl_nfs4.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/kern/subr_acl_nfs4.c b/sys/kern/subr_acl_nfs4.c index ec7ead930bbe..5b2b08622016 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; } |