Author: markj
Date: Fri Dec 20 16:04:26 2019
New Revision: 355933
URL: https://svnweb.freebsd.org/changeset/base/355933

Log:
  MFC r355864:
  an(4): Require privileges for all SIOCGAIRONET requests.

Modified:
  stable/12/sys/dev/an/if_an.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/an/if_an.c
==============================================================================
--- stable/12/sys/dev/an/if_an.c        Fri Dec 20 15:28:40 2019        
(r355932)
+++ stable/12/sys/dev/an/if_an.c        Fri Dec 20 16:04:26 2019        
(r355933)
@@ -1875,6 +1875,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t da
        int                     len;
        int                     i, max;
        struct an_softc         *sc;
+       struct an_req           *areq;
        struct ifreq            *ifr;
        struct thread           *td = curthread;
        struct ieee80211req     *ireq;
@@ -1934,17 +1935,21 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t da
                error = 0;
                break;
        case SIOCGAIRONET:
-               error = copyin(ifr_data_get_ptr(ifr), &sc->areq,
-                   sizeof(sc->areq));
-               if (error != 0)
+               error = priv_check(td, PRIV_DRIVER);
+               if (error)
                        break;
+               areq = malloc(sizeof(*areq), M_TEMP, M_WAITOK);
+               error = copyin(ifr_data_get_ptr(ifr), areq, sizeof(*areq));
+               if (error != 0) {
+                       free(areq, M_TEMP);
+                       break;
+               }
                AN_LOCK(sc);
+               memcpy(&sc->areq, areq, sizeof(sc->areq));
 #ifdef ANCACHE
                if (sc->areq.an_type == AN_RID_ZERO_CACHE) {
-                       error = priv_check(td, PRIV_DRIVER);
-                       if (error)
-                               break;
                        sc->an_sigitems = sc->an_nextitem = 0;
+                       free(areq, M_TEMP);
                        break;
                } else if (sc->areq.an_type == AN_RID_READ_CACHE) {
                        char *pt = (char *)&sc->areq.an_val;
@@ -1960,12 +1965,14 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t da
 #endif
                if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) {
                        AN_UNLOCK(sc);
+                       free(areq, M_TEMP);
                        error = EINVAL;
                        break;
                }
+               memcpy(areq, &sc->areq, sizeof(*areq));
                AN_UNLOCK(sc);
-               error = copyout(&sc->areq, ifr_data_get_ptr(ifr),
-                   sizeof(sc->areq));
+               error = copyout(areq, ifr_data_get_ptr(ifr), sizeof(*areq));
+               free(areq, M_TEMP);
                break;
        case SIOCSAIRONET:
                if ((error = priv_check(td, PRIV_DRIVER)))
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to