aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacques Vidrine <nectar@FreeBSD.org>2002-01-23 23:05:54 +0000
committerJacques Vidrine <nectar@FreeBSD.org>2002-01-23 23:05:54 +0000
commitea0ac1b430f233cbe72574bd6308622521663df3 (patch)
treeb39a41f9a2ffb7388b1f145c8c7ab573bc093caa
parenta7ddbd30254e45aaf4d33f980e3ff51a2ee147ae (diff)
downloadsrc-ea0ac1b430f233cbe72574bd6308622521663df3.tar.gz
src-ea0ac1b430f233cbe72574bd6308622521663df3.zip
Eliminate ptrace/exec race.
MFC 1.191 src/sys/sys/proc.h MFC 1.44 src/sys/kern/kern_exec.c (execve) Add P_INEXEC flag to indicate that a process is currently exec'ing. sys/kern/sys_process.c (ptrace) sys/miscfs/procfs/... Do not allow debugging of a process during exec.
Notes
Notes: svn path=/releng/4.3/; revision=89719
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/kern/kern_exec.c19
-rw-r--r--sys/kern/sys_process.c4
-rw-r--r--sys/miscfs/procfs/procfs.h2
-rw-r--r--sys/miscfs/procfs/procfs_ctl.c3
-rw-r--r--sys/miscfs/procfs/procfs_dbregs.c3
-rw-r--r--sys/miscfs/procfs/procfs_fpregs.c3
-rw-r--r--sys/miscfs/procfs/procfs_mem.c3
-rw-r--r--sys/miscfs/procfs/procfs_regs.c3
-rw-r--r--sys/miscfs/procfs/procfs_status.c4
-rw-r--r--sys/miscfs/procfs/procfs_vnops.c6
-rw-r--r--sys/sys/proc.h1
12 files changed, 47 insertions, 6 deletions
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 78a9af349fc4..a26cf7363190 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -36,7 +36,7 @@
TYPE="FreeBSD"
REVISION="4.3"
-BRANCH="RELEASE-p23"
+BRANCH="RELEASE-p24"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 4c2130d51343..5f024bd988ec 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -113,6 +113,15 @@ execve(p, uap)
imgp = &image_params;
/*
+ * 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;
+
+ /*
* Initialize part of the common data
*/
imgp->proc = p;
@@ -342,10 +351,12 @@ interpret:
VREF(ndp->ni_vp);
p->p_textvp = ndp->ni_vp;
- /*
- * notify others that we exec'd
- */
+ /*
+ * Notify others that we exec'd, and clear the P_INEXEC flag
+ * as we're now a bona fide freshly-execed process.
+ */
KNOTE(&p->p_klist, NOTE_EXEC);
+ p->p_flag &= ~P_INEXEC;
/*
* If tracing the process, trap to debugger so breakpoints
@@ -399,6 +410,8 @@ exec_fail_dealloc:
return (0);
exec_fail:
+ /* we're done here, clear P_INEXEC */
+ p->p_flag &= ~P_INEXEC;
if (imgp->vmspace_destroyed) {
/* sorry, no more process anymore. exit gracefully */
exit1(p, W_EXITCODE(0, SIGABRT));
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 1fd7ef1457ff..482663c793d8 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -220,6 +220,10 @@ ptrace(curp, uap)
if (!PRISON_CHECK(curp, p))
return (ESRCH);
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
+
/*
* Permissions check
*/
diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h
index efc982a4da45..9236cbf6cd70 100644
--- a/sys/miscfs/procfs/procfs.h
+++ b/sys/miscfs/procfs/procfs.h
@@ -97,7 +97,7 @@ struct pfsnode {
((((p1)->p_cred->pc_ucred->cr_uid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_ruid == (p2)->p_cred->p_ruid) && \
((p1)->p_cred->p_svuid == (p2)->p_cred->p_ruid) && \
- ((p2)->p_flag & P_SUGID) == 0) || \
+ ((p2)->p_flag & (P_SUGID|P_INEXEC)) == 0) || \
(suser_xxx((p1)->p_cred->pc_ucred, (p1), PRISON_ROOT) == 0))
/*
diff --git a/sys/miscfs/procfs/procfs_ctl.c b/sys/miscfs/procfs/procfs_ctl.c
index 2192dbe5afa1..6370e8b05912 100644
--- a/sys/miscfs/procfs/procfs_ctl.c
+++ b/sys/miscfs/procfs/procfs_ctl.c
@@ -110,6 +110,9 @@ procfs_control(curp, p, op)
{
int error;
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
/*
* Authorization check: rely on normal debugging protection, except
* allow processes to disengage debugging on a process onto which
diff --git a/sys/miscfs/procfs/procfs_dbregs.c b/sys/miscfs/procfs/procfs_dbregs.c
index 716b6c11e1c3..58b27db6dc8d 100644
--- a/sys/miscfs/procfs/procfs_dbregs.c
+++ b/sys/miscfs/procfs/procfs_dbregs.c
@@ -62,6 +62,9 @@ procfs_dodbregs(curp, p, pfs, uio)
char *kv;
int kl;
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
if (!CHECKIO(curp, p) || p_trespass(curp, p))
return (EPERM);
kl = sizeof(r);
diff --git a/sys/miscfs/procfs/procfs_fpregs.c b/sys/miscfs/procfs/procfs_fpregs.c
index 55bc1c9c9160..bd4e397235ad 100644
--- a/sys/miscfs/procfs/procfs_fpregs.c
+++ b/sys/miscfs/procfs/procfs_fpregs.c
@@ -59,6 +59,9 @@ procfs_dofpregs(curp, p, pfs, uio)
char *kv;
int kl;
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
if (!CHECKIO(curp, p) || p_trespass(curp, p))
return EPERM;
kl = sizeof(r);
diff --git a/sys/miscfs/procfs/procfs_mem.c b/sys/miscfs/procfs/procfs_mem.c
index 4994aa6c830a..7e59c4dded62 100644
--- a/sys/miscfs/procfs/procfs_mem.c
+++ b/sys/miscfs/procfs/procfs_mem.c
@@ -244,6 +244,9 @@ procfs_domem(curp, p, pfs, uio)
if (uio->uio_resid == 0)
return (0);
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
if (!CHECKIO(curp, p) || p_trespass(curp, p))
return EPERM;
diff --git a/sys/miscfs/procfs/procfs_regs.c b/sys/miscfs/procfs/procfs_regs.c
index ab678a5cf3b4..b7050a706fa2 100644
--- a/sys/miscfs/procfs/procfs_regs.c
+++ b/sys/miscfs/procfs/procfs_regs.c
@@ -60,6 +60,9 @@ procfs_doregs(curp, p, pfs, uio)
char *kv;
int kl;
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
if (!CHECKIO(curp, p) || p_trespass(curp, p))
return EPERM;
kl = sizeof(r);
diff --git a/sys/miscfs/procfs/procfs_status.c b/sys/miscfs/procfs/procfs_status.c
index 8c1707584482..b8cc6dbe9f91 100644
--- a/sys/miscfs/procfs/procfs_status.c
+++ b/sys/miscfs/procfs/procfs_status.c
@@ -211,7 +211,9 @@ procfs_docmdline(curp, p, pfs, uio)
*/
if (p->p_args &&
- (ps_argsopen || (CHECKIO(curp, p) && !p_trespass(curp, p)))) {
+ (ps_argsopen || (CHECKIO(curp, p) &&
+ (p->p_flag & P_INEXEC) == 0 &&
+ !p_trespass(curp, p)))) {
bp = p->p_args->ar_args;
buflen = p->p_args->ar_length;
buf = 0;
diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c
index 68713673ff25..c1c7e21cebdd 100644
--- a/sys/miscfs/procfs/procfs_vnops.c
+++ b/sys/miscfs/procfs/procfs_vnops.c
@@ -148,6 +148,9 @@ procfs_open(ap)
return (EBUSY);
p1 = ap->a_p;
+ /* Can't trace a process that's currently exec'ing. */
+ if ((p2->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
if (!CHECKIO(p1, p2) || p_trespass(p1, p2))
return (EPERM);
@@ -239,6 +242,9 @@ procfs_ioctl(ap)
return ENOTTY;
}
+ /* Can't trace a process that's currently exec'ing. */
+ if ((procp->p_flag & P_INEXEC) != 0)
+ return EAGAIN;
if (!CHECKIO(p, procp) || p_trespass(p, procp))
return EPERM;
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 7c7cdef8d4d6..1ee93da7e60f 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -291,6 +291,7 @@ struct proc {
#define P_JAILED 0x1000000 /* Process is in jail */
#define P_OLDMASK 0x2000000 /* need to restore mask before pause */
#define P_ALTSTACK 0x4000000 /* have alternate signal stack */
+#define P_INEXEC 0x8000000 /* Process is in execve(). */
/*
* MOVE TO ucred.h?