introduces new promise "chown" to allow changing owner/group with *chown(2) family
authorsemarie <semarie@openbsd.org>
Sun, 3 Jul 2016 04:36:08 +0000 (04:36 +0000)
committersemarie <semarie@openbsd.org>
Sun, 3 Jul 2016 04:36:08 +0000 (04:36 +0000)
it splits PLEDGE_FATTR in two ("fattr" stills grant the 2 flags, so no functional changes):
  - PLEDGE_CHOWN : to be able to call *chown(2) syscalls
  - PLEDGE_FATTR : the rest

it introduces "chown" which grant:
  - PLEDGE_CHOWN : be able to call *chown(2)
  - PLEDGE_CHOWNUID : be able to modifying owner/group

ok deraadt@ tedu@

lib/libc/sys/pledge.2
sys/kern/kern_pledge.c
sys/kern/vfs_syscalls.c
sys/sys/pledge.h

index 0cc0136..85849f2 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pledge.2,v 1.32 2016/04/13 14:24:30 tb Exp $
+.\" $OpenBSD: pledge.2,v 1.33 2016/07/03 04:36:08 semarie Exp $
 .\"
 .\" Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: April 13 2016 $
+.Dd $Mdocdate: July 3 2016 $
 .Dt PLEDGE 2
 .Os
 .Sh NAME
@@ -318,6 +318,10 @@ relating to a file:
 .Xr lchown 2 ,
 .Xr fchown 2 ,
 .Xr utimes 2 .
+.It Va "chown"
+The
+.Xr chown 2
+family is allowed to change the user or group on a file.
 .It Va "flock"
 File locking via
 .Xr fcntl 2 ,
index f72f27d..8e2180a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_pledge.c,v 1.173 2016/06/28 04:27:58 semarie Exp $       */
+/*     $OpenBSD: kern_pledge.c,v 1.174 2016/07/03 04:36:08 semarie Exp $       */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -333,10 +333,11 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = {
        [SYS_chflags] = PLEDGE_FATTR,
        [SYS_chflagsat] = PLEDGE_FATTR,
        [SYS_fchflags] = PLEDGE_FATTR,
-       [SYS_chown] = PLEDGE_FATTR,
-       [SYS_fchownat] = PLEDGE_FATTR,
-       [SYS_lchown] = PLEDGE_FATTR,
-       [SYS_fchown] = PLEDGE_FATTR,
+
+       [SYS_chown] = PLEDGE_CHOWN,
+       [SYS_fchownat] = PLEDGE_CHOWN,
+       [SYS_lchown] = PLEDGE_CHOWN,
+       [SYS_fchown] = PLEDGE_CHOWN,
 
        [SYS_socket] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE,
        [SYS_connect] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE,
@@ -358,13 +359,14 @@ static const struct {
        uint64_t flags;
 } pledgereq[] = {
        { "audio",              PLEDGE_AUDIO },
+       { "chown",              PLEDGE_CHOWN | PLEDGE_CHOWNUID },
        { "cpath",              PLEDGE_CPATH },
        { "disklabel",          PLEDGE_DISKLABEL },
        { "dns",                PLEDGE_DNS },
        { "dpath",              PLEDGE_DPATH },
        { "drm",                PLEDGE_DRM },
        { "exec",               PLEDGE_EXEC },
-       { "fattr",              PLEDGE_FATTR },
+       { "fattr",              PLEDGE_FATTR | PLEDGE_CHOWN },
        { "flock",              PLEDGE_FLOCK },
        { "getpw",              PLEDGE_GETPW },
        { "id",                 PLEDGE_ID },
@@ -1066,6 +1068,9 @@ pledge_chown(struct proc *p, uid_t uid, gid_t gid)
        if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
                return (0);
 
+       if (p->p_p->ps_pledge & PLEDGE_CHOWNUID)
+               return (0);
+
        if (uid != -1 && uid != p->p_ucred->cr_uid)
                return (EPERM);
        if (gid != -1 && !groupmember(gid, p->p_ucred))
index 8593d17..4378e3d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vfs_syscalls.c,v 1.259 2016/06/27 04:26:41 semarie Exp $      */
+/*     $OpenBSD: vfs_syscalls.c,v 1.260 2016/07/03 04:36:08 semarie Exp $      */
 /*     $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $        */
 
 /*
@@ -2091,7 +2091,7 @@ dofchownat(struct proc *p, int fd, const char *path, uid_t uid, gid_t gid,
 
        follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
        NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p);
-       nd.ni_pledge = PLEDGE_FATTR | PLEDGE_RPATH;
+       nd.ni_pledge = PLEDGE_CHOWN | PLEDGE_RPATH;
        if ((error = namei(&nd)) != 0)
                return (error);
        vp = nd.ni_vp;
@@ -2142,7 +2142,7 @@ sys_lchown(struct proc *p, void *v, register_t *retval)
        gid_t gid = SCARG(uap, gid);
 
        NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
-       nd.ni_pledge = PLEDGE_FATTR | PLEDGE_RPATH;
+       nd.ni_pledge = PLEDGE_CHOWN | PLEDGE_RPATH;
        if ((error = namei(&nd)) != 0)
                return (error);
        vp = nd.ni_vp;
index 0db6d10..586da85 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pledge.h,v 1.28 2016/04/28 14:25:08 beck Exp $        */
+/*     $OpenBSD: pledge.h,v 1.29 2016/07/03 04:36:08 semarie Exp $     */
 
 /*
  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -56,6 +56,8 @@
 #define PLEDGE_DPATH   0x0000000010000000ULL   /* mknod & mkfifo */
 #define PLEDGE_DRM     0x0000000020000000ULL   /* drm ioctls */
 #define PLEDGE_VMM     0x0000000040000000ULL   /* vmm ioctls */
+#define PLEDGE_CHOWN   0x0000000080000000ULL   /* chown(2) family */
+#define PLEDGE_CHOWNUID        0x0000000100000000ULL   /* allow owner/group changes */
 
 /*
  * Bits outside PLEDGE_USERSET are used by the kernel itself
@@ -100,6 +102,7 @@ static struct {
        { PLEDGE_DPATH,         "dpath" },
        { PLEDGE_DRM,           "drm" },
        { PLEDGE_VMM,           "vmm" },
+       { PLEDGE_CHOWNUID,      "chown" },
        { 0, NULL },
 };
 #endif