svn commit: r255443 - in stable/9/sys: fs/nullfs kern net netinet6 netnatm
Dag-Erling Smørgrav
des at FreeBSD.org
Tue Sep 10 10:07:23 UTC 2013
Author: des
Date: Tue Sep 10 10:07:21 2013
New Revision: 255443
URL: http://svnweb.freebsd.org/changeset/base/255443
Log:
Fix the length calculation for the final block of a sendfile(2)
transmission which could be tricked into rounding up to the nearest
page size, leaking up to a page of kernel memory. [13:11]
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-5666
Security: FreeBSD-SA-13:11.sendfile
Security: CVE-2013-5691
Security: FreeBSD-SA-13:12.ifioctl
Security: CVE-2013-5710
Security: FreeBSD-SA-13:13.nullfs
Approved by: so
Modified:
stable/9/sys/fs/nullfs/null_vnops.c
stable/9/sys/kern/uipc_syscalls.c
stable/9/sys/net/if.c
stable/9/sys/netinet6/in6.c
stable/9/sys/netnatm/natm.c
Modified: stable/9/sys/fs/nullfs/null_vnops.c
==============================================================================
--- stable/9/sys/fs/nullfs/null_vnops.c Tue Sep 10 10:05:59 2013 (r255442)
+++ stable/9/sys/fs/nullfs/null_vnops.c Tue Sep 10 10:07:21 2013 (r255443)
@@ -858,6 +858,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
*/
@@ -871,6 +880,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,
Modified: stable/9/sys/kern/uipc_syscalls.c
==============================================================================
--- stable/9/sys/kern/uipc_syscalls.c Tue Sep 10 10:05:59 2013 (r255442)
+++ stable/9/sys/kern/uipc_syscalls.c Tue Sep 10 10:07:21 2013 (r255443)
@@ -2126,11 +2126,10 @@ retry_space:
* or the passed in nbytes.
*/
pgoff = (vm_offset_t)(off & PAGE_MASK);
- if (uap->nbytes)
- rem = (uap->nbytes - fsbytes - loopbytes);
- else
- rem = va.va_size -
- uap->offset - fsbytes - loopbytes;
+ rem = va.va_size - uap->offset;
+ if (uap->nbytes != 0)
+ rem = omin(rem, uap->nbytes);
+ rem -= fsbytes + loopbytes;
xfsize = omin(PAGE_SIZE - pgoff, rem);
xfsize = omin(space - loopbytes, xfsize);
if (xfsize <= 0) {
Modified: stable/9/sys/net/if.c
==============================================================================
--- stable/9/sys/net/if.c Tue Sep 10 10:05:59 2013 (r255442)
+++ stable/9/sys/net/if.c Tue Sep 10 10:07:21 2013 (r255443)
@@ -2555,11 +2555,23 @@ ifioctl(struct socket *so, u_long cmd, c
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
{
@@ -2603,7 +2615,9 @@ ifioctl(struct socket *so, u_long cmd, c
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) {
Modified: stable/9/sys/netinet6/in6.c
==============================================================================
--- stable/9/sys/netinet6/in6.c Tue Sep 10 10:05:59 2013 (r255442)
+++ stable/9/sys/netinet6/in6.c Tue Sep 10 10:07:21 2013 (r255443)
@@ -422,6 +422,18 @@ in6_control(struct socket *so, u_long cm
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;
Modified: stable/9/sys/netnatm/natm.c
==============================================================================
--- stable/9/sys/netnatm/natm.c Tue Sep 10 10:05:59 2013 (r255442)
+++ stable/9/sys/netnatm/natm.c Tue Sep 10 10:07:21 2013 (r255443)
@@ -339,6 +339,21 @@ natm_usr_control(struct socket *so, u_lo
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));
More information about the svn-src-stable-9
mailing list