diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2013-09-10 10:05:59 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2013-09-10 10:05:59 +0000 |
commit | 1a05c762b9c203dec97fc053448eab98b525b088 (patch) | |
tree | 9f08d8dd919edd55c79e7cca2864adf598448f6e /sys/net/if.c | |
parent | 9dc29a3cf064004fb45826509e91a145b5da7674 (diff) | |
download | src-1a05c762b9c203dec97fc053448eab98b525b088.tar.gz src-1a05c762b9c203dec97fc053448eab98b525b088.zip |
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: re
Notes
Notes:
svn path=/head/; revision=255442
Diffstat (limited to 'sys/net/if.c')
-rw-r--r-- | sys/net/if.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 2cb3da013c21..0356ec7fbf46 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2553,11 +2553,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 { @@ -2601,7 +2613,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) { |