From: cheloha Date: Fri, 2 Jun 2023 17:44:29 +0000 (+0000) Subject: pledge(2): stdio: permit restricted profil(2) for moncontrol(3) X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=b7a7cb6aecabdb49bf7d40b2372c9608cf08b53b;p=openbsd pledge(2): stdio: permit restricted profil(2) for moncontrol(3) Currently, pledged '-pg' binaries get killed in _mcleanup() when they try to disable profil(2) via moncontrol(3). Disabling profil(2) is harmless. Add profil(2) to the "stdio" pledge(2) promise and permit profil(2) calls when the scale argument is zero. Enabling profil(2) remains forbidden in pledged processes. This gets us one step closer to making '-pg' binaries compatible with pledge(2). The next step is to decide how to exfiltrate the profiling data from the process during _mcleanup(). Prompted by semarie@. Cleaned up by deraadt@. With input from deraadt@, espie@, and semarie@. "Looks good" deraadt@ pledge(2) pieces ok semarie@ --- diff --git a/lib/libc/sys/pledge.2 b/lib/libc/sys/pledge.2 index 678396c5c25..5cca1fb17ce 100644 --- a/lib/libc/sys/pledge.2 +++ b/lib/libc/sys/pledge.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pledge.2,v 1.65 2023/05/19 01:12:23 guenther Exp $ +.\" $OpenBSD: pledge.2,v 1.66 2023/06/02 17:44:29 cheloha 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: May 19 2023 $ +.Dd $Mdocdate: June 2 2023 $ .Dt PLEDGE 2 .Os .Sh NAME @@ -134,6 +134,8 @@ May open .Pa /etc/localtime and any files below .Pa /usr/share/zoneinfo . +.It Xr profil 2 : +Can only disable profiling. .It Fn pledge : Can only reduce permissions for .Fa promises @@ -209,6 +211,7 @@ As a result, all the expected functionalities of libc stdio work. .Xr poll 2 , .Xr pread 2 , .Xr preadv 2 , +.Xr profil 2 , .Xr pwrite 2 , .Xr pwritev 2 , .Xr read 2 , diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 15a0ae32ab8..de98202776c 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.305 2023/05/19 01:12:23 guenther Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.306 2023/06/02 17:44:29 cheloha Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -145,6 +145,9 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = { */ [SYS_sysctl] = PLEDGE_STDIO, + /* For moncontrol(3). Only allowed to disable profiling. */ + [SYS_profil] = PLEDGE_STDIO, + /* Support for malloc(3) family of operations */ [SYS_getentropy] = PLEDGE_STDIO, [SYS_madvise] = PLEDGE_STDIO, @@ -1586,6 +1589,16 @@ pledge_kill(struct proc *p, pid_t pid) return pledge_fail(p, EPERM, PLEDGE_PROC); } +int +pledge_profil(struct proc *p, u_int scale) +{ + if ((p->p_p->ps_flags & PS_PLEDGE) == 0) + return 0; + if (scale != 0) + return pledge_fail(p, EPERM, PLEDGE_STDIO); + return 0; +} + int pledge_protexec(struct proc *p, int prot) { diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 432c5e2246d..a93b6df9887 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prof.c,v 1.34 2023/05/30 08:30:01 jsg Exp $ */ +/* $OpenBSD: subr_prof.c,v 1.35 2023/06/02 17:44:29 cheloha Exp $ */ /* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */ /*- @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -236,7 +237,11 @@ sys_profil(struct proc *p, void *v, register_t *retval) } */ *uap = v; struct process *pr = p->p_p; struct uprof *upp; - int s; + int error, s; + + error = pledge_profil(p, SCARG(uap, scale)); + if (error) + return error; if (SCARG(uap, scale) > (1 << 16)) return (EINVAL); diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h index 6098fb7fd5c..073ad9a050a 100644 --- a/sys/sys/pledge.h +++ b/sys/sys/pledge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pledge.h,v 1.47 2022/09/01 05:40:46 jsg Exp $ */ +/* $OpenBSD: pledge.h,v 1.48 2023/06/02 17:44:29 cheloha Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -138,6 +138,7 @@ int pledge_flock(struct proc *p); int pledge_fcntl(struct proc *p, int cmd); int pledge_swapctl(struct proc *p, int cmd); int pledge_kill(struct proc *p, pid_t pid); +int pledge_profil(struct proc *, u_int); int pledge_protexec(struct proc *p, int prot); #endif /* _KERNEL */