On 03/01/16(Sun) 14:19, Fabian Raetz wrote:
> On Sun, Jan 03, 2016 at 11:54:18AM +0100, Martin Pieuchot wrote:
> > On 30/12/15(Wed) 12:51, Fabian Raetz wrote:
> > > Hi tech@,
> > > 
> > > i've found the undocumented -carpdev option in ifconfig(8) which freezes
> > > my sytem if executed.
> > > 
> > > As the -carpdev option is undocumented in both ifconfig(8) and carp(4) i
> > > propose two patches to remove this functionality.
> > > 
> > > The patch below will return EINVAL in SIOCSVH if carpr.carpr_carpdev is 
> > > not a
> > > valid interface name.
> > 
> > Did you try this diff?  The SIOCGVH ioctl(2) is not always issued with
> > carpr_carpdev set, so this will break your system.
> [...] 
> Or are you worried about something completly different and i'm missing
> the point?

I'm worried about the fact that your diff breaks ifconfig(8) with
carp(4) interfaces because, as I said previously, the SIOCGVH ioctl(2)
is not always issued with carpr_carpdev set :)

Here's a different approach that should prevent your NULL dereference
(untested):

Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.284
diff -u -p -r1.284 ip_carp.c
--- netinet/ip_carp.c   19 Dec 2015 11:19:35 -0000      1.284
+++ netinet/ip_carp.c   3 Jan 2016 14:51:20 -0000
@@ -1653,11 +1653,9 @@ carp_set_ifp(struct carp_softc *sc, stru
        int myself = 0, error = 0;
        int s;
 
+       KASSERT(ifp0 != sc->sc_carpdev);
        KERNEL_ASSERT_LOCKED(); /* touching vhif_vrs */
 
-       if (ifp0 == sc->sc_carpdev)
-               return (0);
-
        if ((ifp0->if_flags & IFF_MULTICAST) == 0)
                return (EADDRNOTAVAIL);
 
@@ -1968,12 +1966,12 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
        struct carpreq carpr;
        struct ifaddr *ifa = (struct ifaddr *)addr;
        struct ifreq *ifr = (struct ifreq *)addr;
-       struct ifnet *ifp0 = NULL;
+       struct ifnet *ifp0 = sc->sc_carpdev;
        int i, error = 0;
 
        switch (cmd) {
        case SIOCSIFADDR:
-               if (sc->sc_carpdev == NULL)
+               if (ifp0 == NULL)
                        return (EINVAL);
 
                switch (ifa->ifa_addr->sa_family) {
@@ -2029,8 +2027,10 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
                        sc->sc_peer.s_addr = INADDR_CARP_GROUP;
                else
                        sc->sc_peer.s_addr = carpr.carpr_peer.s_addr;
-               if ((error = carp_set_ifp(sc, ifp0)))
-                       return (error);
+               if (ifp0 != sc->sc_carpdev) {
+                       if ((error = carp_set_ifp(sc, ifp0)))
+                               return (error);
+               }
                if (vhe->state != INIT && carpr.carpr_state != vhe->state) {
                        switch (carpr.carpr_state) {
                        case BACKUP:
@@ -2090,9 +2090,8 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
 
        case SIOCGVH:
                memset(&carpr, 0, sizeof(carpr));
-               if (sc->sc_carpdev != NULL)
-                       strlcpy(carpr.carpr_carpdev, sc->sc_carpdev->if_xname,
-                           IFNAMSIZ);
+               if (ifp0 != NULL)
+                       strlcpy(carpr.carpr_carpdev, ifp0->if_xname, IFNAMSIZ);
                i = 0;
                KERNEL_ASSERT_LOCKED(); /* touching carp_vhosts */
                SRPL_FOREACH_LOCKED(vhe, &sc->carp_vhosts, vhost_entries) {

Reply via email to