From 91bc69b80d8c05b03476ea3b34fefd833b593f98 Mon Sep 17 00:00:00 2001 From: deraadt Date: Sun, 25 Oct 2015 20:39:54 +0000 Subject: [PATCH] Fold "malloc" into "stdio" and -- recognizing that no program so far has used less than "stdio" -- include all the "self" operations. Instead of different defines, use regular PLEDGE_* in the "p_pledgenote" variable (which indicates the operation subtype a system call is performing). Many checks before easier to understand. p_pledgenote can often be passed directly to ktrace, so that kdump says: 15565 test CALL pledge(0xa9a3f804c51,0) 15565 test STRU pledge request="stdio" 15565 test RET pledge 0 15565 test CALL open(0xa9a3f804c57,0x2) 15565 test NAMI "/tmp/testfile" 15565 test PLDG open, "wpath", errno 1 Operation not permitted with help from semarie, ok guenther --- sys/kern/kern_exec.c | 4 +- sys/kern/kern_ktrace.c | 21 ++- sys/kern/kern_pledge.c | 308 ++++++++++++++++++++------------------- sys/kern/kern_sig.c | 6 +- sys/kern/kern_sysctl.c | 8 +- sys/kern/uipc_syscalls.c | 7 +- sys/kern/uipc_usrreq.c | 6 +- sys/kern/vfs_syscalls.c | 54 +++---- sys/sys/ktrace.h | 14 +- sys/sys/pledge.h | 69 ++++++--- sys/sys/proc.h | 10 +- usr.bin/kdump/kdump.c | 37 ++++- usr.bin/ktrace/ktrace.h | 4 +- 13 files changed, 326 insertions(+), 222 deletions(-) diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 8b3f0e5e50d..168bdd12f9c 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.169 2015/10/10 14:46:15 deraadt Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.170 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -280,7 +280,7 @@ sys_execve(struct proc *p, void *v, register_t *retval) * Mark this process as "leave me alone, I'm execing". */ atomic_setbits_int(&pr->ps_flags, PS_INEXEC); - p->p_pledgenote = TMN_XPATH; + p->p_pledgenote = PLEDGE_EXEC; #if NSYSTRACE > 0 if (ISSET(p->p_flag, P_SYSTRACE)) { diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 5d34952665c..e1727956af9 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_ktrace.c,v 1.80 2015/10/09 01:10:27 deraadt Exp $ */ +/* $OpenBSD: kern_ktrace.c,v 1.81 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */ /* @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -398,6 +399,22 @@ ktrexec(struct proc *p, int type, const char *data, ssize_t len) atomic_clearbits_int(&p->p_flag, P_INKTR); } +void +ktrpledge(struct proc *p, int error, int code, int syscall) +{ + struct ktr_header kth; + struct ktr_pledge kp; + + atomic_setbits_int(&p->p_flag, P_INKTR); + ktrinitheader(&kth, p, KTR_PLEDGE); + kp.error = error; + kp.code = code; + kp.syscall = syscall; + + ktrwrite(p, &kth, &kp, sizeof(kp)); + atomic_clearbits_int(&p->p_flag, P_INKTR); +} + /* Interface and common routines */ /* @@ -429,7 +446,7 @@ sys_ktrace(struct proc *p, void *v, register_t *retval) * an operation which requires a file argument. */ cred = p->p_ucred; - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, fname), p); if ((error = vn_open(&nd, FREAD|FWRITE|O_NOFOLLOW, 0)) != 0) diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 7e8a6f9cda5..6a8e8e1fa58 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.73 2015/10/25 17:45:29 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.74 2015/10/25 20:39:54 deraadt Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -51,6 +51,7 @@ #include #include #include +#define PLEDGENAMES #include #include "pty.h" @@ -63,107 +64,107 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_kbind] = 0xffffffff, [SYS___get_tcb] = 0xffffffff, - [SYS_getuid] = PLEDGE_SELF, - [SYS_geteuid] = PLEDGE_SELF, - [SYS_getresuid] = PLEDGE_SELF, - [SYS_getgid] = PLEDGE_SELF, - [SYS_getegid] = PLEDGE_SELF, - [SYS_getresgid] = PLEDGE_SELF, - [SYS_getgroups] = PLEDGE_SELF, - [SYS_getlogin] = PLEDGE_SELF, - [SYS_getpgrp] = PLEDGE_SELF, - [SYS_getpgid] = PLEDGE_SELF, - [SYS_getppid] = PLEDGE_SELF, - [SYS_getsid] = PLEDGE_SELF, - [SYS_getthrid] = PLEDGE_SELF, - [SYS_getrlimit] = PLEDGE_SELF, - [SYS_gettimeofday] = PLEDGE_SELF, - [SYS_getdtablecount] = PLEDGE_SELF, - [SYS_getrusage] = PLEDGE_SELF, - [SYS_issetugid] = PLEDGE_SELF, - [SYS_clock_getres] = PLEDGE_SELF, - [SYS_clock_gettime] = PLEDGE_SELF, - [SYS_getpid] = PLEDGE_SELF, - [SYS_umask] = PLEDGE_SELF, - [SYS_sysctl] = PLEDGE_SELF, /* read-only; narrow subset */ - - [SYS_setsockopt] = PLEDGE_SELF, /* white list */ - [SYS_getsockopt] = PLEDGE_SELF, - - [SYS_fchdir] = PLEDGE_SELF, /* careful of directory fd inside jails */ + [SYS_getuid] = PLEDGE_STDIO, + [SYS_geteuid] = PLEDGE_STDIO, + [SYS_getresuid] = PLEDGE_STDIO, + [SYS_getgid] = PLEDGE_STDIO, + [SYS_getegid] = PLEDGE_STDIO, + [SYS_getresgid] = PLEDGE_STDIO, + [SYS_getgroups] = PLEDGE_STDIO, + [SYS_getlogin] = PLEDGE_STDIO, + [SYS_getpgrp] = PLEDGE_STDIO, + [SYS_getpgid] = PLEDGE_STDIO, + [SYS_getppid] = PLEDGE_STDIO, + [SYS_getsid] = PLEDGE_STDIO, + [SYS_getthrid] = PLEDGE_STDIO, + [SYS_getrlimit] = PLEDGE_STDIO, + [SYS_gettimeofday] = PLEDGE_STDIO, + [SYS_getdtablecount] = PLEDGE_STDIO, + [SYS_getrusage] = PLEDGE_STDIO, + [SYS_issetugid] = PLEDGE_STDIO, + [SYS_clock_getres] = PLEDGE_STDIO, + [SYS_clock_gettime] = PLEDGE_STDIO, + [SYS_getpid] = PLEDGE_STDIO, + [SYS_umask] = PLEDGE_STDIO, + [SYS_sysctl] = PLEDGE_STDIO, /* read-only; narrow subset */ + + [SYS_setsockopt] = PLEDGE_STDIO, /* white list */ + [SYS_getsockopt] = PLEDGE_STDIO, + + [SYS_fchdir] = PLEDGE_STDIO, /* careful of directory fd inside jails */ /* needed by threaded programs */ [SYS___tfork] = PLEDGE_PROC, - [SYS_sched_yield] = PLEDGE_SELF, - [SYS___thrsleep] = PLEDGE_SELF, - [SYS___thrwakeup] = PLEDGE_SELF, - [SYS___threxit] = PLEDGE_SELF, - [SYS___thrsigdivert] = PLEDGE_SELF, - - [SYS_sendsyslog] = PLEDGE_SELF, - [SYS_nanosleep] = PLEDGE_SELF, - [SYS_sigaltstack] = PLEDGE_SELF, - [SYS_sigprocmask] = PLEDGE_SELF, - [SYS_sigsuspend] = PLEDGE_SELF, - [SYS_sigaction] = PLEDGE_SELF, - [SYS_sigreturn] = PLEDGE_SELF, - [SYS_sigpending] = PLEDGE_SELF, - [SYS_getitimer] = PLEDGE_SELF, - [SYS_setitimer] = PLEDGE_SELF, - - [SYS_pledge] = PLEDGE_SELF, - - [SYS_wait4] = PLEDGE_SELF, - - [SYS_adjtime] = PLEDGE_SELF, /* read-only, unless "settime" */ + [SYS_sched_yield] = PLEDGE_STDIO, + [SYS___thrsleep] = PLEDGE_STDIO, + [SYS___thrwakeup] = PLEDGE_STDIO, + [SYS___threxit] = PLEDGE_STDIO, + [SYS___thrsigdivert] = PLEDGE_STDIO, + + [SYS_sendsyslog] = PLEDGE_STDIO, + [SYS_nanosleep] = PLEDGE_STDIO, + [SYS_sigaltstack] = PLEDGE_STDIO, + [SYS_sigprocmask] = PLEDGE_STDIO, + [SYS_sigsuspend] = PLEDGE_STDIO, + [SYS_sigaction] = PLEDGE_STDIO, + [SYS_sigreturn] = PLEDGE_STDIO, + [SYS_sigpending] = PLEDGE_STDIO, + [SYS_getitimer] = PLEDGE_STDIO, + [SYS_setitimer] = PLEDGE_STDIO, + + [SYS_pledge] = PLEDGE_STDIO, + + [SYS_wait4] = PLEDGE_STDIO, + + [SYS_adjtime] = PLEDGE_STDIO, /* read-only, unless "settime" */ [SYS_adjfreq] = PLEDGE_SETTIME, [SYS_settimeofday] = PLEDGE_SETTIME, - [SYS_poll] = PLEDGE_RW, - [SYS_kevent] = PLEDGE_RW, - [SYS_kqueue] = PLEDGE_RW, - [SYS_select] = PLEDGE_RW, - - [SYS_close] = PLEDGE_RW, - [SYS_dup] = PLEDGE_RW, - [SYS_dup2] = PLEDGE_RW, - [SYS_dup3] = PLEDGE_RW, - [SYS_closefrom] = PLEDGE_RW, - [SYS_shutdown] = PLEDGE_RW, - [SYS_read] = PLEDGE_RW, - [SYS_readv] = PLEDGE_RW, - [SYS_pread] = PLEDGE_RW, - [SYS_preadv] = PLEDGE_RW, - [SYS_write] = PLEDGE_RW, - [SYS_writev] = PLEDGE_RW, - [SYS_pwrite] = PLEDGE_RW, - [SYS_pwritev] = PLEDGE_RW, - [SYS_ftruncate] = PLEDGE_RW, - [SYS_lseek] = PLEDGE_RW, - [SYS_fstat] = PLEDGE_RW, - - [SYS_fcntl] = PLEDGE_RW, - [SYS_fsync] = PLEDGE_RW, - [SYS_pipe] = PLEDGE_RW, - [SYS_pipe2] = PLEDGE_RW, - [SYS_socketpair] = PLEDGE_RW, - [SYS_getdents] = PLEDGE_RW, - - [SYS_sendto] = PLEDGE_RW | PLEDGE_YP_ACTIVE, - [SYS_sendmsg] = PLEDGE_RW, - [SYS_recvmsg] = PLEDGE_RW, - [SYS_recvfrom] = PLEDGE_RW | PLEDGE_YP_ACTIVE, + [SYS_poll] = PLEDGE_STDIO, + [SYS_kevent] = PLEDGE_STDIO, + [SYS_kqueue] = PLEDGE_STDIO, + [SYS_select] = PLEDGE_STDIO, + + [SYS_close] = PLEDGE_STDIO, + [SYS_dup] = PLEDGE_STDIO, + [SYS_dup2] = PLEDGE_STDIO, + [SYS_dup3] = PLEDGE_STDIO, + [SYS_closefrom] = PLEDGE_STDIO, + [SYS_shutdown] = PLEDGE_STDIO, + [SYS_read] = PLEDGE_STDIO, + [SYS_readv] = PLEDGE_STDIO, + [SYS_pread] = PLEDGE_STDIO, + [SYS_preadv] = PLEDGE_STDIO, + [SYS_write] = PLEDGE_STDIO, + [SYS_writev] = PLEDGE_STDIO, + [SYS_pwrite] = PLEDGE_STDIO, + [SYS_pwritev] = PLEDGE_STDIO, + [SYS_ftruncate] = PLEDGE_STDIO, + [SYS_lseek] = PLEDGE_STDIO, + [SYS_fstat] = PLEDGE_STDIO, + + [SYS_fcntl] = PLEDGE_STDIO, + [SYS_fsync] = PLEDGE_STDIO, + [SYS_pipe] = PLEDGE_STDIO, + [SYS_pipe2] = PLEDGE_STDIO, + [SYS_socketpair] = PLEDGE_STDIO, + [SYS_getdents] = PLEDGE_STDIO, + + [SYS_sendto] = PLEDGE_STDIO | PLEDGE_YPACTIVE, + [SYS_sendmsg] = PLEDGE_STDIO, + [SYS_recvmsg] = PLEDGE_STDIO, + [SYS_recvfrom] = PLEDGE_STDIO | PLEDGE_YPACTIVE, [SYS_fork] = PLEDGE_PROC, [SYS_vfork] = PLEDGE_PROC, [SYS_setpgid] = PLEDGE_PROC, [SYS_setsid] = PLEDGE_PROC, - [SYS_kill] = PLEDGE_SELF | PLEDGE_PROC, + [SYS_kill] = PLEDGE_STDIO | PLEDGE_PROC, [SYS_setrlimit] = PLEDGE_PROC | PLEDGE_ID, [SYS_getpriority] = PLEDGE_PROC | PLEDGE_ID, - /* XXX we should limit the power for the "proc"-only case */ + /* XXX we should limit the power for the "proc"-only case */ [SYS_setpriority] = PLEDGE_PROC | PLEDGE_ID, [SYS_setuid] = PLEDGE_ID, @@ -178,20 +179,20 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_execve] = PLEDGE_EXEC, /* FIONREAD/FIONBIO, plus further checks in pledge_ioctl_check() */ - [SYS_ioctl] = PLEDGE_RW | PLEDGE_IOCTL | PLEDGE_TTY, + [SYS_ioctl] = PLEDGE_STDIO | PLEDGE_IOCTL | PLEDGE_TTY, - [SYS_getentropy] = PLEDGE_MALLOC, - [SYS_madvise] = PLEDGE_MALLOC, - [SYS_minherit] = PLEDGE_MALLOC, - [SYS_mmap] = PLEDGE_MALLOC, - [SYS_mprotect] = PLEDGE_MALLOC, - [SYS_mquery] = PLEDGE_MALLOC, - [SYS_munmap] = PLEDGE_MALLOC, + [SYS_getentropy] = PLEDGE_STDIO, + [SYS_madvise] = PLEDGE_STDIO, + [SYS_minherit] = PLEDGE_STDIO, + [SYS_mmap] = PLEDGE_STDIO, + [SYS_mprotect] = PLEDGE_STDIO, + [SYS_mquery] = PLEDGE_STDIO, + [SYS_munmap] = PLEDGE_STDIO, - [SYS_open] = PLEDGE_SELF, /* further checks in namei */ - [SYS_stat] = PLEDGE_SELF, /* further checks in namei */ - [SYS_access] = PLEDGE_SELF, /* further checks in namei */ - [SYS_readlink] = PLEDGE_SELF, /* further checks in namei */ + [SYS_open] = PLEDGE_STDIO, /* further checks in namei */ + [SYS_stat] = PLEDGE_STDIO, /* further checks in namei */ + [SYS_access] = PLEDGE_STDIO, /* further checks in namei */ + [SYS_readlink] = PLEDGE_STDIO, /* further checks in namei */ [SYS_chdir] = PLEDGE_RPATH, [SYS_chroot] = PLEDGE_ID, @@ -237,8 +238,8 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_lchown] = PLEDGE_FATTR, [SYS_fchown] = PLEDGE_FATTR, - [SYS_socket] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YP_ACTIVE, - [SYS_connect] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YP_ACTIVE, + [SYS_socket] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE, + [SYS_connect] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS | PLEDGE_YPACTIVE, [SYS_bind] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS, [SYS_getsockname] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS, @@ -251,7 +252,7 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_accept] = PLEDGE_INET | PLEDGE_UNIX, [SYS_getpeername] = PLEDGE_INET | PLEDGE_UNIX, - [SYS_flock] = PLEDGE_FLOCK | PLEDGE_YP_ACTIVE, + [SYS_flock] = PLEDGE_FLOCK | PLEDGE_YPACTIVE, [SYS_swapctl] = PLEDGE_VMINFO, /* XXX should limit to "get" operations */ }; @@ -260,18 +261,16 @@ static const struct { char *name; int flags; } pledgereq[] = { - { "malloc", PLEDGE_SELF | PLEDGE_MALLOC }, - { "rw", PLEDGE_SELF | PLEDGE_RW }, - { "stdio", PLEDGE_SELF | PLEDGE_MALLOC | PLEDGE_RW }, - { "rpath", PLEDGE_SELF | PLEDGE_RW | PLEDGE_RPATH }, - { "wpath", PLEDGE_SELF | PLEDGE_RW | PLEDGE_WPATH }, - { "tmppath", PLEDGE_SELF | PLEDGE_RW | PLEDGE_TMPPATH }, - { "inet", PLEDGE_SELF | PLEDGE_RW | PLEDGE_INET }, - { "unix", PLEDGE_SELF | PLEDGE_RW | PLEDGE_UNIX }, - { "dns", PLEDGE_SELF | PLEDGE_MALLOC | PLEDGE_DNS }, - { "getpw", PLEDGE_SELF | PLEDGE_MALLOC | PLEDGE_RW | PLEDGE_GETPW }, - { "sendfd", PLEDGE_RW | PLEDGE_SENDFD }, - { "recvfd", PLEDGE_RW | PLEDGE_RECVFD }, + { "stdio", PLEDGE_STDIO }, + { "rpath", PLEDGE_RPATH }, + { "wpath", PLEDGE_WPATH }, + { "tmppath", PLEDGE_TMPPATH }, + { "inet", PLEDGE_INET }, + { "unix", PLEDGE_UNIX }, + { "dns", PLEDGE_DNS }, + { "getpw", PLEDGE_GETPW }, + { "sendfd", PLEDGE_SENDFD }, + { "recvfd", PLEDGE_RECVFD }, { "ioctl", PLEDGE_IOCTL }, { "id", PLEDGE_ID }, { "route", PLEDGE_ROUTE }, @@ -280,13 +279,13 @@ static const struct { { "proc", PLEDGE_PROC }, { "exec", PLEDGE_EXEC }, { "cpath", PLEDGE_CPATH }, - { "abort", PLEDGE_ABORT }, { "fattr", PLEDGE_FATTR }, { "prot_exec", PLEDGE_PROTEXEC }, { "flock", PLEDGE_FLOCK }, { "ps", PLEDGE_PS }, { "vminfo", PLEDGE_VMINFO }, { "settime", PLEDGE_SETTIME }, + { "abort", 0 }, /* XXX reserve for later */ }; int @@ -472,6 +471,7 @@ sys_pledge(struct proc *p, void *v, register_t *retval) } p->p_p->ps_pledge = flags; + p->p_p->ps_pledge |= PLEDGE_COREDUMP; /* XXX temporary */ p->p_p->ps_flags |= PS_PLEDGE; return (0); } @@ -493,8 +493,19 @@ pledge_check(struct proc *p, int code) int pledge_fail(struct proc *p, int error, int code) { - printf("%s(%d): syscall %d\n", p->p_comm, p->p_pid, p->p_pledge_syscall); - if (p->p_p->ps_pledge & PLEDGE_ABORT) { /* Core dump requested */ + int i; + + /* Print first matching pledge */ + for (i = 0; pledgenames[i].bits != 0; i++) + if (pledgenames[i].bits & code) + break; + printf("%s(%d): syscall %d \"%s\"\n", p->p_comm, p->p_pid, + p->p_pledge_syscall, pledgenames[i].name); +#ifdef KTRACE + ktrpledge(p, error, code, p->p_pledge_syscall); +#endif + if (p->p_p->ps_pledge & PLEDGE_COREDUMP) { + /* Core dump requested */ struct sigaction sa; memset(&sa, 0, sizeof sa); @@ -516,24 +527,25 @@ int pledge_namei(struct proc *p, char *origpath) { char path[PATH_MAX]; + int error; - if (p->p_pledgenote == TMN_COREDUMP) + if (p->p_pledgenote == PLEDGE_COREDUMP) return (0); /* Allow a coredump */ - if (canonpath(origpath, path, sizeof(path)) != 0) - return (pledge_fail(p, EPERM, PLEDGE_RPATH)); + error = canonpath(origpath, path, sizeof(path)); + if (error) + return (pledge_fail(p, error, p->p_pledgenote)); - if ((p->p_pledgenote & TMN_FATTR) && + /* chmod(2), chflags(2), ... */ + if ((p->p_pledgenote & PLEDGE_FATTR) && (p->p_p->ps_pledge & PLEDGE_FATTR) == 0) { - printf("%s(%d): inode syscall%d, not allowed\n", - p->p_comm, p->p_pid, p->p_pledge_syscall); - return (pledge_fail(p, EPERM, PLEDGE_FATTR)); + return (pledge_fail(p, EPERM, p->p_pledgenote)); } /* Detect what looks like a mkstemp(3) family operation */ if ((p->p_p->ps_pledge & PLEDGE_TMPPATH) && (p->p_pledge_syscall == SYS_open) && - (p->p_pledgenote & TMN_CPATH) && + (p->p_pledgenote & PLEDGE_CPATH) && strncmp(path, "/tmp/", sizeof("/tmp/") - 1) == 0) { return (0); } @@ -548,12 +560,12 @@ pledge_namei(struct proc *p, char *origpath) } /* open, mkdir, or other path creation operation */ - if ((p->p_pledgenote & TMN_CPATH) && + if ((p->p_pledgenote & PLEDGE_CPATH) && ((p->p_p->ps_pledge & PLEDGE_CPATH) == 0)) return (pledge_fail(p, EPERM, PLEDGE_CPATH)); /* Doing a permitted execve() */ - if ((p->p_pledgenote & TMN_XPATH) && + if ((p->p_pledgenote & PLEDGE_EXEC) && (p->p_p->ps_pledge & PLEDGE_EXEC)) return (0); @@ -561,14 +573,14 @@ pledge_namei(struct proc *p, char *origpath) switch (p->p_pledge_syscall) { case SYS_open: /* daemon(3) or other such functions */ - if ((p->p_pledgenote & ~(TMN_RPATH | TMN_WPATH)) == 0 && + if ((p->p_pledgenote & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 && strcmp(path, "/dev/null") == 0) { return (0); } /* readpassphrase(3), getpw*(3) */ if ((p->p_p->ps_pledge & (PLEDGE_TTY | PLEDGE_GETPW)) && - (p->p_pledgenote & ~(TMN_RPATH | TMN_WPATH)) == 0 && + (p->p_pledgenote & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 && strcmp(path, "/dev/tty") == 0) { return (0); } @@ -576,7 +588,7 @@ pledge_namei(struct proc *p, char *origpath) } /* ensure PLEDGE_WPATH request for doing write */ - if ((p->p_pledgenote & TMN_WPATH) && + if ((p->p_pledgenote & PLEDGE_WPATH) && (p->p_p->ps_pledge & PLEDGE_WPATH) == 0) return (pledge_fail(p, EPERM, PLEDGE_WPATH)); @@ -584,13 +596,13 @@ pledge_namei(struct proc *p, char *origpath) switch (p->p_pledge_syscall) { case SYS_access: /* tzset() needs this. */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && strcmp(path, "/etc/localtime") == 0) return (0); break; case SYS_open: /* getpw* and friends need a few files */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && (p->p_p->ps_pledge & PLEDGE_GETPW)) { if (strcmp(path, "/etc/spwd.db") == 0) return (EPERM); @@ -601,7 +613,7 @@ pledge_namei(struct proc *p, char *origpath) } /* DNS needs /etc/{resolv.conf,hosts,services}. */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && (p->p_p->ps_pledge & PLEDGE_DNS)) { if (strcmp(path, "/etc/resolv.conf") == 0) return (0); @@ -611,10 +623,10 @@ pledge_namei(struct proc *p, char *origpath) return (0); } - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && (p->p_p->ps_pledge & PLEDGE_GETPW)) { if (strcmp(path, "/var/run/ypbind.lock") == 0) { - p->p_pledgeafter |= TMA_YPLOCK; + p->p_pledgeafter |= PLEDGE_YPACTIVE; return (0); } if (strncmp(path, "/var/yp/binding/", @@ -623,16 +635,16 @@ pledge_namei(struct proc *p, char *origpath) } /* tzset() needs these. */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && strncmp(path, "/usr/share/zoneinfo/", sizeof("/usr/share/zoneinfo/") - 1) == 0) return (0); - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && strcmp(path, "/etc/localtime") == 0) return (0); /* /usr/share/nls/../libc.cat has to succeed for strerror(3). */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && strncmp(path, "/usr/share/nls/", sizeof("/usr/share/nls/") - 1) == 0 && strcmp(path + strlen(path) - 9, "/libc.cat") == 0) @@ -641,13 +653,13 @@ pledge_namei(struct proc *p, char *origpath) break; case SYS_readlink: /* Allow /etc/malloc.conf for malloc(3). */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && strcmp(path, "/etc/malloc.conf") == 0) return (0); break; case SYS_stat: /* DNS needs /etc/resolv.conf. */ - if ((p->p_pledgenote == TMN_RPATH) && + if ((p->p_pledgenote == PLEDGE_RPATH) && (p->p_p->ps_pledge & PLEDGE_DNS) && strcmp(path, "/etc/resolv.conf") == 0) return (0); @@ -660,7 +672,7 @@ pledge_namei(struct proc *p, char *origpath) } /* ensure PLEDGE_RPATH request for doing read */ - if ((p->p_pledgenote & TMN_RPATH) && + if ((p->p_pledgenote & PLEDGE_RPATH) && (p->p_p->ps_pledge & PLEDGE_RPATH) == 0) return (pledge_fail(p, EPERM, PLEDGE_RPATH)); @@ -711,7 +723,7 @@ pledge_namei(struct proc *p, char *origpath) free(builtpath, M_TEMP, builtlen); if (error != 0) { free(canopath, M_TEMP, MAXPATHLEN); - return (pledge_fail(p, EPERM, PLEDGE_RPATH)); + return (pledge_fail(p, error, p->p_pledgenote)); } //printf("namei: canopath = %s strlen %lld\n", canopath, @@ -751,7 +763,7 @@ pledge_namei(struct proc *p, char *origpath) case SYS_lstat: case SYS_fstatat: case SYS_fstat: - p->p_pledgenote |= TMN_STATLIE; + p->p_pledgenote |= PLEDGE_STATLIE; error = 0; } free(canopath, M_TEMP, MAXPATHLEN); @@ -765,14 +777,14 @@ pledge_namei(struct proc *p, char *origpath) if (p->p_p->ps_pledge & PLEDGE_CPATH) return (0); - return (pledge_fail(p, EPERM, PLEDGE_RPATH)); + return (pledge_fail(p, EPERM, p->p_pledgenote)); } void pledge_aftersyscall(struct proc *p, int code, int error) { - if ((p->p_pledgeafter & TMA_YPLOCK) && error == 0) - atomic_setbits_int(&p->p_p->ps_pledge, PLEDGE_YP_ACTIVE | PLEDGE_INET); + if ((p->p_pledgeafter & PLEDGE_YPACTIVE) && error == 0) + atomic_setbits_int(&p->p_p->ps_pledge, PLEDGE_YPACTIVE | PLEDGE_INET); } /* @@ -975,7 +987,7 @@ pledge_sysctl_check(struct proc *p, int miblen, int *mib, void *new) printf("%s(%d): sysctl %d: %d %d %d %d %d %d\n", p->p_comm, p->p_pid, miblen, mib[0], mib[1], mib[2], mib[3], mib[4], mib[5]); - return (EFAULT); + return (EPERM); } int @@ -1249,7 +1261,7 @@ pledge_socket_check(struct proc *p, int dns) if (dns && (p->p_p->ps_pledge & PLEDGE_DNS)) return (0); - if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX|PLEDGE_YP_ACTIVE))) + if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX|PLEDGE_YPACTIVE))) return (0); return (EPERM); } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 536c41f1ce5..677a35e3da5 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.186 2015/10/10 19:12:39 deraadt Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.187 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -576,7 +576,7 @@ sys_kill(struct proc *cp, void *v, register_t *retval) pid == cp->p_pid || pid == 0) ; else - return pledge_fail(cp, EPERM, PLEDGE_SELF); + return pledge_fail(cp, EPERM, PLEDGE_PROC); } if (((u_int)signum) >= NSIG) @@ -1527,7 +1527,7 @@ coredump(struct proc *p) cred->cr_gid = 0; } - p->p_pledgenote = TMN_COREDUMP; + p->p_pledgenote = PLEDGE_COREDUMP; NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p); error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR); diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index b5258b5309c..c76e623ca79 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.296 2015/10/09 01:10:27 deraadt Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.297 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -174,8 +174,10 @@ sys_sysctl(struct proc *p, void *v, register_t *retval) if (error) return (error); - if (pledge_sysctl_check(p, SCARG(uap, namelen), name, SCARG(uap, new))) - return (pledge_fail(p, EPERM, PLEDGE_SELF)); + error = pledge_sysctl_check(p, SCARG(uap, namelen), + name, SCARG(uap, new)); + if (error) + return (pledge_fail(p, error, PLEDGE_STDIO)); switch (name[0]) { case CTL_KERN: diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 77893524de6..73668388001 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_syscalls.c,v 1.118 2015/10/25 17:45:29 deraadt Exp $ */ +/* $OpenBSD: uipc_syscalls.c,v 1.119 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */ /* @@ -612,8 +612,9 @@ sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize) if (error) return (error); } - if (pledge_sendit_check(p, mp->msg_name)) { - error = pledge_fail(p, EPERM, PLEDGE_RW); + error = pledge_sendit_check(p, mp->msg_name); + if (error) { + error = pledge_fail(p, error, PLEDGE_STDIO); goto bad; } diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index ebf23472d6e..4bd71c87091 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.89 2015/10/18 20:15:10 deraadt Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.90 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -434,7 +434,7 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct proc *p) /* Fixup sun_len to keep it in sync with m_len. */ soun->sun_len = nam2->m_len; - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; NDINIT(&nd, CREATE, NOFOLLOW | LOCKPARENT, UIO_SYSSPACE, soun->sun_path, p); /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ @@ -493,7 +493,7 @@ unp_connect(struct socket *so, struct mbuf *nam, struct proc *p) else if (memchr(soun->sun_path, '\0', sizeof(soun->sun_path)) == NULL) return (EINVAL); - p->p_pledgenote = TMN_RPATH | TMN_WPATH; + p->p_pledgenote = PLEDGE_RPATH | PLEDGE_WPATH; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, soun->sun_path, p); if ((error = namei(&nd)) != 0) return (error); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 2c16fb5019b..e9c22cd45e7 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.232 2015/10/20 06:40:00 semarie Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.233 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -563,7 +563,7 @@ sys_statfs(struct proc *p, void *v, register_t *retval) int error; struct nameidata nd; - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return (error); @@ -848,17 +848,17 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode, switch (oflags & O_ACCMODE) { case O_RDONLY: - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; break; case O_WRONLY: - p->p_pledgenote = TMN_WPATH; + p->p_pledgenote = PLEDGE_WPATH; break; case O_RDWR: - p->p_pledgenote = TMN_RPATH | TMN_WPATH; + p->p_pledgenote = PLEDGE_RPATH | PLEDGE_WPATH; break; } if (oflags & O_CREAT) - p->p_pledgenote |= TMN_CPATH; + p->p_pledgenote |= PLEDGE_CPATH; if (oflags & (O_EXLOCK | O_SHLOCK)) { error = pledge_flock_check(p); @@ -1302,7 +1302,7 @@ sys_mkfifo(struct proc *p, void *v, register_t *retval) syscallarg(mode_t) mode; } */ *uap = v; - p->p_pledgenote = TMN_CPATH | TMN_RPATH; + p->p_pledgenote = PLEDGE_CPATH | PLEDGE_RPATH; return (domknodat(p, AT_FDCWD, SCARG(uap, path), (SCARG(uap, mode) & ALLPERMS) | S_IFIFO, 0)); } @@ -1364,7 +1364,7 @@ dolinkat(struct proc *p, int fd1, const char *path1, int fd2, return (EINVAL); follow = (flag & AT_SYMLINK_FOLLOW) ? FOLLOW : NOFOLLOW; - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd1, path1, p); if ((error = namei(&nd)) != 0) return (error); @@ -1375,7 +1375,7 @@ dolinkat(struct proc *p, int fd1, const char *path1, int fd2, flags |= STRIPSLASHES; } - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; NDINITAT(&nd, CREATE, flags, UIO_USERSPACE, fd2, path2, p); if ((error = namei(&nd)) != 0) goto out; @@ -1435,7 +1435,7 @@ dosymlinkat(struct proc *p, const char *upath, int fd, const char *link) error = copyinstr(upath, path, MAXPATHLEN, NULL); if (error) goto out; - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; NDINITAT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, fd, link, p); if ((error = namei(&nd)) != 0) goto out; @@ -1494,7 +1494,7 @@ dounlinkat(struct proc *p, int fd, const char *path, int flag) if (flag & ~AT_REMOVEDIR) return (EINVAL); - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; NDINITAT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) @@ -1615,7 +1615,7 @@ sys_access(struct proc *p, void *v, register_t *retval) syscallarg(int) amode; } */ *uap = v; - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; return (dofaccessat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, amode), 0)); } @@ -1662,7 +1662,7 @@ dofaccessat(struct proc *p, int fd, const char *path, int amode, int flag) newcred->cr_gid = newcred->cr_rgid; } - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) goto out; @@ -1733,7 +1733,7 @@ dofstatat(struct proc *p, int fd, const char *path, struct stat *buf, int flag) follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, follow | LOCKLEAF, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) return (error); @@ -1741,7 +1741,7 @@ dofstatat(struct proc *p, int fd, const char *path, struct stat *buf, int flag) vput(nd.ni_vp); if (error) return (error); - if (p->p_pledgenote & TMN_STATLIE) { + if (p->p_pledgenote & PLEDGE_STATLIE) { if (S_ISDIR(sb.st_mode)) { sb.st_mode &= ~ALLPERMS; sb.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; @@ -1842,7 +1842,7 @@ doreadlinkat(struct proc *p, int fd, const char *path, char *buf, int error; struct nameidata nd; - p->p_pledgenote = TMN_RPATH; + p->p_pledgenote = PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) return (error); @@ -1905,7 +1905,7 @@ dochflagsat(struct proc *p, int fd, const char *path, u_int flags, int atflags) return (EINVAL); follow = (atflags & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; - p->p_pledgenote = TMN_FATTR | TMN_RPATH; + p->p_pledgenote = PLEDGE_FATTR | PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) return (error); @@ -2009,7 +2009,7 @@ dofchmodat(struct proc *p, int fd, const char *path, mode_t mode, int flag) return (EINVAL); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; - p->p_pledgenote = TMN_FATTR | TMN_RPATH; + p->p_pledgenote = PLEDGE_FATTR | PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) return (error); @@ -2110,7 +2110,7 @@ dofchownat(struct proc *p, int fd, const char *path, uid_t uid, gid_t gid, return (EINVAL); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; - p->p_pledgenote = TMN_FATTR | TMN_RPATH; + p->p_pledgenote = PLEDGE_FATTR | PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) return (error); @@ -2162,7 +2162,7 @@ sys_lchown(struct proc *p, void *v, register_t *retval) uid_t uid = SCARG(uap, uid); gid_t gid = SCARG(uap, gid); - p->p_pledgenote = TMN_FATTR | TMN_RPATH; + p->p_pledgenote = PLEDGE_FATTR | PLEDGE_RPATH; NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return (error); @@ -2313,7 +2313,7 @@ doutimensat(struct proc *p, int fd, const char *path, return (EINVAL); follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; - p->p_pledgenote = TMN_FATTR | TMN_RPATH; + p->p_pledgenote = PLEDGE_FATTR | PLEDGE_RPATH; NDINITAT(&nd, LOOKUP, follow, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) return (error); @@ -2458,7 +2458,7 @@ sys_truncate(struct proc *p, void *v, register_t *retval) int error; struct nameidata nd; - p->p_pledgenote = TMN_FATTR | TMN_RPATH; + p->p_pledgenote = PLEDGE_FATTR | PLEDGE_RPATH; NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return (error); @@ -2585,7 +2585,7 @@ dorenameat(struct proc *p, int fromfd, const char *from, int tofd, int error; int flags; - p->p_pledgenote = TMN_RPATH | TMN_CPATH; + p->p_pledgenote = PLEDGE_RPATH | PLEDGE_CPATH; NDINITAT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE, fromfd, from, p); if ((error = namei(&fromnd)) != 0) @@ -2599,7 +2599,7 @@ dorenameat(struct proc *p, int fromfd, const char *from, int tofd, if (fvp->v_type == VDIR) flags |= STRIPSLASHES; - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; NDINITAT(&tond, RENAME, flags, UIO_USERSPACE, tofd, to, p); if ((error = namei(&tond)) != 0) { VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd); @@ -2668,7 +2668,7 @@ sys_mkdir(struct proc *p, void *v, register_t *retval) syscallarg(mode_t) mode; } */ *uap = v; - p->p_pledgenote = TMN_CPATH | TMN_RPATH; + p->p_pledgenote = PLEDGE_CPATH | PLEDGE_RPATH; return (domkdirat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, mode))); } @@ -2693,7 +2693,7 @@ domkdirat(struct proc *p, int fd, const char *path, mode_t mode) int error; struct nameidata nd; - p->p_pledgenote = TMN_CPATH | TMN_RPATH; + p->p_pledgenote = PLEDGE_CPATH | PLEDGE_RPATH; NDINITAT(&nd, CREATE, LOCKPARENT | STRIPSLASHES, UIO_USERSPACE, fd, path, p); if ((error = namei(&nd)) != 0) @@ -2728,7 +2728,7 @@ sys_rmdir(struct proc *p, void *v, register_t *retval) syscallarg(const char *) path; } */ *uap = v; - p->p_pledgenote = TMN_CPATH; + p->p_pledgenote = PLEDGE_CPATH; return (dounlinkat(p, AT_FDCWD, SCARG(uap, path), AT_REMOVEDIR)); } diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index 24560f28a17..f76ae3f487d 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ktrace.h,v 1.25 2015/10/02 05:07:41 guenther Exp $ */ +/* $OpenBSD: ktrace.h,v 1.26 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: ktrace.h,v 1.12 1996/02/04 02:12:29 christos Exp $ */ /* @@ -165,6 +165,16 @@ struct ktr_user { #define KTR_EXECENV 11 +/* + * KTR_PLEDGE - details of pledge violation + */ +#define KTR_PLEDGE 12 +struct ktr_pledge { + int error; + int code; + int syscall; +}; + /* * kernel trace points (in p_traceflag) */ @@ -179,6 +189,7 @@ struct ktr_user { #define KTRFAC_USER (1< @@ -20,24 +20,22 @@ #ifndef _SYS_PLEDGE_H_ #define _SYS_PLEDGE_H_ -#ifdef _KERNEL - #include -#define PLEDGE_SELF 0x00000001 /* operate on own pid */ -#define PLEDGE_RW 0x00000002 /* basic io operations */ -#define PLEDGE_MALLOC 0x00000004 /* enough for malloc */ -#define PLEDGE_DNS 0x00000008 /* DNS services */ -#define PLEDGE_RPATH 0x00000010 /* allow open for read */ -#define PLEDGE_WPATH 0x00000020 /* allow open for write */ -#define PLEDGE_TMPPATH 0x00000040 /* for mk*temp() */ -#define PLEDGE_INET 0x00000080 /* AF_INET/AF_INET6 sockets */ +#define PLEDGE_RPATH 0x00000001 /* allow open for read */ +#define PLEDGE_WPATH 0x00000002 /* allow open for write */ +#define PLEDGE_CPATH 0x00000004 /* allow creat, mkdir, path creations */ +#define PLEDGE_STDIO 0x00000008 /* operate on own pid */ +#define PLEDGE_TMPPATH 0x00000010 /* for mk*temp() */ +#define PLEDGE_DNS 0x00000020 /* DNS services */ +#define PLEDGE_INET 0x00000040 /* AF_INET/AF_INET6 sockets */ +#define PLEDGE_FLOCK 0x00000080 /* file locking */ #define PLEDGE_UNIX 0x00000100 /* AF_UNIX sockets */ #define PLEDGE_ID 0x00000200 /* allow setuid, setgid, etc */ #define PLEDGE_IOCTL 0x00000400 /* Select ioctl */ #define PLEDGE_GETPW 0x00000800 /* YP enables if ypbind.lock */ #define PLEDGE_PROC 0x00001000 /* fork, waitpid, etc */ -#define PLEDGE_CPATH 0x00002000 /* allow creat, mkdir, path creations */ +#define PLEDGE_SETTIME 0x00002000 /* able to set/adj time/freq */ #define PLEDGE_FATTR 0x00004000 /* allow explicit file st_* mods */ #define PLEDGE_PROTEXEC 0x00008000 /* allow use of PROT_EXEC */ #define PLEDGE_TTY 0x00010000 /* tty setting */ @@ -46,17 +44,52 @@ #define PLEDGE_EXEC 0x00080000 /* execve, child is free of pledge */ #define PLEDGE_ROUTE 0x00100000 /* routing lookups */ #define PLEDGE_MCAST 0x00200000 /* multicast joins */ -#define PLEDGE_FLOCK 0x00400000 /* file locking */ +#define PLEDGE_VMINFO 0x00400000 /* vminfo listings */ #define PLEDGE_PS 0x00800000 /* ps listings */ -#define PLEDGE_VMINFO 0x01000000 /* vminfo listings */ -#define PLEDGE_SETTIME 0x02000000 /* able to set/adj time/freq */ - -#define PLEDGE_ABORT 0x08000000 /* SIGABRT instead of SIGKILL */ +#define PLEDGE_COREDUMP 0x01000000 /* generates coredump (default) */ /* Following flags are set by kernel, as it learns things. * Not user settable. Should be moved to a seperate variable */ + +#define PLEDGE_STATLIE 0x40000000 +#define PLEDGE_YPACTIVE 0x80000000 /* YP use detected and allowed */ #define PLEDGE_USERSET 0x0fffffff -#define PLEDGE_YP_ACTIVE 0x10000000 /* YP use detected and allowed */ + +#ifdef PLEDGENAMES +static struct { + u_int32_t bits; + char *name; +} pledgenames[] = { + { PLEDGE_RPATH, "rpath" }, + { PLEDGE_WPATH, "wpath" }, + { PLEDGE_CPATH, "cpath" }, + { PLEDGE_STDIO, "stdio" }, + { PLEDGE_TMPPATH, "tmppath" }, + { PLEDGE_DNS, "dns" }, + { PLEDGE_INET, "inet" }, + { PLEDGE_FLOCK, "flock" }, + { PLEDGE_UNIX, "unix" }, + { PLEDGE_ID, "id" }, + { PLEDGE_IOCTL, "ioctl" }, + { PLEDGE_GETPW, "getpw" }, + { PLEDGE_PROC, "proc" }, + { PLEDGE_SETTIME, "settime" }, + { PLEDGE_FATTR, "fattr" }, + { PLEDGE_PROTEXEC, "protexec" }, + { PLEDGE_TTY, "tty" }, + { PLEDGE_SENDFD, "sendfd" }, + { PLEDGE_RECVFD, "recvfd" }, + { PLEDGE_EXEC, "exec" }, + { PLEDGE_ROUTE, "route" }, + { PLEDGE_MCAST, "mcast" }, + { PLEDGE_VMINFO, "vminfo" }, + { PLEDGE_PS, "ps" }, + { PLEDGE_COREDUMP, "coredump" }, + { 0, NULL }, +}; +#endif + +#ifdef _KERNEL int pledge_check(struct proc *, int); int pledge_fail(struct proc *, int, int); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index bea8af81667..f0d1b8e757c 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.209 2015/10/20 06:40:01 semarie Exp $ */ +/* $OpenBSD: proc.h,v 1.210 2015/10/25 20:39:54 deraadt Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -328,15 +328,7 @@ struct proc { int p_pledge_syscall; /* Cache of current syscall */ int p_pledgenote; /* Observance during syscall */ -#define TMN_RPATH 0x00000001 -#define TMN_WPATH 0x00000002 -#define TMN_CPATH 0x00000004 -#define TMN_XPATH 0x00000008 -#define TMN_FATTR 0x00000010 -#define TMN_COREDUMP 0x00000020 -#define TMN_STATLIE 0x00000040 int p_pledgeafter; -#define TMA_YPLOCK 0x00000001 #ifndef __HAVE_MD_TCB void *p_tcb; /* user-space thread-control-block address */ diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 5230ddd8f25..3dd62d94a80 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kdump.c,v 1.116 2015/10/18 01:32:05 deraadt Exp $ */ +/* $OpenBSD: kdump.c,v 1.117 2015/10/25 20:39:54 deraadt Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -46,6 +46,9 @@ #include #include #include +#define PLEDGENAMES +#include +#undef PLEDGENAMES #define _KERNEL #include #undef _KERNEL @@ -148,6 +151,7 @@ static const char *kresolvsysctl(int, const int *); static void ktrsysret(struct ktr_sysret *, size_t); static void ktruser(struct ktr_user *, size_t); static void ktrexec(const char*, size_t); +static void ktrpledge(struct ktr_pledge *, size_t); static void setemul(const char *); static void usage(void); static void ioctldecode(int); @@ -310,6 +314,9 @@ main(int argc, char *argv[]) case KTR_EXECENV: ktrexec(m, ktrlen); break; + case KTR_PLEDGE: + ktrpledge((struct ktr_pledge *)m, ktrlen); + break; } if (tail) (void)fflush(stdout); @@ -399,6 +406,9 @@ dumpheader(struct ktr_header *kth) case KTR_EXECENV: type = "ENV "; break; + case KTR_PLEDGE: + type = "PLDG"; + break; default: (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)", kth->ktr_type); @@ -1428,6 +1438,31 @@ ktrexec(const char *ptr, size_t len) } } +static void +ktrpledge(struct ktr_pledge *pledge, size_t len) +{ + int i; + + if (len < sizeof(struct ktr_pledge)) + errx(1, "invalid ktr pledge length %zu", len); + + if (pledge->syscall >= current->nsysnames || pledge->syscall < 0) + (void)printf("[%d]", pledge->syscall); + else + (void)printf("%s", current->sysnames[pledge->syscall]); + printf(", "); + for (i = 0; pledgenames[i].bits != 0; i++) { + if (pledgenames[i].bits & pledge->code) { + printf("\"%s\"", pledgenames[i].name); + break; + } + } + (void)printf(", errno %d", pledge->error); + if (fancy) + (void)printf(" %s", strerror(pledge->error)); + printf("\n"); +} + static void usage(void) { diff --git a/usr.bin/ktrace/ktrace.h b/usr.bin/ktrace/ktrace.h index d2a82090778..ccc9bec0659 100644 --- a/usr.bin/ktrace/ktrace.h +++ b/usr.bin/ktrace/ktrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ktrace.h,v 1.8 2015/10/02 05:07:41 guenther Exp $ */ +/* $OpenBSD: ktrace.h,v 1.9 2015/10/25 20:39:54 deraadt Exp $ */ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. @@ -32,7 +32,7 @@ #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_EMUL | KTRFAC_STRUCT | \ - KTRFAC_USER | KTRFAC_EXECARGS) + KTRFAC_USER | KTRFAC_EXECARGS | KTRFAC_PLEDGE) /* any KTRFAC_* not included in DEF_POINTS should be added here */ #define ALL_POINTS (DEF_POINTS | KTRFAC_EXECENV) -- 2.20.1