git: f375bf0e6f0b - main - netinet: pass cred instead of the curthread to ifaddr manipulation funcs.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 26 Sep 2022 13:46:19 UTC
The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=f375bf0e6f0bc6bce3e5b3c6adabc465be2665d0 commit f375bf0e6f0bc6bce3e5b3c6adabc465be2665d0 Author: Alexander V. Chernikov <melifaro@FreeBSD.org> AuthorDate: 2022-09-26 12:07:18 +0000 Commit: Alexander V. Chernikov <melifaro@FreeBSD.org> CommitDate: 2022-09-26 13:46:13 +0000 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 --- sys/netinet/in.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 790740456160..7f88a897ff44 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -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 @@ fail1: } 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; }