anyone?

On 2021-11-18 09:02 +01, Florian Obser <flor...@openbsd.org> wrote:
> This is split in two for easier review and I also intend to commit it
> like this.
>
> The first diff shuffles setting of if_index around so that it's
> available in all switch cases and uses it consistently instead of
> ifm->ifm_index.
>
> That way we can copy the if_name == NULL check into each case block
> preventing crashes when an interface disappears at just the wrong
> moment.
>
> OK?
>
> (btw. I found this because I transmogrified slaacd into gelatod and kn@
> reported a crash while running in debug mode so I could spot what's
> wrong with it. Much harder to find in slaacd...)
>
> commit 2880598cb424e5d889ecdbf06d9d72d777b11569
> Author: Florian Obser <flor...@narrans.de>
> Date:   Wed Nov 17 20:13:55 2021 +0100
>
>     normalize if_index handling in route messages
>
> diff --git frontend.c frontend.c
> index 72d7929c5df..29446c11e16 100644
> --- frontend.c
> +++ frontend.c
> @@ -793,30 +793,28 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>       switch (rtm->rtm_type) {
>       case RTM_IFINFO:
>               ifm = (struct if_msghdr *)rtm;
> -             if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
> +             if_index = ifm->ifm_index;
> +             if_name = if_indextoname(if_index, ifnamebuf);
>               if (if_name == NULL) {
> -                     log_debug("RTM_IFINFO: lost if %d", ifm->ifm_index);
> -                     if_index = ifm->ifm_index;
> +                     log_debug("RTM_IFINFO: lost if %d", if_index);
>                       frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
>                           &if_index, sizeof(if_index));
>                       remove_iface(if_index);
> +                     break;
> +             }
> +             xflags = get_xflags(if_name);
> +             if (xflags == -1 || !(xflags & (IFXF_AUTOCONF6 |
> +                 IFXF_AUTOCONF6TEMP))) {
> +                     log_debug("RTM_IFINFO: %s(%d) no(longer) autoconf6", 
> if_name,
> +                         if_index);
> +                     frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0,
> +                         0, &if_index, sizeof(if_index));
> +                     remove_iface(if_index);
>               } else {
> -                     xflags = get_xflags(if_name);
> -                     if (xflags == -1 || !(xflags & (IFXF_AUTOCONF6 |
> -                         IFXF_AUTOCONF6TEMP))) {
> -                             log_debug("RTM_IFINFO: %s(%d) no(longer) "
> -                                "autoconf6", if_name, ifm->ifm_index);
> -                             if_index = ifm->ifm_index;
> -                             frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0,
> -                                 0, &if_index, sizeof(if_index));
> -                             remove_iface(if_index);
> -                     } else {
> -                             update_iface(ifm->ifm_index, if_name);
> +                     update_iface(if_index, if_name);
>  #ifndef      SMALL
> -                             update_autoconf_addresses(ifm->ifm_index,
> -                                 if_name);
> +                     update_autoconf_addresses(if_index, if_name);
>  #endif       /* SMALL */
> -                     }
>               }
>               break;
>       case RTM_IFANNOUNCE:
> @@ -830,27 +828,29 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>               break;
>       case RTM_NEWADDR:
>               ifm = (struct if_msghdr *)rtm;
> -             if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
> -             log_debug("RTM_NEWADDR: %s[%u]", if_name, ifm->ifm_index);
> -             update_iface(ifm->ifm_index, if_name);
> +             if_index = ifm->ifm_index;
> +             if_name = if_indextoname(if_index, ifnamebuf);
> +             log_debug("RTM_NEWADDR: %s[%u]", if_name, if_index);
> +             update_iface(if_index, if_name);
>               break;
>       case RTM_DELADDR:
>               ifm = (struct if_msghdr *)rtm;
> -             if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
> +             if_index = ifm->ifm_index;
> +             if_name = if_indextoname(if_index, ifnamebuf);
>               if (rtm->rtm_addrs & RTA_IFA && rti_info[RTAX_IFA]->sa_family
>                   == AF_INET6) {
> -                     del_addr.if_index = ifm->ifm_index;
> +                     del_addr.if_index = if_index;
>                       memcpy(&del_addr.addr, rti_info[RTAX_IFA], sizeof(
>                           del_addr.addr));
>                       frontend_imsg_compose_engine(IMSG_DEL_ADDRESS,
>                                   0, 0, &del_addr, sizeof(del_addr));
> -                     log_debug("RTM_DELADDR: %s[%u]", if_name,
> -                         ifm->ifm_index);
> +                     log_debug("RTM_DELADDR: %s[%u]", if_name, if_index);
>               }
>               break;
>       case RTM_CHGADDRATTR:
>               ifm = (struct if_msghdr *)rtm;
> -             if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
> +             if_index = ifm->ifm_index;
> +             if_name = if_indextoname(if_index, ifnamebuf);
>               if (rtm->rtm_addrs & RTA_IFA && rti_info[RTAX_IFA]->sa_family
>                   == AF_INET6) {
>                       sin6 = (struct sockaddr_in6 *) rti_info[RTAX_IFA];
> @@ -869,13 +869,13 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>                       }
>  
>  #ifndef      SMALL
> -                     log_debug("RTM_CHGADDRATTR: %s -%s",
> +                     log_debug("RTM_CHGADDRATTR: %s - %s",
>                           sin6_to_str(sin6),
>                           flags_to_str(ifr6.ifr_ifru.ifru_flags6));
>  #endif       /* SMALL */
>  
>                       if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED) {
> -                             dup_addr.if_index = ifm->ifm_index;
> +                             dup_addr.if_index = if_index;
>                               dup_addr.addr = *sin6;
>                               frontend_imsg_compose_engine(IMSG_DUP_ADDRESS,
>                                   0, 0, &dup_addr, sizeof(dup_addr));
> @@ -902,10 +902,10 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>               rl = (struct sockaddr_rtlabel *)rti_info[RTAX_LABEL];
>               if (strcmp(rl->sr_label, SLAACD_RTA_LABEL) != 0)
>                       break;
> +             if_index = ifm->ifm_index;
> +             if_name = if_indextoname(if_index, ifnamebuf);
>  
> -             if_name = if_indextoname(ifm->ifm_index, ifnamebuf);
> -
> -             del_route.if_index = ifm->ifm_index;
> +             del_route.if_index = if_index;
>               memcpy(&del_route.gw, rti_info[RTAX_GATEWAY],
>                   sizeof(del_route.gw));
>               in6 = &del_route.gw.sin6_addr;
>
> commit e8882f2329db1789914358c1c6b56ddec74fc35f
> Author: Florian Obser <flor...@narrans.de>
> Date:   Wed Nov 17 20:17:29 2021 +0100
>
>     Make sure the interface still exists before updating it.
>     
>     When we get a route message, for example an address being added
>     (RTM_NEWADDR, but the problem exists with most of the route messages)
>     and the interface gets unplugged at just the right moment
>     if_nametoindex(3) will return NULL. We will pass NULL through
>     update_iface() to get_xflags() which will then crash because we
>     dereference the NULL pointer there.
>     
>     This might be the crash kn@ was seeing once in a blue moon.
>
> diff --git frontend.c frontend.c
> index 29446c11e16..329f93c39ae 100644
> --- frontend.c
> +++ frontend.c
> @@ -830,6 +830,14 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>               ifm = (struct if_msghdr *)rtm;
>               if_index = ifm->ifm_index;
>               if_name = if_indextoname(if_index, ifnamebuf);
> +             if (if_name == NULL) {
> +                     log_debug("RTM_NEWADDR: lost if %d", if_index);
> +                     frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
> +                         &if_index, sizeof(if_index));
> +                     remove_iface(if_index);
> +                     break;
> +             }
> +
>               log_debug("RTM_NEWADDR: %s[%u]", if_name, if_index);
>               update_iface(if_index, if_name);
>               break;
> @@ -837,6 +845,13 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>               ifm = (struct if_msghdr *)rtm;
>               if_index = ifm->ifm_index;
>               if_name = if_indextoname(if_index, ifnamebuf);
> +             if (if_name == NULL) {
> +                     log_debug("RTM_DELADDR: lost if %d", if_index);
> +                     frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
> +                         &if_index, sizeof(if_index));
> +                     remove_iface(if_index);
> +                     break;
> +             }
>               if (rtm->rtm_addrs & RTA_IFA && rti_info[RTAX_IFA]->sa_family
>                   == AF_INET6) {
>                       del_addr.if_index = if_index;
> @@ -851,6 +866,13 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>               ifm = (struct if_msghdr *)rtm;
>               if_index = ifm->ifm_index;
>               if_name = if_indextoname(if_index, ifnamebuf);
> +             if (if_name == NULL) {
> +                     log_debug("RTM_CHGADDRATTR: lost if %d", if_index);
> +                     frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
> +                         &if_index, sizeof(if_index));
> +                     remove_iface(if_index);
> +                     break;
> +             }
>               if (rtm->rtm_addrs & RTA_IFA && rti_info[RTAX_IFA]->sa_family
>                   == AF_INET6) {
>                       sin6 = (struct sockaddr_in6 *) rti_info[RTAX_IFA];
> @@ -904,6 +926,13 @@ handle_route_message(struct rt_msghdr *rtm, struct 
> sockaddr **rti_info)
>                       break;
>               if_index = ifm->ifm_index;
>               if_name = if_indextoname(if_index, ifnamebuf);
> +             if (if_name == NULL) {
> +                     log_debug("RTM_DELETE: lost if %d", if_index);
> +                     frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0,
> +                         &if_index, sizeof(if_index));
> +                     remove_iface(if_index);
> +                     break;
> +             }
>  
>               del_route.if_index = if_index;
>               memcpy(&del_route.gw, rti_info[RTAX_GATEWAY],
>
> -- 
>
> I'm not entirely sure you are real.
>

-- 
I'm not entirely sure you are real.

Reply via email to