+ /*
+ * Lock the process and set the P_INEXEC flag to indicate that
+ * it should be left alone until we're done here. This is
+ * necessary to avoid race conditions - e.g. in ptrace() -
+ * that might allow a local user to illicitly obtain elevated
+ * privileges.
+ */
+ p->p_flag |= P_INEXEC;
+
ndp = epp->ep_ndp;
ndp->ni_cnd.cn_nameiop = LOOKUP;
ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME;
@@ -498,9 +507,11 @@
ktremul(p->p_tracep, p, p->p_emul->e_name);
#endif
+ p->p_flag &= ~P_INEXEC;
return (EJUSTRETURN);
bad:
+ p->p_flag &= ~P_INEXEC;
/* free the vmspace-creation commands, and release their references */
kill_vmcmds(&pack.ep_vmcmds);
/* kill any opened file descriptor, if necessary */
@@ -516,10 +527,12 @@
uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
exec_abort:
+ p->p_flag &= ~P_INEXEC;
/*
* the old process doesn't exist anymore. exit gracefully.
* get rid of the (new) address space we have created, if any, get rid
Index: sys/sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.74.2.2
diff -u -r1.74.2.2 proc.h
--- sys/sys/proc.h 2000/04/30 20:12:04 1.74.2.2
+++ sys/sys/proc.h 2002/01/14 14:29:20
@@ -210,24 +210,25 @@
#define SZOMB 5 /* Awaiting collection by parent. */
/* These flags are kept in p_flag. */
-#define P_ADVLOCK 0x00001 /* Process may hold a POSIX advisory lock. */
-#define P_CONTROLT 0x00002 /* Has a controlling terminal. */
-#define P_INMEM 0x00004 /* Loaded into memory. */
-#define P_NOCLDSTOP 0x00008 /* No SIGCHLD when children stop. */
-#define P_PPWAIT 0x00010 /* Parent is waiting for child to exec/exit. */
-#define P_PROFIL 0x00020 /* Has started profiling. */
-#define P_SELECT 0x00040 /* Selecting; wakeup/waiting danger. */
-#define P_SINTR 0x00080 /* Sleep is interruptible. */
-#define P_SUGID 0x00100 /* Had set id privileges since last exec. */
-#define P_SYSTEM 0x00200 /* System proc: no sigs, stats or swapping. */
-#define P_TIMEOUT 0x00400 /* Timing out during sleep. */
-#define P_TRACED 0x00800 /* Debugged process being traced. */
-#define P_WAITED 0x01000 /* Debugging process has waited for child. */
-#define P_WEXIT 0x02000 /* Working on exiting. */
-#define P_EXEC 0x04000 /* Process called exec. */
-#define P_OWEUPC 0x08000 /* Owe process an addupc() call at next ast. */
-#define P_FSTRACE 0x10000 /* Debugger process being traced by procfs */
-#define P_NOCLDWAIT 0x20000 /* No zombies if child dies */
+#define P_ADVLOCK 0x000001 /* Process may hold a POSIX advisory lock. */
+#define P_CONTROLT 0x000002 /* Has a controlling terminal. */
+#define P_INMEM 0x000004 /* Loaded into memory. */
+#define P_NOCLDSTOP 0x000008 /* No SIGCHLD when children stop. */
+#define P_PPWAIT 0x000010 /* Parent is waiting for child to exec/exit. */
+#define P_PROFIL 0x000020 /* Has started profiling. */
+#define P_SELECT 0x000040 /* Selecting; wakeup/waiting danger. */
+#define P_SINTR 0x000080 /* Sleep is interruptible. */
+#define P_SUGID 0x000100 /* Had set id privileges since last exec. */
+#define P_SYSTEM 0x000200 /* System proc: no sigs, stats or swapping. */
+#define P_TIMEOUT 0x000400 /* Timing out during sleep. */
+#define P_TRACED 0x000800 /* Debugged process being traced. */
+#define P_WAITED 0x001000 /* Debugging process has waited for child. */
+#define P_WEXIT 0x002000 /* Working on exiting. */
+#define P_EXEC 0x004000 /* Process called exec. */
+#define P_OWEUPC 0x008000 /* Owe process an addupc() call at next ast. */
+#define P_FSTRACE 0x010000 /* Debugger process being traced by procfs */
+#define P_NOCLDWAIT 0x020000 /* No zombies if child dies */
+#define P_INEXEC 0x100000 /* Process is exec'ing and cannot be traced */
/*
* These flags are kept in schedflags. schedflags may be modified
Index: sys/miscfs/procfs/procfs_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/procfs/procfs_vnops.c,v
retrieving revision 1.61.2.1
diff -u -r1.61.2.1 procfs_vnops.c
--- sys/miscfs/procfs/procfs_vnops.c 1999/08/28 23:28:16 1.61.2.1
+++ sys/miscfs/procfs/procfs_vnops.c 2002/01/14 14:29:33
@@ -233,7 +233,7 @@
return (EBUSY);
if ((error = procfs_checkioperm(curp, p)) != 0)
! return error;
kl = sizeof(r);
kv = (char *) &r;
Index: sys/miscfs/procfs/procfs_mem.c
===================================================================
RCS file: /cvsroot/syssrc/sys/miscfs/procfs/procfs_mem.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -c -p -r1.29 -r1.30
*** sys/miscfs/procfs/procfs_mem.c 2001/11/10 13:33:43 1.29
--- sys/miscfs/procfs/procfs_mem.c 2002/01/12 18:51:31 1.30
*************** procfs_checkioperm(p, t)
*** 122,128 ****
/*
* You cannot attach to a processes mem/regs if:
*
! * (1) it's not owned by you, or is set-id on exec
* (unless you're root), or...
*/
if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
--- 122,134 ----
/*
* You cannot attach to a processes mem/regs if:
*
! * (1) It is currently exec'ing
! */
! if (ISSET(t->p_flag, P_INEXEC))
! return (EAGAIN);
!
! /*
! * (2) it's not owned by you, or is set-id on exec
* (unless you're root), or...
*/
if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
*************** procfs_checkioperm(p, t)
*** 131,137 ****
return (error);
/*
! * (2) ...it's init, which controls the security level
* of the entire system, and the system was not
* compiled with permanetly insecure mode turned on.
*/
--- 137,143 ----
return (error);
/*
! * (3) ...it's init, which controls the security level
* of the entire system, and the system was not
* compiled with permanetly insecure mode turned on.
*/
*************** procfs_checkioperm(p, t)
*** 139,150 ****
return (EPERM);
/*
! * (3) the tracer is chrooted, and its root directory is
! * not at or above the root directory of the tracee
*/
-
if (!proc_isunder(t, p))
! return EPERM;
return (0);
}
--- 145,155 ----
return (EPERM);
/*
! * (4) the tracer is chrooted, and its root directory is
! * not at or above the root directory of the tracee
*/
if (!proc_isunder(t, p))
! return (EPERM);
/*
* Attach - attaches the target process for debugging
* by the calling process.
*/
- switch (op) {
case PROCFS_CTL_ATTACH:
/*
* You can't attach to a process if:
--- 108,123 ----
int s, error;
/*
+ * You cannot do anything to the process if it is currently exec'ing
+ */
+ if (ISSET(p->p_flag, P_INEXEC))
+ return (EAGAIN);
+
+ switch (op) {
+ /*
* Attach - attaches the target process for debugging
* by the calling process.
*/
case PROCFS_CTL_ATTACH:
/*
* You can't attach to a process if:
Index: sys/kern/sys_process.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/sys_process.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -c -p -r1.71 -r1.72
*** sys/kern/sys_process.c 2001/12/05 00:58:05 1.71
--- sys/kern/sys_process.c 2002/01/11 21:16:28 1.72
*************** sys_ptrace(p, v, retval)
*** 106,111 ****
--- 106,115 ----
if ((t = pfind(SCARG(uap, pid))) == NULL)
return (ESRCH);
}
+
+ /* Can't trace a process that's currently exec'ing. */
+ if ((t->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
/* Make sure we can operate on it. */
switch (SCARG(uap, req)) {