svn commit: r191456 - head/sys/netinet

Robert Watson rwatson at FreeBSD.org
Fri Apr 24 09:54:47 UTC 2009


Author: rwatson
Date: Fri Apr 24 09:54:46 2009
New Revision: 191456
URL: http://svn.freebsd.org/changeset/base/191456

Log:
  Relocate permissions checking code in in_control() to before the body
  of the implementation of ioctls.  This makes the mapping of ioctls to
  specific privileges more explicit, and also simplifies the
  implementation by reducing the use of FALLTHROUGH handling in switch.
  
  While this is not intended to be a functional change, it does mean
  that certain privilege checks are now performed earlier, so EPERM
  might be returned in preference to EADDRNOTAVAIL for management
  ioctls that could have failed for both reasons.
  
  MFC after:	3 weeks

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Fri Apr 24 08:57:54 2009	(r191455)
+++ head/sys/netinet/in.c	Fri Apr 24 09:54:46 2009	(r191456)
@@ -280,6 +280,31 @@ in_control(struct socket *so, u_long cmd
 		return (EADDRNOTAVAIL);
 
 	/*
+	 * Security checks before we get involved in any work.
+	 */
+	switch (cmd) {
+	case SIOCAIFADDR:
+	case SIOCSIFADDR:
+	case SIOCSIFBRDADDR:
+	case SIOCSIFNETMASK:
+	case SIOCSIFDSTADDR:
+		if (td != NULL) {
+			error = priv_check(td, PRIV_NET_ADDIFADDR);
+			if (error)
+				return (error);
+		}
+		break;
+
+	case SIOCDIFADDR:
+		if (td != NULL) {
+			error = priv_check(td, PRIV_NET_DELIFADDR);
+			if (error)
+				return (error);
+		}
+		break;
+	}
+
+	/*
 	 * Find address for this interface, if it exists.
 	 *
 	 * If an alias address was specified, find that one instead of the
@@ -334,13 +359,6 @@ in_control(struct socket *so, u_long cmd
 	case SIOCSIFADDR:
 	case SIOCSIFNETMASK:
 	case SIOCSIFDSTADDR:
-		if (td != NULL) {
-			error = priv_check(td, (cmd == SIOCDIFADDR) ? 
-			    PRIV_NET_DELIFADDR : PRIV_NET_ADDIFADDR);
-			if (error)
-				return (error);
-		}
-
 		if (ia == NULL) {
 			ia = (struct in_ifaddr *)
 				malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO);
@@ -376,13 +394,6 @@ in_control(struct socket *so, u_long cmd
 		break;
 
 	case SIOCSIFBRDADDR:
-		if (td != NULL) {
-			error = priv_check(td, PRIV_NET_ADDIFADDR);
-			if (error)
-				return (error);
-		}
-		/* FALLTHROUGH */
-
 	case SIOCGIFADDR:
 	case SIOCGIFNETMASK:
 	case SIOCGIFDSTADDR:


More information about the svn-src-head mailing list