Re: Vulnerability in 4.4BSD Secure Levels Implementation

From: Darren Reed (avalonat_private)
Date: Sat Jun 13 1998 - 08:43:36 PDT

  • Next message: Gus: "Re: more named warez"

    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:
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:57:54 PDT