summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-01-20 11:27:53 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-01-20 11:27:53 +0000
commitb1debdf727116f16170aa85959010013dd34583e (patch)
treeb2f6cee252eb75c2e5b8874177dcccb398a63941
parent5553da18201980ea91c0445a3120d60334ec5ae5 (diff)
When a process is exec:ing mark it with a flag. Check that flag in ptrace
and procfs (and possibly more places in the future) and simply refuse to fiddle with the execing process. This is an ugly hack, but this far we haven't been successful in creating a race-free exec.
-rw-r--r--sys/kern/kern_exec.c11
-rw-r--r--sys/kern/sys_process.c5
-rw-r--r--sys/miscfs/procfs/procfs_mem.c7
-rw-r--r--sys/sys/proc.h3
4 files changed, 22 insertions, 4 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 6bec610b8e2..b8b6b6d479a 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exec.c,v 1.62 2001/12/19 08:58:06 art Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.63 2002/01/20 11:27:52 art Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
@@ -250,6 +250,12 @@ sys_execve(p, v, retval)
extern struct emul emul_native;
/*
+ * Cheap solution to complicated problems.
+ * Mark this process as "leave me alone, I'm execing".
+ */
+ p->p_flag |= P_INEXEC;
+
+ /*
* figure out the maximum size of an exec header, if necessary.
* XXX should be able to keep LKM code from modifying exec switch
* when we're still using it, but...
@@ -614,6 +620,7 @@ sys_execve(p, v, retval)
if (KTRPOINT(p, KTR_EMUL))
ktremul(p, p->p_emul->e_name);
#endif
+ p->p_flag &= ~P_INEXEC;
return (0);
bad:
@@ -632,6 +639,7 @@ bad:
freehdr:
free(pack.ep_hdr, M_EXEC);
+ p->p_flag &= ~P_INEXEC;
return (error);
exec_abort:
@@ -655,6 +663,7 @@ free_pack_abort:
exit1(p, -1);
/* NOTREACHED */
+ p->p_flag &= ~P_INEXEC;
return (0);
}
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index e20fedf045d..2e27b3d46ea 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_process.c,v 1.15 2002/01/02 02:38:42 art Exp $ */
+/* $OpenBSD: sys_process.c,v 1.16 2002/01/20 11:27:52 art Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
@@ -107,6 +107,9 @@ sys_ptrace(p, v, retval)
return (ESRCH);
}
+ if ((t->p_flag & P_INEXEC) != 0)
+ return (EAGAIN);
+
/* Make sure we can operate on it. */
switch (SCARG(uap, req)) {
case PT_TRACE_ME:
diff --git a/sys/miscfs/procfs/procfs_mem.c b/sys/miscfs/procfs/procfs_mem.c
index 57c121a0f9d..afa929c1f7a 100644
--- a/sys/miscfs/procfs/procfs_mem.c
+++ b/sys/miscfs/procfs/procfs_mem.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: procfs_mem.c,v 1.15 2001/11/06 01:44:23 art Exp $ */
+/* $OpenBSD: procfs_mem.c,v 1.16 2002/01/20 11:27:52 art Exp $ */
/* $NetBSD: procfs_mem.c,v 1.8 1996/02/09 22:40:50 christos Exp $ */
/*
@@ -104,6 +104,8 @@ procfs_domem(curp, p, pfs, uio)
* of the entire system, and the system was not
* compiled with permanently insecure mode turned
* on.
+ *
+ * (3) It's currently execing.
*/
int
procfs_checkioperm(p, t)
@@ -119,6 +121,9 @@ procfs_checkioperm(p, t)
if ((t->p_pid == 1) && (securelevel > -1))
return (EPERM);
+ if (t->p_flag & P_INEXEC)
+ return (EAGAIN);
+
return (0);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index e8f96b1fa09..bb3ceb2956d 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.51 2001/12/01 23:42:22 deraadt Exp $ */
+/* $OpenBSD: proc.h,v 1.52 2002/01/20 11:27:52 art Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -246,6 +246,7 @@ struct proc {
#define P_NOCLDWAIT 0x080000 /* Let pid 1 wait for my children */
#define P_NOZOMBIE 0x100000 /* Pid 1 waits for me instead of dad */
+#define P_INEXEC 0x200000 /* Process is doing an exec right now */
/* Macro to compute the exit signal to be delivered. */
#define P_EXITSIG(p) \