From d14eca6c8aa6d042c8c0bf0c1865ed74292e09a4 Mon Sep 17 00:00:00 2001 From: semarie Date: Mon, 26 Oct 2015 07:24:20 +0000 Subject: [PATCH] make pledge_check(), used for syscall check with pledge, returns an error and provide the required pledge request for pledge_fail(). ok deraadt@ --- sys/kern/kern_pledge.c | 17 ++++++++++++----- sys/sys/pledge.h | 4 ++-- sys/sys/syscall_mi.h | 6 +++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 6a8e8e1fa58..1f8a029c59c 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.74 2015/10/25 20:39:54 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.75 2015/10/26 07:24:20 semarie Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -477,17 +477,24 @@ sys_pledge(struct proc *p, void *v, register_t *retval) } int -pledge_check(struct proc *p, int code) +pledge_check(struct proc *p, int code, int *tval) { p->p_pledgenote = p->p_pledgeafter = 0; /* XX optimise? */ p->p_pledge_syscall = code; + *tval = 0; if (code < 0 || code > SYS_MAXSYSCALL - 1) + return (EINVAL); + + if ((p->p_p->ps_pledge == 0) && + (code == SYS_exit || code == SYS_kbind)) return (0); - if (p->p_p->ps_pledge == 0) - return (code == SYS_exit || code == SYS_kbind); - return (p->p_p->ps_pledge & pledge_syscalls[code]); + if (p->p_p->ps_pledge & pledge_syscalls[code]) + return (0); + + *tval = pledge_syscalls[code]; + return (EPERM); } int diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h index d1c373fca18..062036907f0 100644 --- a/sys/sys/pledge.h +++ b/sys/sys/pledge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pledge.h,v 1.12 2015/10/25 20:39:54 deraadt Exp $ */ +/* $OpenBSD: pledge.h,v 1.13 2015/10/26 07:24:20 semarie Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -91,7 +91,7 @@ static struct { #ifdef _KERNEL -int pledge_check(struct proc *, int); +int pledge_check(struct proc *, int, int *); int pledge_fail(struct proc *, int, int); int pledge_namei(struct proc *, char *); void pledge_aftersyscall(struct proc *, int, int); diff --git a/sys/sys/syscall_mi.h b/sys/sys/syscall_mi.h index 0219db0663e..e944c0e0830 100644 --- a/sys/sys/syscall_mi.h +++ b/sys/sys/syscall_mi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall_mi.h,v 1.11 2015/10/09 01:17:18 deraadt Exp $ */ +/* $OpenBSD: syscall_mi.h,v 1.12 2015/10/26 07:24:20 semarie Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -72,10 +72,10 @@ mi_syscall(struct proc *p, register_t code, const struct sysent *callp, if (lock) KERNEL_LOCK(); pledged = (p->p_p->ps_flags & PS_PLEDGE); - if (pledged && !(tval = pledge_check(p, code))) { + if (pledged && (error = pledge_check(p, code, &tval))) { if (!lock) KERNEL_LOCK(); - error = pledge_fail(p, EPERM, tval); + error = pledge_fail(p, error, tval); KERNEL_UNLOCK(); return (error); } -- 2.20.1