Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Mar 1997 00:07:51 -0600 (CST)
From:      tqbf@babel.enteract.com
To:        freebsd-security@freebsd.org
Subject:   Privileged ports...
Message-ID:  <19970326060751.3783.qmail@smtp.enteract.com>

next in thread | raw e-mail | index | archive | help
As part of a gradual effort to rid my kernel of suser() calls, I whipped
up a quick patch to in_pcb.c that configurably removes the superuser
restriction on binding privileged ports. 

This has the effect of removing the requirement for programs like rlogin
and rsh to run with superuser privs, thus eliminating a few more SUID
programs. In place of suser(), I've inserted two new sysctl OIDs under
net.inet.ip - resv_uid and resv_gid.  Any process running with an
effective UID of "resv_uid" or belonging to group "resv_gid" can now bind
low ports. 

The idea here is to set the system up so that a hole in "rlogin" or "rsh"
no longer provides root access - instead, an attacker only has the ability
to bind privileged ports. While this is a problem on some networks
(obviously this breaks host trust), it's a benefit to networks that don't
rely on the concept in the first place. Meanwhile, privileged ports are as
restricted as they were before - the restrictions are just configurable. 

I'm interested in comments and suggestions regarding the implementation of
more granularity in kernel-level privilege. Thanks to Guido van Rooij for
showing me how FreeBSD's sysctl works. 

*** in_pcb.c-pre-tqbf	Tue Mar 25 23:09:13 1997
--- in_pcb.c	Tue Mar 25 23:39:34 1997
***************
*** 64,67 ****
--- 64,69 ----
  static void	 in_pcbinshash __P((struct inpcb *));
  static void	 in_rtchange __P((struct inpcb *, int));
+ static int	 in_okresvport __P((struct proc *));
+ static int 	 cred_isingroup __P((gid_t, struct proc *));
  
  /*
***************
*** 189,194 ****
  			/* GROSS */
  			if (ntohs(lport) < IPPORT_RESERVED &&
! 			    (error = suser(p->p_ucred, &p->p_acflag)))
! 				return (EACCES);
  			t = in_pcblookup(inp->inp_pcbinfo, zeroin_addr, 0,
  			    sin->sin_addr, lport, wild);
--- 191,197 ----
  			/* GROSS */
  			if (ntohs(lport) < IPPORT_RESERVED &&
! 			   !in_okresvport(p))			
! 					return (EACCES);
! 
  			t = in_pcblookup(inp->inp_pcbinfo, zeroin_addr, 0,
  			    sin->sin_addr, lport, wild);
***************
*** 209,213 ****
  			lastport = &inp->inp_pcbinfo->lasthi;
  		} else if (inp->inp_flags & INP_LOWPORT) {
! 			if (error = suser(p->p_ucred, &p->p_acflag))
  				return (EACCES);
  			first = ipport_lowfirstauto;	/* 1023 */
--- 212,216 ----
  			lastport = &inp->inp_pcbinfo->lasthi;
  		} else if (inp->inp_flags & INP_LOWPORT) {
! 			if (!in_okresvport(p))
  				return (EACCES);
  			first = ipport_lowfirstauto;	/* 1023 */
***************
*** 747,749 ****
--- 750,801 ----
  	LIST_INSERT_HEAD(head, inp, inp_hash);
  	splx(s);
+ }
+ 
+ static int resv_uid;
+ static int resv_gid;
+ 
+ SYSCTL_INT(_net_inet_ip, 
+ 	   IPCTL_RESVUID, 
+ 	   resv_uid, 
+    	   CTLFLAG_RW, 
+ 	   &resv_uid,
+ 	   0,
+ 	   "");
+ 
+ SYSCTL_INT(_net_inet_ip, 
+ 	   IPCTL_RESVGID, 
+ 	   resv_gid, 
+    	   CTLFLAG_RW, 
+ 	   &resv_gid,
+ 	   0,
+ 	   "");
+ 
+ static int in_okresvport(struct proc *prc) {
+ 	int error;
+ 
+ 	error = suser(prc->p_ucred, &prc->p_acflag);
+ 	if(!error)
+ 		return(1);
+ 
+ 	if(resv_uid &&
+ 	   prc->p_ucred->cr_uid == resv_uid)
+ 		return(1);
+ 
+ 	if(resv_gid &&
+ 	   cred_isingroup((gid_t) resv_gid, prc))
+ 		return(1);
+ 
+ 	return(0);
+ }
+ 
+ int cred_isingroup(gid_t gid, struct proc *prc) {
+ 	struct ucred *uc = prc->p_ucred;
+ 	short i;
+ 	
+ 	for(i = 0; i < uc->cr_ngroups; i++) {
+ 		if(gid == uc->cr_groups[i])
+ 			return(1);
+ 	}
+ 
+ 	return(0);
  }

*** in.h-pre-tqbf	Tue Mar 25 23:46:16 1997
--- in.h	Tue Mar 25 23:48:51 1997
***************
*** 304,307 ****
--- 304,309 ----
  #define IPCTL_INTRQDROPS	11	/* number of netisr q drops */
  #define	IPCTL_MAXID		12
+ #define IPCTL_RESVUID		20	/* UID to bind privileged ports */
+ #define IPCTL_RESVGID		21	/* GID to bind privileged ports */
  
  #define	IPCTL_NAMES { \



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19970326060751.3783.qmail>