Bugtraq mailing list archives

Re: Vulnerability in 4.4BSD Secure Levels Implementation


From: avalon () COOMBS ANU EDU AU (Darren Reed)
Date: Sun, 14 Jun 1998 01:43:36 +1000


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:



Current thread: