summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs/ufs')
-rw-r--r--sys/ufs/ufs/ufs_lookup.c5
-rw-r--r--sys/ufs/ufs/ufs_vnops.c69
2 files changed, 48 insertions, 26 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index 22387a9..894ee12 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -476,9 +476,8 @@ found:
* implements append-only directories.
*/
if ((dp->i_mode & ISVTX) &&
- suser_xxx(cred, p, PRISON_ROOT) &&
- cred->cr_uid != dp->i_uid &&
- VTOI(tdp)->i_uid != cred->cr_uid) {
+ VOP_ACCESS(vdp, VADMIN, cred, cnp->cn_proc) &&
+ VOP_ACCESS(tdp, VADMIN, cred, cnp->cn_proc)) {
vput(tdp);
return (EPERM);
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 3ac1038..7201d49 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -411,13 +411,17 @@ ufs_setattr(ap)
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
/*
- * Privileged processes in jail() are permitted to modify
- * arbitrary user flags on files, but are not permitted
- * to modify system flags.
+ * Callers may only modify the file flags on objects they
+ * have VADMIN rights for.
*/
- if (cred->cr_uid != ip->i_uid &&
- (error = suser_xxx(cred, p, PRISON_ROOT)))
+ if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
return (error);
+ /*
+ * Unprivileged processes and privileged processes in
+ * jail() are not permitted to set system flags.
+ * Privileged processes not in jail() may only set system
+ * flags if the securelevel <= 0.
+ */
if (!suser_xxx(cred, NULL, 0)) {
if ((ip->i_flags
& (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
@@ -450,7 +454,8 @@ ufs_setattr(ap)
if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
- if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred, p)) != 0)
+ if ((error = ufs_chown(vp, vap->va_uid, vap->va_gid, cred,
+ p)) != 0)
return (error);
}
if (vap->va_size != VNOVAL) {
@@ -480,8 +485,15 @@ ufs_setattr(ap)
return (EROFS);
if ((ip->i_flags & SF_SNAPSHOT) != 0)
return (EPERM);
- if (cred->cr_uid != ip->i_uid &&
- (error = suser_xxx(cred, p, PRISON_ROOT)) &&
+ /*
+ * From utimes(2):
+ * If times is NULL, ... The caller must be the owner of
+ * the file, have permission to write the file, or be the
+ * super-user.
+ * If times is non-NULL, ... The caller must be the owner of
+ * the file or be the super-user.
+ */
+ if ((error = VOP_ACCESS(vp, VADMIN, cred, p)) &&
((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
(error = VOP_ACCESS(vp, VWRITE, cred, p))))
return (error);
@@ -529,11 +541,17 @@ ufs_chmod(vp, mode, cred, p)
register struct inode *ip = VTOI(vp);
int error;
- if (cred->cr_uid != ip->i_uid) {
- error = suser_xxx(cred, p, PRISON_ROOT);
- if (error)
+ /*
+ * To modify the permissions on a file, must possess VADMIN
+ * for that file.
+ */
+ if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
return (error);
- }
+ /*
+ * Privileged processes may set the sticky bit on non-directories,
+ * as well as set the setgid bit on a file with a group that the
+ * process is not a member of.
+ */
if (suser_xxx(cred, NULL, PRISON_ROOT)) {
if (vp->v_type != VDIR && (mode & S_ISTXT))
return (EFTYPE);
@@ -572,11 +590,17 @@ ufs_chown(vp, uid, gid, cred, p)
if (gid == (gid_t)VNOVAL)
gid = ip->i_gid;
/*
- * If we don't own the file, are trying to change the owner
- * of the file, or are not a member of the target group,
- * the caller must be superuser or the call fails.
+ * To modify the ownership of a file, must possess VADMIN
+ * for that file.
+ */
+ if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
+ return (error);
+ /*
+ * To change the owner of a file, or change the group of a file
+ * to a group of which we are not a member, the caller must
+ * have privilege.
*/
- if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
+ if ((uid != ip->i_uid ||
(gid != ip->i_gid && !groupmember(gid, cred))) &&
(error = suser_xxx(cred, p, PRISON_ROOT)))
return (error);
@@ -1095,15 +1119,14 @@ abortit:
if (xp->i_number == ip->i_number)
panic("ufs_rename: same file");
/*
- * If the parent directory is "sticky", then the user must
- * own the parent directory, or the destination of the rename,
- * otherwise the destination may not be changed (except by
- * root). This implements append-only directories.
+ * If the parent directory is "sticky", then the caller
+ * must possess VADMIN for the parent directory, or the
+ * destination of the rename. This implements append-only
+ * directories.
*/
if ((dp->i_mode & S_ISTXT) &&
- suser_xxx(tcnp->cn_cred, NULL, PRISON_ROOT) &&
- tcnp->cn_cred->cr_uid != dp->i_uid &&
- xp->i_uid != tcnp->cn_cred->cr_uid) {
+ VOP_ACCESS(tdvp, VADMIN, tcnp->cn_cred, p) &&
+ VOP_ACCESS(tvp, VADMIN, tcnp->cn_cred, p)) {
error = EPERM;
goto bad;
}
OpenPOWER on IntegriCloud