Vulnerability in 4.4BSD Secure Levels Implementation
Date: Sun, 14 Jun 1998 01:43:36 +1000
From: Darren Reed <avalon@COOMBS.ANU.EDU.AU. >
To: [email protected]
Subject: Re: Vulnerability in 4.4BSD Secure Levels Implementation
I'm not sure I see the value in that particular patch for this problem.
Rather than block out all ptrace access to processes, maybe it is more
appropriate to protect all processes on a system where securelevel > 0
- irrespective of whether or not it's init or immutable - from operations
which could `change' it if it is an immutable executeable.
Anyway, below I've attached what I hope is a "better" patch - allows
ptrace to be used in read-only mode on immutable processes (or init)
where the system is running where securelevel > 0.
Darren
sys_process.c.orig Sun Jun 14 01:17:14 1998
--- sys_process.c Sun Jun 14 01:39:15 1998
***************
37,42 ****
--- 37,43 ----
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/ptrace.h>
+ #include <sys/stat.h>
#include <sys/errno.h>
#include <sys/queue.h>
***************
243,248 ****
--- 244,253 ----
if (p->p_flag & P_TRACED)
return EBUSY;
+ /* Tracing a system process doesn't work anyway */
+ if (p->p_flag & P_SYSTEM)
+ return EINVAL;
+
/* not owned by you, has done setuid (unless you're root) */
if ((p->p_cred->p_ruid != curp->p_cred->p_ruid) ||
(p->p_flag & P_SUGID)) {
***************
250,268 ****
return error;
}
- /* can't trace init when securelevel > 0 */
- if (securelevel > 0 && p->p_pid == 1)
- return EPERM;
-
/* OK */
break;
- case PT_READ_I:
- case PT_READ_D:
- case PT_READ_U:
case PT_WRITE_I:
case PT_WRITE_D:
case PT_WRITE_U:
case PT_CONTINUE:
case PT_KILL:
case PT_STEP:
--- 255,284 ----
return error;
}
/* OK */
break;
case PT_WRITE_I:
case PT_WRITE_D:
case PT_WRITE_U:
+ #ifdef PT_SETREGS
+ case PT_SETREGS:
+ #endif
+ #ifdef PT_SETFPREGS
+ case PT_SETFPREGS:
+ #endif
+ if ((error = VOP_GETATTR(p->p_textvp, &va, p->p_ucred, p)) != 0)
+ return error;
+ /*
+ * disallow changes to immutable executeables running in a
+ * `secure' kernel environment.
+ */
+ if ((securelevel > 0) &&
+ ((va.va_flags & (IMMUTABLE|NOUNLINK)) || (p->p_pid == 1)))
+ return EPERM;
+ case PT_READ_I:
+ case PT_READ_D:
+ case PT_READ_U:
case PT_CONTINUE:
case PT_KILL:
case PT_STEP:
***************
270,283 ****
#ifdef PT_GETREGS
case PT_GETREGS:
#endif
- #ifdef PT_SETREGS
- case PT_SETREGS:
- #endif
#ifdef PT_GETFPREGS
case PT_GETFPREGS:
- #endif
- #ifdef PT_SETFPREGS
- case PT_SETFPREGS:
#endif
/* not being traced... */
if ((p->p_flag & P_TRACED) == 0)
--- 286,293 ----
procfs_vnops.c.orig Sun Jun 14 01:25:29 1998
--- procfs_vnops.c Sun Jun 14 01:27:54 1998
***************
121,126 ****
--- 121,128 ----
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
struct proc *p1 = ap->a_p, *p2 = PFIND(pfs->pfs_pid);
+ int error;
+ struct vattr va;
if (p2 == NULL)
return ENOENT;
***************
135,144 ****
(p1->p_cred->pc_ucred->cr_gid != KMEM_GROUP))
return EPERM;
!
! if (ap->a_mode & FWRITE)
pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
!
return (0);
default:
--- 137,150 ----
(p1->p_cred->pc_ucred->cr_gid != KMEM_GROUP))
return EPERM;
! error = VOP_GETATTR(p2->p_textvp, &va, p1->p_ucred, p1);
! if (error)
! return error;
! if (ap->a_mode & FWRITE) {
! if (va.va_flags & IMMUTABLE)
! return EPERM;
pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
! }
return (0);
default: