diff --git a/sys/netinet/in.c b/sys/netinet/in.c --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -325,8 +325,8 @@ * Generic internet control operations (ioctl's). */ int -in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp, - struct thread *td) +in_control_ioctl(u_long cmd, void *data, struct ifnet *ifp, + struct ucred *cred) { struct ifreq *ifr = (struct ifreq *)data; struct sockaddr_in *addr = (struct sockaddr_in *)&ifr->ifr_addr; @@ -338,8 +338,6 @@ 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(). @@ -441,6 +439,13 @@ return (error); } +int +in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp, + struct thread *td) +{ + return (in_control_ioctl(cmd, data, ifp, td ? td->td_ucred : NULL)); +} + static int in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct ucred *cred) { diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -437,6 +437,7 @@ struct rib_head; struct ip_moptions; +struct ucred; struct in_multi *inm_lookup_locked(struct ifnet *, const struct in_addr); struct in_multi *inm_lookup(struct ifnet *, const struct in_addr); @@ -458,6 +459,8 @@ /*const*/ struct in_mfilter *); int in_control(struct socket *, u_long, void *, struct ifnet *, struct thread *); +int in_control_ioctl(u_long, void *, struct ifnet *, + struct ucred *); int in_addprefix(struct in_ifaddr *); int in_scrubprefix(struct in_ifaddr *, u_int); void in_ifscrub_all(void); diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -249,8 +249,8 @@ #endif int -in6_control(struct socket *so, u_long cmd, void *data, - struct ifnet *ifp, struct thread *td) +in6_control_ioctl(u_long cmd, void *data, + struct ifnet *ifp, struct ucred *cred) { struct in6_ifreq *ifr = (struct in6_ifreq *)data; struct in6_ifaddr *ia = NULL; @@ -281,8 +281,8 @@ switch (cmd) { case SIOCAADDRCTL_POLICY: case SIOCDADDRCTL_POLICY: - if (td != NULL) { - error = priv_check(td, PRIV_NETINET_ADDRCTRL6); + if (cred != NULL) { + error = priv_check_cred(cred, PRIV_NETINET_ADDRCTRL6); if (error) return (error); } @@ -299,8 +299,8 @@ case SIOCSDEFIFACE_IN6: case SIOCSIFINFO_FLAGS: case SIOCSIFINFO_IN6: - if (td != NULL) { - error = priv_check(td, PRIV_NETINET_ND6); + if (cred != NULL) { + error = priv_check_cred(cred, PRIV_NETINET_ND6); if (error) return (error); } @@ -343,8 +343,8 @@ switch (cmd) { case SIOCSSCOPE6: - if (td != NULL) { - error = priv_check(td, PRIV_NETINET_SCOPE6); + if (cred != NULL) { + error = priv_check_cred(cred, PRIV_NETINET_SCOPE6); if (error) return (error); } @@ -412,7 +412,7 @@ error = in6_setscope(&sa6->sin6_addr, ifp, NULL); if (error != 0) return (error); - if (td != NULL && (error = prison_check_ip6(td->td_ucred, + if (cred != NULL && (error = prison_check_ip6(cred, &sa6->sin6_addr)) != 0) return (error); sx_xlock(&in6_control_sx); @@ -457,8 +457,8 @@ goto out; } - if (td != NULL) { - error = priv_check(td, (cmd == SIOCDIFADDR_IN6) ? + if (cred != NULL) { + error = priv_check_cred(cred, (cmd == SIOCDIFADDR_IN6) ? PRIV_NET_DELIFADDR : PRIV_NET_ADDIFADDR); if (error) goto out; @@ -596,6 +596,13 @@ return (error); } +int +in6_control(struct socket *so, u_long cmd, void *data, + struct ifnet *ifp, struct thread *td) +{ + return (in6_control_ioctl(cmd, data, ifp, td ? td->td_ucred : NULL)); +} + static struct in6_multi_mship * in6_joingroup_legacy(struct ifnet *ifp, const struct in6_addr *mcaddr, int *errorp, int delay) diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -838,6 +838,7 @@ struct sockopt; struct inpcbinfo; struct rib_head; +struct ucred; /* Multicast KPIs. */ int im6o_mc_filter(const struct ip6_moptions *, const struct ifnet *, @@ -862,6 +863,7 @@ int in6_mask2len(struct in6_addr *, u_char *); int in6_control(struct socket *, u_long, void *, struct ifnet *, struct thread *); +int in6_control_ioctl(u_long, void *, struct ifnet *, struct ucred *); int in6_update_ifa(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int); void in6_prepare_ifra(struct in6_aliasreq *, const struct in6_addr *, diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -1185,7 +1185,7 @@ if (dst != NULL) req.ifra_dstaddr = *dst; - return (in_control(NULL, SIOCAIFADDR, &req, ifp, curthread)); + return (in_control_ioctl(SIOCAIFADDR, &req, ifp, nlp_get_cred(nlp))); } static int @@ -1204,7 +1204,7 @@ struct in_aliasreq req = { .ifra_addr = *addr }; - return (in_control(NULL, SIOCDIFADDR, &req, ifp, curthread)); + return (in_control_ioctl(SIOCDIFADDR, &req, ifp, nlp_get_cred(nlp))); } #endif @@ -1269,7 +1269,7 @@ if (dst != NULL) req.ifra_dstaddr = *dst; - return (in6_control(NULL, SIOCAIFADDR_IN6, &req, ifp, curthread)); + return (in6_control_ioctl(SIOCAIFADDR_IN6, &req, ifp, nlp_get_cred(nlp))); } static int @@ -1288,7 +1288,7 @@ struct in6_aliasreq req = { .ifra_addr = *addr }; - return (in6_control(NULL, SIOCDIFADDR_IN6, &req, ifp, curthread)); + return (in6_control_ioctl(SIOCDIFADDR_IN6, &req, ifp, nlp_get_cred(nlp))); } #endif