diff options
author | natano <natano@openbsd.org> | 2018-12-23 10:46:51 +0000 |
---|---|---|
committer | natano <natano@openbsd.org> | 2018-12-23 10:46:51 +0000 |
commit | eae075513215a8fc3d71561da8bc7465610a0457 (patch) | |
tree | b92b3ef5b6f520d7dbd88f1e45924b3fc1ed03d5 /sys/ufs | |
parent | EVP_MD_CTX_cleanup() is deprecated and doesn't free, so recommend using (diff) | |
download | wireguard-openbsd-eae075513215a8fc3d71561da8bc7465610a0457.tar.xz wireguard-openbsd-eae075513215a8fc3d71561da8bc7465610a0457.zip |
Rectify some issues with the noperm mount flag; the root vnode was not
protected properly and files without any x bit set were accidentaly considered
executable when checked with access(2).
Issues found and reported by deraadt, halex, reyk, tb
ok deraadt
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 4 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 4 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 41 |
3 files changed, 26 insertions, 23 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 09ca4bd0914..f5cf41063c6 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ffs_vnops.c,v 1.92 2018/07/21 09:35:08 anton Exp $ */ +/* $OpenBSD: ffs_vnops.c,v 1.93 2018/12/23 10:46:51 natano Exp $ */ /* $NetBSD: ffs_vnops.c,v 1.7 1996/05/11 18:27:24 mycroft Exp $ */ /* @@ -391,7 +391,7 @@ ffs_write(void *v) * tampering. */ if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0 && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0) + !vnoperm(vp)) DIP_ASSIGN(ip, mode, DIP(ip, mode) & ~(ISUID | ISGID)); if (resid > uio->uio_resid) VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0)); diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 448edb5a3f2..3825de24188 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs_lookup.c,v 1.53 2018/09/06 11:50:54 jsg Exp $ */ +/* $OpenBSD: ufs_lookup.c,v 1.54 2018/12/23 10:46:51 natano Exp $ */ /* $NetBSD: ufs_lookup.c,v 1.7 1996/02/09 22:36:06 christos Exp $ */ /* @@ -496,7 +496,7 @@ found: if ((DIP(dp, mode) & ISVTX) && cred->cr_uid != 0 && cred->cr_uid != DIP(dp, uid) && - (vdp->v_mount->mnt_flag & MNT_NOPERM) == 0 && + !vnoperm(vdp) && DIP(VTOI(tdp), uid) != cred->cr_uid) { vput(tdp); return (EPERM); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 20f2a179e6b..82ebd356af0 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs_vnops.c,v 1.142 2018/06/21 14:17:23 visa Exp $ */ +/* $OpenBSD: ufs_vnops.c,v 1.143 2018/12/23 10:46:51 natano Exp $ */ /* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */ /* @@ -274,9 +274,13 @@ ufs_access(void *v) if ((mode & VWRITE) && (DIP(ip, flags) & IMMUTABLE)) return (EPERM); - if ((vp->v_mount->mnt_flag & MNT_NOPERM) && - (vp->v_flag & VROOT) == 0) - return (0); + if (vnoperm(vp)) { + /* For VEXEC, at least one of the execute bits must be set. */ + if ((mode & VEXEC) && vp->v_type != VDIR && + (DIP(ip, mode) & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) + return EACCES; + return 0; + } return (vaccess(vp->v_type, DIP(ip, mode), DIP(ip, uid), DIP(ip, gid), mode, ap->a_cred)); @@ -353,10 +357,10 @@ ufs_setattr(void *v) if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); if (cred->cr_uid != DIP(ip, uid) && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0 && + !vnoperm(vp) && (error = suser_ucred(cred))) return (error); - if (cred->cr_uid == 0) { + if (cred->cr_uid == 0 || vnoperm(vp)) { if ((DIP(ip, flags) & (SF_IMMUTABLE | SF_APPEND)) && securelevel > 0) return (EPERM); @@ -413,7 +417,7 @@ ufs_setattr(void *v) if (vp->v_mount->mnt_flag & MNT_RDONLY) return (EROFS); if (cred->cr_uid != DIP(ip, uid) && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0 && + !vnoperm(vp) && (error = suser_ucred(cred)) && ((vap->va_vaflags & VA_UTIMES_NULL) == 0 || (error = VOP_ACCESS(vp, VWRITE, cred, p)))) @@ -461,11 +465,10 @@ ufs_chmod(struct vnode *vp, int mode, struct ucred *cred, struct proc *p) int error; if (cred->cr_uid != DIP(ip, uid) && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0 && + !vnoperm(vp) && (error = suser_ucred(cred))) return (error); - if (cred->cr_uid && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0) { + if (cred->cr_uid && !vnoperm(vp)) { if (vp->v_type != VDIR && (mode & S_ISTXT)) return (EFTYPE); if (!groupmember(DIP(ip, gid), cred) && (mode & ISGID)) @@ -505,7 +508,7 @@ ufs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred, */ if ((cred->cr_uid != DIP(ip, uid) || uid != DIP(ip, uid) || (gid != DIP(ip, gid) && !groupmember(gid, cred))) && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0 && + !vnoperm(vp) && (error = suser_ucred(cred))) return (error); ogid = DIP(ip, gid); @@ -546,12 +549,12 @@ ufs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred, if (ouid != uid || ogid != gid) ip->i_flag |= IN_CHANGE; - if (ouid != uid && cred->cr_uid != 0 && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0) - DIP_AND(ip, mode, ~ISUID); - if (ogid != gid && cred->cr_uid != 0 && - (vp->v_mount->mnt_flag & MNT_NOPERM) == 0) - DIP_AND(ip, mode, ~ISGID); + if (!vnoperm(vp)) { + if (ouid != uid && cred->cr_uid != 0) + DIP_AND(ip, mode, ~ISUID); + if (ogid != gid && cred->cr_uid != 0) + DIP_AND(ip, mode, ~ISGID); + } return (0); error: @@ -975,7 +978,7 @@ abortit: if ((DIP(dp, mode) & S_ISTXT) && tcnp->cn_cred->cr_uid != 0 && tcnp->cn_cred->cr_uid != DIP(dp, uid) && DIP(xp, uid )!= tcnp->cn_cred->cr_uid && - (tdvp->v_mount->mnt_flag & MNT_NOPERM) == 0) { + !vnoperm(tdvp)) { error = EPERM; goto bad; } @@ -1853,7 +1856,7 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, softdep_change_linkcnt(ip, 0); if ((DIP(ip, mode) & ISGID) && !groupmember(DIP(ip, gid), cnp->cn_cred) && - (dvp->v_mount->mnt_flag & MNT_NOPERM) == 0 && + !vnoperm(dvp) && suser_ucred(cnp->cn_cred)) DIP_AND(ip, mode, ~ISGID); |