summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-10-02 05:07:42 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-10-02 05:07:42 +0000
commit68eb2b766cad99f9a6a449107300fbce546c8ab0 (patch)
tree73f84c023523db8b9f0e4edfa50aa175349ed49d /sys/kern
parent5d058ac5fea652d7bdb9d58965b0da6343c641b9 (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.c31
-rw-r--r--sys/kern/kern_ktrace.c38
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 */