From 1d0044e1a18fd369520e5d95af6cbac838a7ade8 Mon Sep 17 00:00:00 2001 From: semarie Date: Sun, 3 Jul 2016 04:36:08 +0000 Subject: [PATCH] introduces new promise "chown" to allow changing owner/group with *chown(2) family 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 | 8 ++++++-- sys/kern/kern_pledge.c | 17 +++++++++++------ sys/kern/vfs_syscalls.c | 6 +++--- sys/sys/pledge.h | 5 ++++- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/libc/sys/pledge.2 b/lib/libc/sys/pledge.2 index 0cc0136451b..85849f27216 100644 --- a/lib/libc/sys/pledge.2 +++ b/lib/libc/sys/pledge.2 @@ -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 .\" @@ -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 , diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index f72f27d1d44..8e2180abd94 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -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 @@ -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)) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 8593d170f7a..4378e3d3c1a 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -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; diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h index 0db6d10ad1c..586da853ceb 100644 --- a/sys/sys/pledge.h +++ b/sys/sys/pledge.h @@ -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 @@ -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 -- 2.20.1