summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsemarie <semarie@openbsd.org>2015-10-28 13:59:07 +0000
committersemarie <semarie@openbsd.org>2015-10-28 13:59:07 +0000
commiteeb4c48f919cdbecdc14937c4a7bd6ab4fc6b215 (patch)
tree6d6fc3a9bb9d39c15ba5e1b6abd10e079c73e3eb
parentcanonpath() error isn't related to p_pledgenote requirement (only possible (diff)
downloadwireguard-openbsd-eeb4c48f919cdbecdc14937c4a7bd6ab4fc6b215.tar.xz
wireguard-openbsd-eeb4c48f919cdbecdc14937c4a7bd6ab4fc6b215.zip
refactor pledge_namei() a bit
- remove all explicit checks that ensure p_pledgenote have counterpart in ps_pledge by one unique check. It makes management of explicit whitelisted operations on some paths more simple to manage. And now, we can use p_pledgenote for more fined checking in namei usage. - add special case for unsetted p_pledgenote: the behaviour is the same as previously (we allow the operation with "rpath", "wpath" or "cpath" request) but it should be changed soon to be more strict. "go ahead" deraadt@
-rw-r--r--sys/kern/kern_pledge.c47
1 files changed, 18 insertions, 29 deletions
diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c
index 113fdbbf54e..6a50f2353cf 100644
--- a/sys/kern/kern_pledge.c
+++ b/sys/kern/kern_pledge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_pledge.c,v 1.86 2015/10/28 13:42:57 semarie Exp $ */
+/* $OpenBSD: kern_pledge.c,v 1.87 2015/10/28 13:59:07 semarie Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -550,12 +550,6 @@ pledge_namei(struct proc *p, char *origpath)
if (error)
return (pledge_fail(p, error, 0));
- /* chmod(2), chflags(2), ... */
- if ((p->p_pledgenote & PLEDGE_FATTR) &&
- (p->p_p->ps_pledge & PLEDGE_FATTR) == 0) {
- return (pledge_fail(p, EPERM, PLEDGE_FATTR));
- }
-
/* Detect what looks like a mkstemp(3) family operation */
if ((p->p_p->ps_pledge & PLEDGE_TMPPATH) &&
(p->p_pledge_syscall == SYS_open) &&
@@ -573,11 +567,6 @@ pledge_namei(struct proc *p, char *origpath)
return (0);
}
- /* open, mkdir, or other path creation operation */
- if ((p->p_pledgenote & PLEDGE_CPATH) &&
- ((p->p_p->ps_pledge & PLEDGE_CPATH) == 0))
- return (pledge_fail(p, EPERM, PLEDGE_CPATH));
-
/* Whitelisted read/write paths */
switch (p->p_pledge_syscall) {
case SYS_open:
@@ -596,11 +585,6 @@ pledge_namei(struct proc *p, char *origpath)
break;
}
- /* ensure PLEDGE_WPATH request for doing write */
- if ((p->p_pledgenote & PLEDGE_WPATH) &&
- (p->p_p->ps_pledge & PLEDGE_WPATH) == 0)
- return (pledge_fail(p, EPERM, PLEDGE_WPATH));
-
/* Whitelisted read-only paths */
switch (p->p_pledge_syscall) {
case SYS_access:
@@ -680,10 +664,22 @@ pledge_namei(struct proc *p, char *origpath)
break;
}
- /* ensure PLEDGE_RPATH request for doing read */
- if ((p->p_pledgenote & PLEDGE_RPATH) &&
- (p->p_p->ps_pledge & PLEDGE_RPATH) == 0)
- return (pledge_fail(p, EPERM, PLEDGE_RPATH));
+ /*
+ * Ensure each flag of p_pledgenote has counterpart allowing it in
+ * ps_pledge
+ */
+ if (p->p_pledgenote & ~p->p_p->ps_pledge)
+ return (pledge_fail(p, EPERM, (p->p_pledgenote &
+ ~p->p_p->ps_pledge)));
+
+ /* generic check for unsetted p_pledgenote */
+ if (p->p_pledgenote == 0) {
+ //printf("pledge_namei: %s(%d): syscall %d p_pledgenote=0\n",
+ // p->p_comm, p->p_pid, p->p_pledge_syscall);
+
+ if ((p->p_p->ps_pledge & (PLEDGE_RPATH | PLEDGE_WPATH | PLEDGE_CPATH)) == 0)
+ return (pledge_fail(p, EPERM, PLEDGE_RPATH));
+ }
/*
* If a whitelist is set, compare canonical paths. Anything
@@ -779,14 +775,7 @@ pledge_namei(struct proc *p, char *origpath)
return (error); /* Don't hint why it failed */
}
- if (p->p_p->ps_pledge & PLEDGE_RPATH)
- return (0);
- if (p->p_p->ps_pledge & PLEDGE_WPATH)
- return (0);
- if (p->p_p->ps_pledge & PLEDGE_CPATH)
- return (0);
-
- return (pledge_fail(p, EPERM, p->p_pledgenote));
+ return (0);
}
void