netinet: pass cred instead of the curthread to ifaddr manipulation funcs.
Pass the credentials directly to the functions, so non-ioctl kernel users can also performan address manipulations. MFC after: 2 weeks
This commit is contained in:
parent
b3ab58bd43
commit
f375bf0e6f
@ -76,9 +76,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/udp_var.h>
|
||||
|
||||
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
|
||||
static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
|
||||
static int in_gifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *);
|
||||
static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct ucred *);
|
||||
static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct ucred *);
|
||||
static int in_gifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct ucred *);
|
||||
|
||||
static void in_socktrim(struct sockaddr_in *);
|
||||
static void in_purgemaddrs(struct ifnet *);
|
||||
@ -337,6 +337,8 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
|
||||
if (ifp == NULL)
|
||||
return (EADDRNOTAVAIL);
|
||||
|
||||
struct ucred *cred = (td != NULL) ? td->td_ucred : NULL;
|
||||
|
||||
/*
|
||||
* Filter out 4 ioctls we implement directly. Forward the rest
|
||||
* to specific functions and ifp->if_ioctl().
|
||||
@ -349,18 +351,18 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
|
||||
break;
|
||||
case SIOCGIFALIAS:
|
||||
sx_xlock(&in_control_sx);
|
||||
error = in_gifaddr_ioctl(cmd, data, ifp, td);
|
||||
error = in_gifaddr_ioctl(cmd, data, ifp, cred);
|
||||
sx_xunlock(&in_control_sx);
|
||||
return (error);
|
||||
case SIOCDIFADDR:
|
||||
sx_xlock(&in_control_sx);
|
||||
error = in_difaddr_ioctl(cmd, data, ifp, td);
|
||||
error = in_difaddr_ioctl(cmd, data, ifp, cred);
|
||||
sx_xunlock(&in_control_sx);
|
||||
return (error);
|
||||
case OSIOCAIFADDR: /* 9.x compat */
|
||||
case SIOCAIFADDR:
|
||||
sx_xlock(&in_control_sx);
|
||||
error = in_aifaddr_ioctl(cmd, data, ifp, td);
|
||||
error = in_aifaddr_ioctl(cmd, data, ifp, cred);
|
||||
sx_xunlock(&in_control_sx);
|
||||
return (error);
|
||||
case SIOCSIFADDR:
|
||||
@ -376,7 +378,7 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
|
||||
}
|
||||
|
||||
if (addr->sin_addr.s_addr != INADDR_ANY &&
|
||||
prison_check_ip4(td->td_ucred, &addr->sin_addr) != 0)
|
||||
prison_check_ip4(cred, &addr->sin_addr) != 0)
|
||||
return (EADDRNOTAVAIL);
|
||||
|
||||
/*
|
||||
@ -396,7 +398,7 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
|
||||
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
ia = (struct in_ifaddr *)ifa;
|
||||
if (prison_check_ip4(td->td_ucred,
|
||||
if (prison_check_ip4(cred,
|
||||
&ia->ia_addr.sin_addr) == 0)
|
||||
break;
|
||||
}
|
||||
@ -439,7 +441,7 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
|
||||
}
|
||||
|
||||
static int
|
||||
in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct ucred *cred)
|
||||
{
|
||||
const struct in_aliasreq *ifra = (struct in_aliasreq *)data;
|
||||
const struct sockaddr_in *addr = &ifra->ifra_addr;
|
||||
@ -453,7 +455,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
bool iaIsFirst;
|
||||
int error = 0;
|
||||
|
||||
error = priv_check(td, PRIV_NET_ADDIFADDR);
|
||||
error = priv_check_cred(cred, PRIV_NET_ADDIFADDR);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
@ -493,7 +495,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
|
||||
it = (struct in_ifaddr *)ifa;
|
||||
if (it->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
|
||||
prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0)
|
||||
prison_check_ip4(cred, &addr->sin_addr) == 0)
|
||||
ia = it;
|
||||
else
|
||||
iaIsFirst = false;
|
||||
@ -501,7 +503,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
NET_EPOCH_EXIT(et);
|
||||
|
||||
if (ia != NULL)
|
||||
(void )in_difaddr_ioctl(cmd, data, ifp, td);
|
||||
(void )in_difaddr_ioctl(cmd, data, ifp, cred);
|
||||
|
||||
ifa = ifa_alloc(sizeof(struct in_ifaddr), M_WAITOK);
|
||||
ia = (struct in_ifaddr *)ifa;
|
||||
@ -654,7 +656,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
}
|
||||
|
||||
static int
|
||||
in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct ucred *cred)
|
||||
{
|
||||
const struct ifreq *ifr = (struct ifreq *)data;
|
||||
const struct sockaddr_in *addr = (const struct sockaddr_in *)
|
||||
@ -664,8 +666,8 @@ in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
bool deleteAny, iaIsLast;
|
||||
int error;
|
||||
|
||||
if (td != NULL) {
|
||||
error = priv_check(td, PRIV_NET_DELIFADDR);
|
||||
if (cred != NULL) {
|
||||
error = priv_check_cred(cred, PRIV_NET_DELIFADDR);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
@ -686,12 +688,12 @@ in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
continue;
|
||||
|
||||
it = (struct in_ifaddr *)ifa;
|
||||
if (deleteAny && ia == NULL && (td == NULL ||
|
||||
prison_check_ip4(td->td_ucred, &it->ia_addr.sin_addr) == 0))
|
||||
if (deleteAny && ia == NULL && (cred == NULL ||
|
||||
prison_check_ip4(cred, &it->ia_addr.sin_addr) == 0))
|
||||
ia = it;
|
||||
|
||||
if (it->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
|
||||
(td == NULL || prison_check_ip4(td->td_ucred,
|
||||
(cred == NULL || prison_check_ip4(cred,
|
||||
&addr->sin_addr) == 0))
|
||||
ia = it;
|
||||
|
||||
@ -757,7 +759,7 @@ in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
}
|
||||
|
||||
static int
|
||||
in_gifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
in_gifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct ucred *cred)
|
||||
{
|
||||
struct in_aliasreq *ifra = (struct in_aliasreq *)data;
|
||||
const struct sockaddr_in *addr = &ifra->ifra_addr;
|
||||
@ -785,7 +787,7 @@ in_gifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
|
||||
|
||||
it = (struct in_ifaddr *)ifa;
|
||||
if (it->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
|
||||
prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0) {
|
||||
prison_check_ip4(cred, &addr->sin_addr) == 0) {
|
||||
ia = it;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user