Date: Fri, 25 Jan 2002 21:55:25 +0300 (MSK) From: Oleg Derevenetz <oleg@oleg.vsi.ru> To: security@freebsd.org Subject: FreeBSD-SA-02:08.exec patch for 4.0-RELEASE systems Message-ID: <1011984925.3c51aa1dd5d4d@webmail.vsi.ru>
next in thread | raw e-mail | index | archive | help
4.0-RELEASE systems seems to be affected with problems in this advisory. My company use a number of 4.0-RELEASE systems that are not upgradable for some reasons. So I wrote a patch for these systems (below). Can anybody tell me, are these changes in code sufficient to avoid problems listed in advisory ? Index: sys/kern/kern_exec.c diff -u sys/kern/kern_exec.c.orig sys/kern/kern_exec.c --- kern_exec.c.orig Tue Jul 10 22:15:28 2001 +++ kern_exec.c Fri Jan 25 14:38:21 2002 @@ -113,6 +113,15 @@ 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; @@ -333,6 +342,12 @@ VREF(ndp->ni_vp); p->p_textvp = ndp->ni_vp; + /* + * Clear the P_INEXEC flag + * as we're now a bona fide freshly-execed process. + */ + p->p_flag &= ~P_INEXEC; + /* * If tracing the process, trap to debugger so breakpoints * can be set before the program executes. @@ -385,6 +400,8 @@ 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)); Index: sys/kern/sys_process.c diff -u sys/kern/sys_process.c.orig sys/kern/sys_process.c --- sys_process.c.orig Sun Nov 21 22:03:10 1999 +++ sys_process.c Fri Jan 25 14:40:29 2002 @@ -220,6 +220,10 @@ 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 */ Index: sys/miscfs/procfs/procfs_ctl.c diff -u sys/miscfs/procfs/procfs_ctl.c.orig sys/miscfs/procfs/procfs_ctl.c --- procfs_ctl.c.orig Wed Dec 8 11:59:36 1999 +++ procfs_ctl.c Fri Jan 25 14:42:19 2002 @@ -110,6 +110,10 @@ { int error; + /* Can't trace a process that's currently exec'ing. */ + if ((p->p_flag & P_INEXEC) != 0) + return EAGAIN; + /* * Attach - attaches the target process for debugging * by the calling process. Index: sys/miscfs/procfs/procfs_dbregs.c diff -u sys/miscfs/procfs/procfs_dbregs.c.orig sys/miscfs/procfs/procfs_dbregs.c --- procfs_dbregs.c.orig Wed Dec 8 11:59:36 1999 +++ procfs_dbregs.c Fri Jan 25 14:48:36 2002 @@ -62,6 +62,10 @@ char *kv; int kl; + /* Can't trace a process that's currently exec'ing. */ + if ((p->p_flag & P_INEXEC) != 0) + return EAGAIN; + if (p_trespass(curp, p)) return (EPERM); kl = sizeof(r); Index: sys/miscfs/procfs/procfs_fpregs.c diff -u sys/miscfs/procfs/procfs_fpregs.c.orig sys/miscfs/procfs/procfs_fpregs.c --- procfs_fpregs.c.orig Wed Dec 8 11:59:37 1999 +++ procfs_fpregs.c Fri Jan 25 14:50:05 2002 @@ -59,6 +59,10 @@ char *kv; int kl; + /* Can't trace a process that's currently exec'ing. */ + if ((p->p_flag & P_INEXEC) != 0) + return EAGAIN; + if (p_trespass(curp, p)) return EPERM; kl = sizeof(r); Index: sys/miscfs/procfs/procfs_mem.c diff -u sys/miscfs/procfs/procfs_mem.c.orig sys/miscfs/procfs/procfs_mem.c --- procfs_mem.c.orig Mon Dec 20 21:26:58 1999 +++ procfs_mem.c Fri Jan 25 15:01:13 2002 @@ -255,7 +255,11 @@ * means that KMEM_GROUP can't change without editing procfs.h! * All in all, quite yucky. */ - + + /* Can't trace a process that's currently exec'ing. */ + if ((p->p_flag & P_INEXEC) != 0) + return EAGAIN; + if (p_trespass(curp, p) && !(uio->uio_rw == UIO_READ && procfs_kmemaccess(curp))) Index: sys/miscfs/procfs/procfs_regs.c diff -u sys/miscfs/procfs/procfs_regs.c.orig sys/miscfs/procfs/procfs_regs.c --- procfs_regs.c.orig Sun Nov 21 22:03:19 1999 +++ procfs_regs.c Fri Jan 25 14:50:44 2002 @@ -60,6 +60,10 @@ char *kv; int kl; + /* Can't trace a process that's currently exec'ing. */ + if ((p->p_flag & P_INEXEC) != 0) + return EAGAIN; + if (p_trespass(curp, p)) return EPERM; kl = sizeof(r); Index: sys/miscfs/procfs/procfs_status.c diff -u sys/miscfs/procfs/procfs_status.c.orig sys/miscfs/procfs/procfs_status.c --- procfs_status.c.orig Mon Dec 27 19:03:38 1999 +++ procfs_status.c Fri Jan 25 14:57:57 2002 @@ -183,7 +183,8 @@ * Linux behaviour is to return zero-length in this case. */ - if (p->p_args && (ps_argsopen ||!p_trespass(curp, p))) { + if (p->p_args && (ps_argsopen || ((p->p_flag & P_INEXEC) == 0 && + !p_trespass(curp, p)))) { bp = p->p_args->ar_args; buflen = p->p_args->ar_length; buf = 0; Index: sys/miscfs/procfs/procfs_vnops.c diff -u sys/miscfs/procfs/procfs_vnops.c.orig sys/miscfs/procfs/procfs_vnops.c --- procfs_vnops.c.orig Thu Dec 16 02:02:08 1999 +++ procfs_vnops.c Fri Jan 25 15:05:10 2002 @@ -145,6 +145,11 @@ 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 (p_trespass(p1, p2) && !procfs_kmemaccess(p1)) return (EPERM); @@ -236,6 +241,10 @@ if (procp == NULL) { return ENOTTY; } + + /* Can't trace a process that's currently exec'ing. */ + if ((procp->p_flag & P_INEXEC) != 0) + return EAGAIN; if (p_trespass(p, procp)) return EPERM; Index: sys/sys/proc.h diff -u sys/sys/proc.h.orig sys/sys/proc.h --- proc.h.orig Fri Jan 28 23:40:18 2000 +++ proc.h Fri Jan 25 14:58:53 2002 @@ -289,6 +289,7 @@ #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? To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1011984925.3c51aa1dd5d4d>