When pledged with "fattr", allow chown to supplimentary groups. This
authorderaadt <deraadt@openbsd.org>
Wed, 14 Oct 2015 14:24:03 +0000 (14:24 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 14 Oct 2015 14:24:03 +0000 (14:24 +0000)
came out of a discussion regarding "sort foo -o foo".
ok semarie

sys/kern/kern_pledge.c
sys/kern/vfs_syscalls.c
sys/sys/pledge.h

index c36ae6b..b37f95a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_pledge.c,v 1.24 2015/10/14 04:05:43 deraadt Exp $        */
+/*     $OpenBSD: kern_pledge.c,v 1.25 2015/10/14 14:24:03 deraadt Exp $        */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -912,6 +912,18 @@ pledge_sysctl_check(struct proc *p, int miblen, int *mib, void *new)
        return (EFAULT);
 }
 
+int
+pledge_chown_check(struct proc *p, uid_t uid, gid_t gid)
+{
+       if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
+               return (0);
+       if (uid != -1 && uid != p->p_ucred->cr_uid)
+               return (EPERM);
+       if (gid != -1 && !groupmember(gid, p->p_ucred))
+               return (EPERM);
+       return (0);
+}
+
 int
 pledge_adjtime_check(struct proc *p, const void *v)
 {
index af85e9a..584b541 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_syscalls.c,v 1.229 2015/10/09 01:10:27 deraadt Exp $      */
+/*     $OpenBSD: vfs_syscalls.c,v 1.230 2015/10/14 14:24:03 deraadt Exp $      */
 /*     $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $        */
 
 /*
@@ -49,6 +49,7 @@
 #include <sys/vnode.h>
 #include <sys/mount.h>
 #include <sys/proc.h>
+#include <sys/pledge.h>
 #include <sys/uio.h>
 #include <sys/malloc.h>
 #include <sys/pool.h>
@@ -2102,12 +2103,8 @@ dofchownat(struct proc *p, int fd, const char *path, uid_t uid, gid_t gid,
        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                error = EROFS;
        else {
-               if ((p->p_p->ps_flags & PS_PLEDGE) &&
-                   ((uid != -1 && uid != p->p_ucred->cr_uid) ||
-                    (gid != -1 && gid != p->p_ucred->cr_gid))) {
-                       error = EPERM;
+               if ((error = pledge_chown_check(p, uid, gid)))
                        goto out;
-               }
                if ((uid != -1 || gid != -1) &&
                    (suser(p, 0) || suid_clear)) {
                        error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
@@ -2158,12 +2155,8 @@ sys_lchown(struct proc *p, void *v, register_t *retval)
        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                error = EROFS;
        else {
-               if ((p->p_p->ps_flags & PS_PLEDGE) &&
-                   ((uid != -1 && uid != p->p_ucred->cr_uid) ||
-                    (gid != -1 && gid != p->p_ucred->cr_gid))) {
-                       error = EPERM;
+               if ((error = pledge_chown_check(p, uid, gid)))
                        goto out;
-               }
                if ((uid != -1 || gid != -1) &&
                    (suser(p, 0) || suid_clear)) {
                        error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
@@ -2212,12 +2205,8 @@ sys_fchown(struct proc *p, void *v, register_t *retval)
        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                error = EROFS;
        else {
-               if ((p->p_p->ps_flags & PS_PLEDGE) &&
-                   ((uid != -1 && uid != p->p_ucred->cr_uid) ||
-                    (gid != -1 && gid != p->p_ucred->cr_gid))) {
-                       error = EPERM;
+               if ((error = pledge_chown_check(p, uid, gid)))
                        goto out;
-               }
                if ((uid != -1 || gid != -1) &&
                    (suser(p, 0) || suid_clear)) {
                        error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
index 583ef86..534629f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pledge.h,v 1.1 2015/10/09 01:10:27 deraadt Exp $      */
+/*     $OpenBSD: pledge.h,v 1.2 2015/10/14 14:24:03 deraadt Exp $      */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -64,6 +64,7 @@ struct mbuf;
 int    pledge_cmsg_send(struct proc *p, struct mbuf *control);
 int    pledge_cmsg_recv(struct proc *p, struct mbuf *control);
 int    pledge_sysctl_check(struct proc *p, int namelen, int *name, void *new);
+int    pledge_chown_check(struct proc *p, uid_t, gid_t);
 int    pledge_adjtime_check(struct proc *p, const void *v);
 int    pledge_recvfrom_check(struct proc *p, void *from);
 int    pledge_sendto_check(struct proc *p, const void *to);