Subject: procfs/ptrace/systrace/ktrace diff
To: None <tech-kern@NetBSD.org>
From: Elad Efrat <elad@NetBSD.org>
List: tech-security
Date: 11/23/2006 18:43:40
This is a multi-part message in MIME format.

--Boundary_(ID_JHNFraipZEqn3oToTMoQGw)
Content-type: text/plain; charset=ISO-8859-1
Content-transfer-encoding: 7BIT

hi,

attached diff affects procfs/ptrace/systrace/ktrace.

it tackles a few issues:
  - ktrace: now uses its own kauth(9) request. (only ktrace change)

  - systrace: indirectly used process_checkioperm() via process_domem(),
    and checked securelevel. now uses its own kauth(9) request. (only
    systrace change)

  - procfs/ptrace on i386/powerpc: these architectures support get/set
    regs operations, commonly used by procfs/ptrace via process_doregs()
    and process_dofpregs(). permission checks taken out of both and
    replaced by procfs/ptrace-specific kauth(9) calls before them in
    their callers.

  - procfs/ptrace: relies on process_domem(), process_doregs(), and
    process_dofpregs(), in turn relying on process_checkioperm(), which
    checks securelevel.

    simplified call graphs:

      sys_ptrace() -> process_domem()
      sys_ptrace() -> process_doregs()
      sys_ptrace() -> process_dofpregs()

      procfs_rw() -> procfs_domem() -> process_domem()
      procfs_rw() -> procfs_doregs() -> process_doregs()
      procfs_rw() -> procfs_dofpregs() -> process_dofpregs()

    the removed process_checkioperm() calls from process_domem(),
    process_doregs(), and process_dofpregs() were replaced by kauth(9)
    calls in sys_ptrace() before the calls to the above three, and by
    a single call in procfs_rw().

notes:
  - the diff offers poor context to kauth(9). this should probably be
    addressed by passing the specific ptrace request, procfs pfsnode
    (already done), uio request (if any), and tracer lwp. this can also
    move the proc_isunder() calls to the secmodel code.

  - mildly tested under amd64. please make sure it at least compiles on
    i386 and powerpc.

  - I don't do extensive use (or use at all) any of the four affected
    subsystems. please at least try to use them to see if they retain
    functionality. if you feel helpful, try to break them: root should
    not be able to touch pid 1 if securelevel > -1, you should not be
    able to attach (or touch?) processes you don't own with these, and
    you should not be able to attach (or touch?) processes outside your
    chroot.

comments?

-e.

-- 
Elad Efrat

--Boundary_(ID_JHNFraipZEqn3oToTMoQGw)
Content-type: text/plain; name=proc.diff
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=proc.diff

Index: arch/i386/i386/process_machdep.c
===================================================================
RCS file: /usr/cvs/src/sys/arch/i386/i386/process_machdep.c,v
retrieving revision 1.59
diff -u -p -r1.59 process_machdep.c
--- arch/i386/i386/process_machdep.c	16 Nov 2006 01:32:38 -0000	1.59
+++ arch/i386/i386/process_machdep.c	22 Nov 2006 13:40:21 -0000
@@ -73,6 +73,7 @@ __KERNEL_RCSID(0, "$NetBSD: process_mach
 #include <sys/user.h>
 #include <sys/vnode.h>
 #include <sys/ptrace.h>
+#include <sys/kauth.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -472,6 +473,14 @@ ptrace_machdep_dorequest(
 	struct iovec iov;
 	int write = 0;
 
+	if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANTRACE,
+	    lt->l_proc, (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE, NULL,
+	    NULL) != 0)
+		return (EPERM);
+
+	if (!proc_isunder(lt->l_proc, l))
+		return (EPERM);
+
 	switch (req) {
 	case PT_SETXMMREGS:
 		write = 1;
@@ -524,9 +533,6 @@ process_machdep_doxmmregs(curl, l, uio)
 	char *kv;
 	int kl;
 
-	if ((error = process_checkioperm(curl, l->l_proc)) != 0)
-		return (error);
-
 	kl = sizeof(r);
 	kv = (char *) &r;
 
Index: arch/i386/i386/procfs_machdep.c
===================================================================
RCS file: /usr/cvs/src/sys/arch/i386/i386/procfs_machdep.c,v
retrieving revision 1.25
diff -u -p -r1.25 procfs_machdep.c
--- arch/i386/i386/procfs_machdep.c	16 Nov 2006 01:32:38 -0000	1.25
+++ arch/i386/i386/procfs_machdep.c	22 Nov 2006 13:27:16 -0000
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_machd
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/vnode.h>
+#include <sys/kauth.h>
 
 #include <miscfs/procfs/procfs.h>
 
@@ -214,6 +215,14 @@ procfs_machdep_rw(struct lwp *curl, stru
     struct uio *uio)
 {
 
+	if (kauth_authorize_process(curl->l_cred, KAUTH_PROCESS_CANTRACE,
+	    l->l_proc, (void *)KAUTH_REQ_PROCESS_CANTRACE_PROCFS, pfs,
+	    NULL) != 0)
+		return (EPERM);
+
+	if (!proc_isunder(l->l_proc, curl))
+		return (EPERM);
+
 	switch (pfs->pfs_type) {
 	case Pmachdep_xmmregs:
 		return (procfs_machdep_doxmmregs(curl, l, pfs, uio));
Index: arch/powerpc/powerpc/process_machdep.c
===================================================================
RCS file: /usr/cvs/src/sys/arch/powerpc/powerpc/process_machdep.c,v
retrieving revision 1.21
diff -u -p -r1.21 process_machdep.c
--- arch/powerpc/powerpc/process_machdep.c	1 Mar 2006 12:38:12 -0000	1.21
+++ arch/powerpc/powerpc/process_machdep.c	22 Nov 2006 13:26:07 -0000
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: process_mach
 #include <sys/user.h>
 #include <sys/systm.h>
 #include <sys/ptrace.h>
+#include <sys/kauth.h>
 
 #include <machine/fpu.h>
 #include <machine/pcb.h>
@@ -187,6 +188,14 @@ ptrace_machdep_dorequest(struct lwp *l, 
 	struct iovec iov;
 	int write = 0;
 
+	if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANTRACE,
+	    lt->l_proc, (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE, NULL,
+	    NULL) != 0)
+		return (EPERM);
+
+	if (!proc_isunder(lt->l_proc, l))
+		return (EPERM);
+
 	switch (req) {
 	case PT_SETVECREGS:
 		write = 1;
@@ -225,9 +234,6 @@ process_machdep_dovecregs(struct lwp *cu
 	char *kv;
 	int kl;
 
-	if ((error = process_checkioperm(curl, l->l_proc)) != 0)
-		return (error);
-
 	kl = sizeof(r);
 	kv = (char *) &r;
 
Index: arch/powerpc/powerpc/procfs_machdep.c
===================================================================
RCS file: /usr/cvs/src/sys/arch/powerpc/powerpc/procfs_machdep.c,v
retrieving revision 1.5
diff -u -p -r1.5 procfs_machdep.c
--- arch/powerpc/powerpc/procfs_machdep.c	11 Dec 2005 12:18:46 -0000	1.5
+++ arch/powerpc/powerpc/procfs_machdep.c	22 Nov 2006 13:26:29 -0000
@@ -8,6 +8,7 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_machd
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/vnode.h>
+#include <sys/kauth.h>
 #include <miscfs/procfs/procfs.h>
 
 #include <machine/reg.h>
@@ -47,6 +48,14 @@ procfs_machdep_rw(struct lwp *curl, stru
     struct uio *uio)
 {
 
+	if (kauth_authorize_process(curl->l_cred, KAUTH_PROCESS_CANTRACE,
+	    l->l_proc, (void *)KAUTH_REQ_PROCESS_CANTRACE_PROCFS, pfs,
+	    NULL) != 0)
+		return (EPERM);
+
+	if (!proc_isunder(l, curl->l_proc))
+		return (EPERM);
+
 	switch (pfs->pfs_type) {
 	case Pmachdep_vecregs:
 		return (procfs_machdep_dovecregs(curl, l, pfs, uio));
Index: miscfs/procfs/procfs_subr.c
===================================================================
RCS file: /usr/cvs/src/sys/miscfs/procfs/procfs_subr.c,v
retrieving revision 1.72
diff -u -p -r1.72 procfs_subr.c
--- miscfs/procfs/procfs_subr.c	16 Nov 2006 01:33:38 -0000	1.72
+++ miscfs/procfs/procfs_subr.c	21 Nov 2006 17:55:11 -0000
@@ -85,6 +85,7 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_subr.
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <sys/filedesc.h>
+#include <sys/kauth.h>
 
 #include <miscfs/procfs/procfs.h>
 
@@ -314,7 +315,8 @@ procfs_rw(v)
 	 * Do not allow init to be modified while in secure mode; it
 	 * could be duped into changing the security level.
 	 */
-	if (uio->uio_rw == UIO_WRITE && p == initproc && securelevel > -1)
+	if (kauth_authorize_process(kauth_cred_get(), KAUTH_PROCESS_CANTRACE,
+	    p, (void *)KAUTH_REQ_PROCESS_CANTRACE_PROCFS, pfs, NULL) != 0)
 		return EPERM;
 
 	curl = curlwp;
Index: miscfs/procfs/procfs_vnops.c
===================================================================
RCS file: /usr/cvs/src/sys/miscfs/procfs/procfs_vnops.c,v
retrieving revision 1.138
diff -u -p -r1.138 procfs_vnops.c
--- miscfs/procfs/procfs_vnops.c	16 Nov 2006 01:33:38 -0000	1.138
+++ miscfs/procfs/procfs_vnops.c	22 Nov 2006 13:28:24 -0000
@@ -280,7 +280,6 @@ procfs_open(v)
 	struct pfsnode *pfs = VTOPFS(ap->a_vp);
 	struct lwp *l1;
 	struct proc *p2;
-	int error;
 
 	l1 = ap->a_l;				/* tracer */
 	p2 = PFIND(pfs->pfs_pid);		/* traced */
@@ -288,15 +287,19 @@ procfs_open(v)
 	if (p2 == NULL)
 		return (ENOENT);		/* was ESRCH, jsp */
 
+	if (kauth_authorize_process(kauth_cred_get(), KAUTH_PROCESS_CANTRACE,
+	    p2, (void *)KAUTH_REQ_PROCESS_CANTRACE_PROCFS, pfs, NULL) != 0)
+		return (EPERM);
+
+	if (!proc_isunder(p2, l1))
+		return (EPERM);
+
 	switch (pfs->pfs_type) {
 	case PFSmem:
 		if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) ||
 		    ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)))
 			return (EBUSY);
 
-		if ((error = process_checkioperm(l1, p2)) != 0)
-			return (error);
-
 		if (ap->a_mode & FWRITE)
 			pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
 
Index: kern/sys_process.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/sys_process.c,v
retrieving revision 1.114
diff -u -p -r1.114 sys_process.c
--- kern/sys_process.c	13 Nov 2006 02:52:08 -0000	1.114
+++ kern/sys_process.c	22 Nov 2006 14:50:52 -0000
@@ -184,19 +184,16 @@ sys_ptrace(struct lwp *l, void *v, regis
 		 *	(4) it's not owned by you, or is set-id on exec
 		 *	    (unless you're root), or...
 		 */
-		if ((kauth_cred_getuid(t->p_cred) !=
-		    kauth_cred_getuid(l->l_cred) ||
-		    ISSET(t->p_flag, P_SUGID)) &&
-		    (error = kauth_authorize_generic(l->l_cred,
-		    KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
-			return (error);
 
 		/*
 		 *	(5) ...it's init, which controls the security level
 		 *	    of the entire system, and the system was not
 		 *	    compiled with permanently insecure mode turned on
 		 */
-		if (t == initproc && securelevel > -1)
+
+		if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANTRACE,
+		    t, (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE, NULL,
+		    NULL) != 0)
 			return (EPERM);
 
 		/*
@@ -329,6 +326,12 @@ sys_ptrace(struct lwp *l, void *v, regis
 		uio.uio_resid = sizeof(tmp);
 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
 		UIO_SETUP_SYSSPACE(&uio);
+
+		if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANTRACE,
+		    t, (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE, NULL,
+		    NULL) != 0)
+			return (EPERM);
+
 		error = process_domem(l, lt, &uio);
 		if (!write)
 			*retval = tmp;
@@ -361,6 +364,12 @@ sys_ptrace(struct lwp *l, void *v, regis
 		default:
 			return (EINVAL);
 		}
+
+		if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANTRACE,
+		    t, (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE, NULL,
+		    NULL) != 0)
+			return (EPERM);
+
 		error = process_domem(l, lt, &uio);
 		piod.piod_len -= uio.uio_resid;
 		(void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
@@ -573,6 +582,13 @@ sys_ptrace(struct lwp *l, void *v, regis
 			uio.uio_resid = sizeof(struct reg);
 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
 			uio.uio_vmspace = vm;
+
+			if (kauth_authorize_process(l->l_cred,
+			    KAUTH_PROCESS_CANTRACE, t,
+			    (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE,
+			    NULL, NULL) != 0)
+				return (EPERM);
+
 			error = process_doregs(l, lt, &uio);
 			uvmspace_free(vm);
 			return error;
@@ -611,6 +627,13 @@ sys_ptrace(struct lwp *l, void *v, regis
 			uio.uio_resid = sizeof(struct fpreg);
 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
 			uio.uio_vmspace = vm;
+
+			if (kauth_authorize_process(l->l_cred,
+			    KAUTH_PROCESS_CANTRACE, t,
+			    (void *)KAUTH_REQ_PROCESS_CANTRACE_PTRACE,
+			    NULL, NULL) != 0)
+				return (EPERM);
+
 			error = process_dofpregs(l, lt, &uio);
 			uvmspace_free(vm);
 			return error;
@@ -637,7 +660,6 @@ process_doregs(struct lwp *curl /*tracer
     struct uio *uio)
 {
 #if defined(PT_GETREGS) || defined(PT_SETREGS)
-	struct proc *p = l->l_proc;
 	int error;
 	struct reg r;
 	char *kv;
@@ -646,9 +668,6 @@ process_doregs(struct lwp *curl /*tracer
 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
 		return EINVAL;
 
-	if ((error = process_checkioperm(curl, p)) != 0)
-		return error;
-
 	kl = sizeof(r);
 	kv = (char *)&r;
 
@@ -695,7 +714,6 @@ process_dofpregs(struct lwp *curl /*trac
     struct uio *uio)
 {
 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
-	struct proc *p = l->l_proc;
 	int error;
 	struct fpreg r;
 	char *kv;
@@ -704,9 +722,6 @@ process_dofpregs(struct lwp *curl /*trac
 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
 		return EINVAL;
 
-	if ((error = process_checkioperm(curl, p)) != 0)
-		return (error);
-
 	kl = sizeof(r);
 	kv = (char *)&r;
 
@@ -772,9 +787,6 @@ process_domem(struct lwp *curl /*tracer*
 	addr = uio->uio_offset;
 #endif
 
-	if ((error = process_checkioperm(curl, p)) != 0)
-		return (error);
-
 	vm = p->p_vmspace;
 
 	simple_lock(&vm->vm_map.ref_lock);
Index: kern/kern_systrace.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_systrace.c,v
retrieving revision 1.61
diff -u -p -r1.61 kern_systrace.c
--- kern/kern_systrace.c	1 Nov 2006 10:17:58 -0000	1.61
+++ kern/kern_systrace.c	22 Nov 2006 14:31:15 -0000
@@ -1204,6 +1204,10 @@ systrace_io(struct str_process *strp, st
 	uio.uio_resid = io->strio_len;
 	uio.uio_vmspace = l->l_proc->p_vmspace;
 
+	if (kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANTRACE, t,
+	    (void *)KAUTH_REQ_PROCESS_CANTRACE_SYSTRACE, NULL, NULL) != 0)
+		return (EPERM);
+
 #ifdef __NetBSD__
 	error = process_domem(l, proc_representative_lwp(t), &uio);
 #else
@@ -1267,11 +1271,6 @@ systrace_attach(struct fsystrace *fst, p
 	 *	special privileges using setuid() from being
 	 *	traced. This is good security.]
 	 */
-	if ((kauth_cred_getuid(proc->p_cred) != kauth_cred_getuid(p->p_cred) ||
-		ISSET(proc->p_flag, P_SUGID)) &&
-	    (error = kauth_authorize_generic(p->p_cred, KAUTH_GENERIC_ISSUSER,
-				       &p->p_acflag)) != 0)
-		goto out;
 
 	/*
 	 *	(5) ...it's init, which controls the security level
@@ -1279,7 +1278,10 @@ systrace_attach(struct fsystrace *fst, p
 	 *          compiled with permanently insecure mode turned
 	 *	    on.
 	 */
-	if ((proc->p_pid == 1) && (securelevel > -1)) {
+
+	if (kauth_authorize_process(kauth_cred_get(), KAUTH_PROCESS_CANTRACE,
+	    proc, (void *)KAUTH_REQ_PROCESS_CANTRACE_SYSTRACE, NULL,
+	    NULL) != 0) {
 		error = EPERM;
 		goto out;
 	}
Index: kern/kern_ktrace.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.111
diff -u -p -r1.111 kern_ktrace.c
--- kern/kern_ktrace.c	1 Nov 2006 10:17:58 -0000	1.111
+++ kern/kern_ktrace.c	21 Nov 2006 14:05:27 -0000
@@ -1292,16 +1292,9 @@ ktrace_thread(void *arg)
 int
 ktrcanset(struct lwp *calll, struct proc *targetp)
 {
-	kauth_cred_t caller = calll->l_cred;
-	kauth_cred_t target = targetp->p_cred;
-
-	if ((kauth_cred_geteuid(caller) == kauth_cred_getuid(target) &&
-	    kauth_cred_getuid(target) == kauth_cred_getsvuid(target) &&
-	    kauth_cred_getgid(caller) == kauth_cred_getgid(target) &&	/* XXX */
-	    kauth_cred_getgid(target) == kauth_cred_getsvgid(target) &&
-	    (targetp->p_traceflag & KTRFAC_ROOT) == 0 &&
-	    (targetp->p_flag & P_SUGID) == 0) ||
-	    kauth_cred_geteuid(caller) == 0)
+	if (kauth_authorize_process(calll->l_cred, KAUTH_PROCESS_CANTRACE,
+	    targetp, (void *)KAUTH_REQ_PROCESS_CANTRACE_KTRACE, NULL,
+	    NULL) == 0)
 		return (1);
 
 	return (0);
Index: sys/kauth.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/kauth.h,v
retrieving revision 1.22
diff -u -p -r1.22 kauth.h
--- sys/kauth.h	22 Nov 2006 13:59:27 -0000	1.22
+++ sys/kauth.h	21 Nov 2006 13:43:37 -0000
@@ -118,6 +118,7 @@ enum kauth_system_req {
 enum {
 	KAUTH_PROCESS_CANSEE=1,
 	KAUTH_PROCESS_CANSIGNAL,
+	KAUTH_PROCESS_CANTRACE,
 	KAUTH_PROCESS_CORENAME,
 	KAUTH_PROCESS_RESOURCE,
 	KAUTH_PROCESS_SETID
@@ -127,7 +128,11 @@ enum {
  * Process scope - sub-actions.
  */
 enum {
-	KAUTH_REQ_PROCESS_RESOURCE_NICE=1,
+	KAUTH_REQ_PROCESS_CANTRACE_KTRACE=1,
+	KAUTH_REQ_PROCESS_CANTRACE_PROCFS,
+	KAUTH_REQ_PROCESS_CANTRACE_PTRACE,
+	KAUTH_REQ_PROCESS_CANTRACE_SYSTRACE,
+	KAUTH_REQ_PROCESS_RESOURCE_NICE,
 	KAUTH_REQ_PROCESS_RESOURCE_RLIMIT
 };
 
Index: secmodel/bsd44/secmodel_bsd44_suser.c
===================================================================
RCS file: /usr/cvs/src/sys/secmodel/bsd44/secmodel_bsd44_suser.c,v
retrieving revision 1.16
diff -u -p -r1.16 secmodel_bsd44_suser.c
--- secmodel/bsd44/secmodel_bsd44_suser.c	16 Nov 2006 01:33:51 -0000	1.16
+++ secmodel/bsd44/secmodel_bsd44_suser.c	21 Nov 2006 16:06:17 -0000
@@ -211,6 +211,74 @@ secmodel_bsd44_suser_process_cb(kauth_cr
 			result = KAUTH_RESULT_ALLOW;
 		break;
 
+	case KAUTH_PROCESS_CANTRACE:
+		switch ((u_long)arg1) {
+		case KAUTH_REQ_PROCESS_CANTRACE_KTRACE:
+			if (isroot) {
+				result = KAUTH_RESULT_ALLOW;
+				break;
+			}
+
+			if ((p->p_traceflag & KTRFAC_ROOT) ||
+			    (p->p_flag & P_SUGID)) {
+				result = KAUTH_RESULT_DENY;
+				break;
+			}
+
+			if (kauth_cred_geteuid(cred) ==
+			     kauth_cred_getuid(p->p_cred) &&
+			    kauth_cred_getuid(cred) ==
+			     kauth_cred_getsvuid(p->p_cred) &&
+			    kauth_cred_getgid(cred) ==
+			     kauth_cred_getgid(p->p_cred) && /* XXX */
+			    kauth_cred_getgid(cred) ==
+			     kauth_cred_getsvgid(p->p_cred)) {
+				result = KAUTH_RESULT_ALLOW;
+				break;
+			}
+
+			result = KAUTH_RESULT_DENY;
+			break;
+
+		case KAUTH_REQ_PROCESS_CANTRACE_PTRACE:
+			if (isroot) {
+				result = KAUTH_RESULT_ALLOW;
+				break;
+			}
+
+			if ((kauth_cred_getuid(cred) !=
+			     kauth_cred_getuid(p->p_cred)) ||
+			    ISSET(p->p_flag, P_SUGID)) {
+				result = KAUTH_RESULT_DENY;
+				break;
+			}
+
+			result = KAUTH_RESULT_ALLOW;
+
+			break;
+
+		case KAUTH_REQ_PROCESS_CANTRACE_SYSTRACE:
+			if (isroot) {
+				result = KAUTH_RESULT_ALLOW;
+				break;
+			}
+
+			if ((kauth_cred_getuid(cred) !=
+			     kauth_cred_getuid(p->p_cred)) ||
+			    ISSET(p->p_flag, P_SUGID)) {
+				result = KAUTH_RESULT_DENY;
+				break;
+			}
+
+			result = KAUTH_RESULT_ALLOW;
+			break;
+
+		default:
+			result = KAUTH_RESULT_DEFER;
+			break;
+		}
+		break;
+
 	case KAUTH_PROCESS_RESOURCE:
 		switch ((u_long)arg1) {
 		case KAUTH_REQ_PROCESS_RESOURCE_NICE:
Index: secmodel/bsd44/secmodel_bsd44_securelevel.c
===================================================================
RCS file: /usr/cvs/src/sys/secmodel/bsd44/secmodel_bsd44_securelevel.c,v
retrieving revision 1.16
diff -u -p -r1.16 secmodel_bsd44_securelevel.c
--- secmodel/bsd44/secmodel_bsd44_securelevel.c	22 Nov 2006 20:57:52 -0000	1.16
+++ secmodel/bsd44/secmodel_bsd44_securelevel.c	22 Nov 2006 14:54:19 -0000
@@ -227,11 +227,50 @@ secmodel_bsd44_securelevel_process_cb(ka
     kauth_action_t action, void *cookie, void *arg0,
     void *arg1, void *arg2, void *arg3)
 {
+	struct proc *p;
 	int result;
 
 	result = KAUTH_RESULT_DENY;
+	p = arg0;
 
 	switch (action) {
+	case KAUTH_PROCESS_CANTRACE:
+		switch ((u_long)arg1) {
+		case KAUTH_REQ_PROCESS_CANTRACE_PROCFS:
+			if ((p == initproc) && (securelevel >= 0)) {
+				result = KAUTH_RESULT_DENY;
+				break;
+			}
+
+			result = KAUTH_RESULT_ALLOW;
+
+			break;
+
+		case KAUTH_REQ_PROCESS_CANTRACE_PTRACE:
+			if ((p == initproc) && (securelevel >= 0)) {
+				result = KAUTH_RESULT_DENY;
+				break;
+			}
+
+			result = KAUTH_RESULT_ALLOW;
+
+			break;
+
+		case KAUTH_REQ_PROCESS_CANTRACE_SYSTRACE:
+			if ((p == initproc) && (securelevel >= 0)) {
+				result = KAUTH_RESULT_DENY;
+				break;
+			}
+
+			result = KAUTH_RESULT_ALLOW;
+
+			break;
+		default:
+			result = KAUTH_RESULT_DEFER;
+			break;
+		}
+		break;
+
 	case KAUTH_PROCESS_CORENAME:
 		if (securelevel < 2)
 			result = KAUTH_RESULT_ALLOW;

--Boundary_(ID_JHNFraipZEqn3oToTMoQGw)--