Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Jan 2000 16:05:36 -0800 (PST)
From:      Michael Oswell <oswell@xcert.com>
To:        Warner Losh <imp@village.org>
Cc:        Matthew Dillon <dillon@apollo.backplane.com>, Tim Yardley <yardley@uiuc.edu>, freebsd-security@FreeBSD.ORG
Subject:   Re: Fwd: *BSD procfs vulnerability 
Message-ID:  <Pine.BSF.4.21.0001241557240.89994-100000@oswell.x509.com>
In-Reply-To: <200001241334.GAA02980@harmony.village.org>

next in thread | previous in thread | raw e-mail | index | archive | help

I've manually taken the information from the 3.x patch and used it to
patch a 2.2.7 box we had here.  It appears to work, though all I have done
to test this is run the exploit script that was sent to bugtraq. 

I have also run the patch against a 2.2.8 box successfully (and recompiled
the kernel), though have yet to reboot to the box to be sure it works.

The actual code in the patch below is identical to the one that was
released for 3.2 (just manually inserted instead of using patch).  Like I
said, it appears to work here, though I make no guarentees to anyone that
this is the best or correct way to patch the 2.2.x kernels for this bug.


*** sys/filedesc.h	Fri Feb 23 10:49:21 1996
--- sys/filedesc.h.patched	Mon Jan 24 11:50:34 2000
***************
*** 106,112 ****
--- 106,113 ----
  void	fdfree __P((struct proc *p));
  int	closef __P((struct file *fp,struct proc *p));
  void	fdcloseexec __P((struct proc *p));
  int	getvnode __P((struct filedesc *fdp, int fd, struct file **fpp));
+ void	setugidsafety __P((struct proc *p));
  #endif
  
  #endif
*** kern/kern_descrip.c	Sat Dec 21 11:04:24 1996
--- kern/kern_descrip.c.patched	Mon Jan 24 11:52:13 2000
***************
*** 977,984 ****
--- 977,1041 ----
  	p->p_dupfd = minor(dev);
  	return (ENODEV);
  }
  
+  /*
+  * For setuid/setgid programs we don't want to people to use that setuidness
+  * to generate error messages which write to a file which otherwise would 
+  * otherwise be off limits to the proces.
+  * 
+  * This is a gross hack to plug the hole.  A better solution would involve
+  * a special vop or other form of generalized access control mechanism.  We
+  * go ahead and just reject all procfs file systems accesses as dangerous.
+  *
+  * Since setugidsafety calls this only for fd 0, 1 and 2, this check is
+  * sufficient.  We also don't for setugidness since we know we are.
+  */
+ static int
+ is_unsafe(struct file *fp)
+ {
+        if (fp->f_type == DTYPE_VNODE &&
+            ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS)
+                return (1);
+        return (0);
+ }   
+ 
+ /*
+  * Make this setguid thing safe, if at all possible.
+  */
+ void
+ setugidsafety(p)  
+        struct proc *p;
+ {
+        struct filedesc *fdp = p->p_fd;
+        struct file **fpp;
+        char *fdfp;
+        register int i;
+        
+        /* Certain daemons might not have file descriptors. */
+        if (fdp == NULL)
+                return;   
+                        
+        fpp = fdp->fd_ofiles;
+        fdfp = fdp->fd_ofileflags;
+        for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) {
+                if (i > 2)
+                        break;
+                if (*fpp != NULL && is_unsafe(*fpp)) {
+                        if (*fdfp & UF_MAPPED)
+                                (void) munmapfd(p, i);
+                        (void) closef(*fpp, p); 
+                        *fpp = NULL;
+                        *fdfp = 0;
+                        if (i < fdp->fd_freefile)
+                                fdp->fd_freefile = i;
+                }
+        }
+        while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
+                fdp->fd_lastfile--;
+ }
+ 
+ 
  /*
   * Duplicate the specified descriptor to a free descriptor.
   */
  int
*** kern/kern_exec.c	Mon Mar  2 00:54:56 1998
--- kern/kern_exec.c.patched	Mon Jan 24 11:52:52 2000
***************
*** 318,325 ****
--- 318,326 ----
  			p->p_ucred->cr_uid = attr.va_uid;
  		if (attr.va_mode & VSGID)
  			p->p_ucred->cr_gid = attr.va_gid;
  		p->p_flag |= P_SUGID;
+ 		setugidsafety(p);
  	} else {
  	        if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
  		    p->p_ucred->cr_gid == p->p_cred->p_rgid)
  			p->p_flag &= ~P_SUGID;

---------------------------

 On Mon, 24 Jan 2000, Warner Losh wrote:

> Sure would be nice.  Don't have the machines or time to do it myself.
> 2.x is no longer officially supported.
> 

-----
Michael Oswell
Xcert International Inc.




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0001241557240.89994-100000>