The branch stable/13 has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=77afa3132ee96872ad2c715d81699bf1635c52ba

commit 77afa3132ee96872ad2c715d81699bf1635c52ba
Author:     Alexander V. Chernikov <[email protected]>
AuthorDate: 2022-09-26 12:07:18 +0000
Commit:     Alexander V. Chernikov <[email protected]>
CommitDate: 2023-01-13 21:24:12 +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
    
    (cherry picked from commit f375bf0e6f0bc6bce3e5b3c6adabc465be2665d0)
---
 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 9fa9ab289fd3..15779d6e61a7 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -75,9 +75,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 *);
@@ -280,6 +280,8 @@ in_control(struct socket *so, u_long cmd, caddr_t 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().
@@ -292,18 +294,18 @@ in_control(struct socket *so, u_long cmd, caddr_t 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:
@@ -319,7 +321,7 @@ in_control(struct socket *so, u_long cmd, caddr_t 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);
 
        /*
@@ -339,7 +341,7 @@ in_control(struct socket *so, u_long cmd, caddr_t 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;
                        }
@@ -382,7 +384,7 @@ in_control(struct socket *so, u_long cmd, caddr_t 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;
@@ -396,7 +398,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);
 
@@ -436,7 +438,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;
@@ -444,7 +446,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;
@@ -598,7 +600,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 *)
@@ -608,8 +610,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);
        }
@@ -630,12 +632,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;
 
@@ -702,7 +704,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;
@@ -730,7 +732,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;
                }

Reply via email to