diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-10-02 05:07:42 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-10-02 05:07:42 +0000 |
commit | 68eb2b766cad99f9a6a449107300fbce546c8ab0 (patch) | |
tree | 73f84c023523db8b9f0e4edfa50aa175349ed49d /sys/kern | |
parent | 5d058ac5fea652d7bdb9d58965b0da6343c641b9 (diff) |
Add ktracing of argv and envp to execve(2), with envp not traced by default
ok tedu@ deraadt@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_exec.c | 31 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 38 |
2 files changed, 63 insertions, 6 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index ee5bb5dafdc..6ae6064a054 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.164 2015/09/28 20:32:59 deraadt Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.165 2015/10/02 05:07:41 guenther Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -249,6 +249,9 @@ sys_execve(struct proc *p, void *v, register_t *retval) struct ucred *cred = p->p_ucred; char *argp; char * const *cpp, *dp, *sp; +#ifdef KTRACE + char *env_start; +#endif struct process *pr = p->p_p; long argc, envc; size_t len, sgap; @@ -377,9 +380,17 @@ sys_execve(struct proc *p, void *v, register_t *retval) goto bad; } +#ifdef KTRACE + if (KTRPOINT(p, KTR_EXECARGS)) + ktrexec(p, KTR_EXECARGS, argp, dp - argp); +#endif + envc = 0; /* environment does not need to be there */ if ((cpp = SCARG(uap, envp)) != NULL ) { +#ifdef KTRACE + env_start = dp; +#endif while (1) { len = argp + ARG_MAX - dp; if ((error = copyin(cpp, &sp, sizeof(sp))) != 0) @@ -395,6 +406,11 @@ sys_execve(struct proc *p, void *v, register_t *retval) cpp++; envc++; } + +#ifdef KTRACE + if (KTRPOINT(p, KTR_EXECENV)) + ktrexec(p, KTR_EXECENV, env_start, dp - env_start); +#endif } dp = (char *)(((long)dp + _STACKALIGNBYTES) & ~_STACKALIGNBYTES); @@ -713,12 +729,17 @@ sys_execve(struct proc *p, void *v, register_t *retval) if (pack.ep_emul->e_proc_exec) (*pack.ep_emul->e_proc_exec)(p, &pack); +#if defined(KTRACE) && defined(COMPAT_LINUX) + /* update ps_emul, but don't ktrace it if native-execing-native */ + if (pr->ps_emul != pack.ep_emul || pack.ep_emul != &emul_native) { + pr->ps_emul = pack.ep_emul; + + if (KTRPOINT(p, KTR_EMUL) + ktremul(p); + } +#else /* update ps_emul, the old value is no longer needed */ pr->ps_emul = pack.ep_emul; - -#ifdef KTRACE - if (KTRPOINT(p, KTR_EMUL)) - ktremul(p); #endif atomic_clearbits_int(&pr->ps_flags, PS_INEXEC); diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index bb6a97a3ded..1fed1fa84b8 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_ktrace.c,v 1.78 2015/09/13 17:08:03 guenther Exp $ */ +/* $OpenBSD: kern_ktrace.c,v 1.79 2015/10/02 05:07:41 guenther Exp $ */ /* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */ /* @@ -361,6 +361,42 @@ ktruser(struct proc *p, const char *id, const void *addr, size_t len) return (error); } +void +ktrexec(struct proc *p, int type, const char *data, ssize_t len) +{ + struct ktr_header kth; + int count; + int buflen; + + assert(type == KTR_EXECARGS || type == KTR_EXECENV); + atomic_setbits_int(&p->p_flag, P_INKTR); + + /* beware overflow */ + if (len > PAGE_SIZE) + buflen = PAGE_SIZE; + else + buflen = len; + + ktrinitheader(&kth, p, type); + + while (len > 0) { + /* + * Don't allow this process to hog the cpu when doing + * huge I/O. + */ + if (curcpu()->ci_schedstate.spc_schedflags & SPCF_SHOULDYIELD) + preempt(NULL); + + count = lmin(len, buflen); + if (ktrwrite(p, &kth, data, count) != 0) + break; + + len -= count; + data += count; + } + + atomic_clearbits_int(&p->p_flag, P_INKTR); +} /* Interface and common routines */ |