Module Name: src Committed By: hannken Date: Wed Nov 28 10:01:28 UTC 2018
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_vnops.c src/tests/fs/vfs: t_unpriv.c Log Message: Redo the access check for setting va_flags in zfs_netbsd_setattr(). Use user flag UF_NODUMP instead of UF_IMMUTABLE for the test as it is the only user flag supported by all tested file systems. PR kern/47656 test zfs_flags. To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c cvs rdiff -u -r1.15 -r1.16 src/tests/fs/vfs/t_unpriv.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.34 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.35 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c:1.34 Wed Nov 28 09:58:58 2018 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vnops.c Wed Nov 28 10:01:28 2018 @@ -5345,9 +5345,11 @@ zfs_netbsd_setattr(void *v) cred_t *cred = ap->a_cred; znode_t *zp = VTOZ(vp); xvattr_t xvap; - u_long fflags; + kauth_action_t action; + u_long fflags, sfflags = 0; uint64_t zflags; int error, flags = 0; + bool changing_sysflags; vattr_init_mask(vap); vap->va_mask &= ~AT_NOSET; @@ -5365,40 +5367,14 @@ zfs_netbsd_setattr(void *v) fflags = vap->va_flags; if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0) return (EOPNOTSUPP); - /* - * Callers may only modify the file flags on objects they - * have VADMIN rights for. - */ - if ((error = VOP_ACCESS(vp, VWRITE, cred)) != 0) - return (error); - /* - * Unprivileged processes are not permitted to unset system - * flags, or modify flags if any system flags are set. - * Privileged non-jail processes may not modify system flags - * if securelevel > 0 and any existing system flags are set. - * Privileged jail processes behave like privileged non-jail - * processes if the security.jail.chflags_allowed sysctl is - * is non-zero; otherwise, they behave like unprivileged - * processes. - */ - if (kauth_authorize_system(cred, KAUTH_SYSTEM_CHSYSFLAGS, 0, - NULL, NULL, NULL) != 0) { - - if (zflags & - (ZFS_IMMUTABLE | ZFS_APPENDONLY | ZFS_NOUNLINK)) { - return (EPERM); - } - if (fflags & - (SF_IMMUTABLE | SF_APPEND | SF_NOUNLINK)) { - return (EPERM); - } - } #define FLAG_CHANGE(fflag, zflag, xflag, xfield) do { \ if (((fflags & (fflag)) && !(zflags & (zflag))) || \ ((zflags & (zflag)) && !(fflags & (fflag)))) { \ XVA_SET_REQ(&xvap, (xflag)); \ (xfield) = ((fflags & (fflag)) != 0); \ + if (((fflag) & SF_SETTABLE) != 0) \ + sfflags |= (fflag); \ } \ } while (0) /* Convert chflags into ZFS-type flags. */ @@ -5412,6 +5388,23 @@ zfs_netbsd_setattr(void *v) FLAG_CHANGE(UF_NODUMP, ZFS_NODUMP, XAT_NODUMP, xvap.xva_xoptattrs.xoa_nodump); #undef FLAG_CHANGE + + action = KAUTH_VNODE_WRITE_FLAGS; + changing_sysflags = false; + + if (zflags & (ZFS_IMMUTABLE|ZFS_APPENDONLY|ZFS_NOUNLINK)) { + action |= KAUTH_VNODE_HAS_SYSFLAGS; + } + if (sfflags != 0) { + action |= KAUTH_VNODE_WRITE_SYSFLAGS; + changing_sysflags = true; + } + + error = kauth_authorize_vnode(cred, action, vp, NULL, + genfs_can_chflags(cred, vp->v_type, zp->z_uid, + changing_sysflags)); + if (error) + return error; } if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || Index: src/tests/fs/vfs/t_unpriv.c diff -u src/tests/fs/vfs/t_unpriv.c:1.15 src/tests/fs/vfs/t_unpriv.c:1.16 --- src/tests/fs/vfs/t_unpriv.c:1.15 Wed Nov 28 09:58:58 2018 +++ src/tests/fs/vfs/t_unpriv.c Wed Nov 28 10:01:28 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: t_unpriv.c,v 1.15 2018/11/28 09:58:58 hannken Exp $ */ +/* $NetBSD: t_unpriv.c,v 1.16 2018/11/28 10:01:28 hannken Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -187,20 +187,18 @@ flags(const atf_tc_t *tc, const char *mp if (rump_sys_stat(name, &st) == -1) atf_tc_fail_errno("stat"); - if (FSTYPE_ZFS(tc)) - atf_tc_expect_fail("PR kern/47656: Test known to be broken"); if (rump_sys_chflags(name, st.st_flags) == -1) { if (errno == EOPNOTSUPP) atf_tc_skip("file flags not supported by file system"); atf_tc_fail_errno("chflags"); } - fflags = st.st_flags | UF_IMMUTABLE; + fflags = st.st_flags | UF_NODUMP; rump_pub_lwproc_rfork(RUMP_RFCFDG); if (rump_sys_setuid(1) == -1) atf_tc_fail_errno("setuid"); - fflags |= UF_IMMUTABLE; + fflags |= UF_NODUMP; if (rump_sys_chflags(name, fflags) != -1 || errno != EPERM) atf_tc_fail_errno("chflags"); rump_pub_lwproc_releaselwp(); @@ -208,7 +206,7 @@ flags(const atf_tc_t *tc, const char *mp if (rump_sys_chflags(name, fflags) == -1) atf_tc_fail_errno("chflags"); - fflags &= ~UF_IMMUTABLE; + fflags &= ~UF_NODUMP; if (rump_sys_chflags(name, fflags) == -1) atf_tc_fail_errno("chflags");