aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2013-09-10 10:13:14 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2013-09-10 10:13:14 +0000
commit7a0109492beceecbaa84a70be78e95fcd2caf6e2 (patch)
tree6d783dec588a42124c02a6c5b935b8e99287e16c
parente72a33b081cc5ff2ccfbeb6eb899e5cd3112528b (diff)
downloadsrc-7a0109492beceecbaa84a70be78e95fcd2caf6e2.tar.gz
src-7a0109492beceecbaa84a70be78e95fcd2caf6e2.zip
In IPv6 and NetATM, stop SIOCSIFADDR, SIOCSIFBRDADDR, SIOCSIFDSTADDR
and SIOCSIFNETMASK at the socket layer rather than pass them on to the link layer without validation or credential checks. [SA-13:12] Prevent cross-mount hardlinks between different nullfs mounts of the same underlying filesystem. [SA-13:13] Security: CVE-2013-5691 Security: FreeBSD-SA-13:12.ifioctl Security: CVE-2013-5710 Security: FreeBSD-SA-13:13.nullfs Approved by: so
Notes
Notes: svn path=/releng/8.3/; revision=255446
-rw-r--r--UPDATING11
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/fs/nullfs/null_vnops.c10
-rw-r--r--sys/net/if.c18
-rw-r--r--sys/netinet6/in6.c12
-rw-r--r--sys/netnatm/natm.c15
6 files changed, 65 insertions, 3 deletions
diff --git a/UPDATING b/UPDATING
index 44fb89ff04bb..6964b47b6a10 100644
--- a/UPDATING
+++ b/UPDATING
@@ -15,6 +15,17 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW ON IA64 OR SUN4V:
debugging tools present in HEAD were left in place because
sun4v support still needs work to become production ready.
+20130910: p11 FreeBSD-SA-13:12.ifioctl
+ FreeBSD-SA-13:13.nullfs
+
+ In IPv6 and NetATM, stop SIOCSIFADDR, SIOCSIFBRDADDR,
+ SIOCSIFDSTADDR and SIOCSIFNETMASK at the socket layer rather
+ than pass them on to the link layer without validation or
+ credential checks. [SA-13:12]
+
+ Prevent cross-mount hardlinks between different nullfs mounts
+ of the same underlying filesystem. [SA-13:13]
+
20130822: p10 FreeBSD-SA-13:09.ip_multicast
FreeBSD-SA-13:10.sctp
Fix an integer overflow in computing the size of a temporary buffer
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 1c2eb32c7f20..dff5a1f503cf 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="8.3"
-BRANCH="RELEASE-p10"
+BRANCH="RELEASE-p11"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index 265ee742df08..65cf71e9c3fa 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -817,6 +817,15 @@ null_vptocnp(struct vop_vptocnp_args *ap)
return (error);
}
+static int
+null_link(struct vop_link_args *ap)
+{
+
+ if (ap->a_tdvp->v_mount != ap->a_vp->v_mount)
+ return (EXDEV);
+ return (null_bypass((struct vop_generic_args *)ap));
+}
+
/*
* Global vfs data structures
*/
@@ -829,6 +838,7 @@ struct vop_vector null_vnodeops = {
.vop_getwritemount = null_getwritemount,
.vop_inactive = null_inactive,
.vop_islocked = vop_stdislocked,
+ .vop_link = null_link,
.vop_lock1 = null_lock,
.vop_lookup = null_lookup,
.vop_open = null_open,
diff --git a/sys/net/if.c b/sys/net/if.c
index b950e002f8c9..2e4731a015b5 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2606,11 +2606,23 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
CURVNET_RESTORE();
return (EOPNOTSUPP);
}
+
+ /*
+ * Pass the request on to the socket control method, and if the
+ * latter returns EOPNOTSUPP, directly to the interface.
+ *
+ * Make an exception for the legacy SIOCSIF* requests. Drivers
+ * trust SIOCSIFADDR et al to come from an already privileged
+ * layer, and do not perform any credentials checks or input
+ * validation.
+ */
#ifndef COMPAT_43
error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
data,
ifp, td));
- if (error == EOPNOTSUPP && ifp != NULL && ifp->if_ioctl != NULL)
+ if (error == EOPNOTSUPP && ifp != NULL && ifp->if_ioctl != NULL &&
+ cmd != SIOCSIFADDR && cmd != SIOCSIFBRDADDR &&
+ cmd != SIOCSIFDSTADDR && cmd != SIOCSIFNETMASK)
error = (*ifp->if_ioctl)(ifp, cmd, data);
#else
{
@@ -2654,7 +2666,9 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
data,
ifp, td));
if (error == EOPNOTSUPP && ifp != NULL &&
- ifp->if_ioctl != NULL)
+ ifp->if_ioctl != NULL &&
+ cmd != SIOCSIFADDR && cmd != SIOCSIFBRDADDR &&
+ cmd != SIOCSIFDSTADDR && cmd != SIOCSIFNETMASK)
error = (*ifp->if_ioctl)(ifp, cmd, data);
switch (ocmd) {
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 56e6ea40808b..b1b6fe3aa439 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -339,6 +339,18 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
case SIOCGIFSTAT_ICMP6:
sa6 = &ifr->ifr_addr;
break;
+ case SIOCSIFADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCSIFDSTADDR:
+ case SIOCSIFNETMASK:
+ /*
+ * Although we should pass any non-INET6 ioctl requests
+ * down to driver, we filter some legacy INET requests.
+ * Drivers trust SIOCSIFADDR et al to come from an already
+ * privileged layer, and do not perform any credentials
+ * checks or input validation.
+ */
+ return (EINVAL);
default:
sa6 = NULL;
break;
diff --git a/sys/netnatm/natm.c b/sys/netnatm/natm.c
index cfcbaa786c73..c7bebc2bb0a8 100644
--- a/sys/netnatm/natm.c
+++ b/sys/netnatm/natm.c
@@ -339,6 +339,21 @@ natm_usr_control(struct socket *so, u_long cmd, caddr_t arg,
npcb = (struct natmpcb *)so->so_pcb;
KASSERT(npcb != NULL, ("natm_usr_control: npcb == NULL"));
+ switch (cmd) {
+ case SIOCSIFADDR:
+ case SIOCSIFBRDADDR:
+ case SIOCSIFDSTADDR:
+ case SIOCSIFNETMASK:
+ /*
+ * Although we should pass any non-ATM ioctl requests
+ * down to driver, we filter some legacy INET requests.
+ * Drivers trust SIOCSIFADDR et al to come from an already
+ * privileged layer, and do not perform any credentials
+ * checks or input validation.
+ */
+ return (EINVAL);
+ }
+
if (ifp == NULL || ifp->if_ioctl == NULL)
return (EOPNOTSUPP);
return ((*ifp->if_ioctl)(ifp, cmd, arg));