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

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

original patch had two issues:
  - semantic issue of not checking for P_INEXEC in places where
    process_checkioperm() was removed.

  - 'error' in process_domem() was not initialized, which broke stuff.

thanks to skrll@ for reporting breakage.

updated version attached.

-e.

-- 
Elad Efrat

--Boundary_(ID_LNM9BQrKcRaPhniCJygjVg)
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 18:15:41 -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,17 @@ ptrace_machdep_dorequest(
 	struct iovec iov;
 	int write = 0;
 
+	if (ISSET(lt->l_proc->p_flag, P_INEXEC))
+		return (EAGAIN);
+
+	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 +536,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 18:15:51 -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,17 @@ procfs_machdep_rw(struct lwp *curl, stru
     struct uio *uio)
 {
 
+	if (ISSET(l->l_proc->p_flag, P_INEXEC))
+		return (EAGAIN);
+
+	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 18:16:06 -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,17 @@ ptrace_machdep_dorequest(struct lwp *l, 
 	struct iovec iov;
 	int write = 0;
 
+	if (ISSET(lt->l_proc->p_flag, P_INEXEC))
+		return (EAGAIN);
+
+	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 +237,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 18:16:42 -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,17 @@ procfs_machdep_rw(struct lwp *curl, stru
     struct uio *uio)
 {
 
+	if (ISSET(l->l_proc->p_flag, P_INEXEC))
+		return (EAGAIN);
+
+	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 18:31: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,22 @@ procfs_open(v)
 	if (p2 == NULL)
 		return (ENOENT);		/* was ESRCH, jsp */
 
+	if (ISSET(p2->p_flag, P_INEXEC))
+		return (EAGAIN);
+
+	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 20:23:07 -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,8 +668,8 @@ 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;
+	if (ISSET(l->l_proc->p_flag, P_INEXEC))
+		return (EAGAIN);
 
 	kl = sizeof(r);
 	kv = (char *)&r;
@@ -695,7 +717,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,8 +725,8 @@ 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);
+	if (ISSET(l->l_proc->p_flag, P_INEXEC))
+		return (EAGAIN);
 
 	kl = sizeof(r);
 	kv = (char *)&r;
@@ -763,6 +784,7 @@ process_domem(struct lwp *curl /*tracer*
 	vaddr_t	addr;
 #endif
 
+	error = 0;
 	len = uio->uio_resid;
 
 	if (len == 0)
@@ -772,8 +794,8 @@ process_domem(struct lwp *curl /*tracer*
 	addr = uio->uio_offset;
 #endif
 
-	if ((error = process_checkioperm(curl, p)) != 0)
-		return (error);
+	if (ISSET(p->p_flag, P_INEXEC))
+		return (EAGAIN);
 
 	vm = p->p_vmspace;
 
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_LNM9BQrKcRaPhniCJygjVg)--