Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys/net Pull up following revision(s) (requested by ozaki...



details:   https://anonhg.NetBSD.org/src/rev/0476eaa050c1
branches:  netbsd-8
changeset: 434520:0476eaa050c1
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jan 02 10:30:10 2018 +0000

description:
Pull up following revision(s) (requested by ozaki-r in ticket #457):
        sys/net/rtsock.c: revision 1.233-1.234, 1.236
Protect ifp returned from route_output_get_ifa surely
An ifp returned from route_output_get_ifa was supposed to be protected
by a returned ifa; if the ifa belongs to ifp, holding the ifa prevents
the ifp from being freed. However route_output_get_ifa can return an ifp
to which a returned ifa doesn't belong. So we need to take a reference
to a returning ifp separately.
--
Fix a bug that tries to psref_acquire ifa with a psref used before
This fixes ATF tests that started to fail by a recent change to psref.
--
Fix compile error (may be used uninitialized)
Hmm, __noinline had hidden this error.

diffstat:

 sys/net/rtsock.c |  25 ++++++++++++++++++-------
 1 files changed, 18 insertions(+), 7 deletions(-)

diffs (93 lines):

diff -r efbd00b00964 -r 0476eaa050c1 sys/net/rtsock.c
--- a/sys/net/rtsock.c  Tue Jan 02 10:20:32 2018 +0000
+++ b/sys/net/rtsock.c  Tue Jan 02 10:30:10 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtsock.c,v 1.213.2.4 2018/01/02 10:20:33 snj Exp $     */
+/*     $NetBSD: rtsock.c,v 1.213.2.5 2018/01/02 10:30:10 snj Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.213.2.4 2018/01/02 10:20:33 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.213.2.5 2018/01/02 10:30:10 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -608,7 +608,7 @@
 
 static struct ifaddr *
 route_output_get_ifa(const struct rt_addrinfo info, const struct rtentry *rt,
-    struct ifnet **ifp, struct psref *psref)
+    struct ifnet **ifp, struct psref *psref_ifp, struct psref *psref)
 {
        struct ifaddr *ifa = NULL;
 
@@ -618,9 +618,11 @@
                if (ifa == NULL)
                        goto next;
                *ifp = ifa->ifa_ifp;
+               if_acquire(*ifp, psref_ifp);
                if (info.rti_info[RTAX_IFA] == NULL &&
                    info.rti_info[RTAX_GATEWAY] == NULL)
                        goto next;
+               ifa_release(ifa, psref);
                if (info.rti_info[RTAX_IFA] == NULL) {
                        /* route change <dst> <gw> -ifp <if> */
                        ifa = ifaof_ifpforaddr_psref(info.rti_info[RTAX_GATEWAY],
@@ -648,8 +650,14 @@
                    info.rti_info[RTAX_GATEWAY], psref);
        }
 out:
-       if (ifa != NULL && *ifp == NULL)
+       if (ifa != NULL && *ifp == NULL) {
                *ifp = ifa->ifa_ifp;
+               if_acquire(*ifp, psref_ifp);
+       }
+       if (ifa == NULL && *ifp != NULL) {
+               if_put(*ifp, psref_ifp);
+               *ifp = NULL;
+       }
        return ifa;
 }
 
@@ -658,9 +666,9 @@
     struct rt_xmsghdr *rtm)
 {
        int error = 0;
-       struct ifnet *ifp = NULL, *new_ifp;
+       struct ifnet *ifp = NULL, *new_ifp = NULL;
        struct ifaddr *ifa = NULL, *new_ifa;
-       struct psref psref_ifa, psref_new_ifa, psref_ifp;
+       struct psref psref_ifa, psref_new_ifa, psref_ifp, psref_new_ifp;
        bool newgw, ifp_changed = false;
 
        /*
@@ -674,6 +682,7 @@
        if (newgw || info->rti_info[RTAX_IFP] != NULL ||
            info->rti_info[RTAX_IFA] != NULL) {
                ifp = rt_getifp(info, &psref_ifp);
+               /* info refers ifp so we need to keep a reference */
                ifa = rt_getifa(info, &psref_ifa);
                if (ifa == NULL) {
                        error = ENETUNREACH;
@@ -698,7 +707,8 @@
         * flags may also be different; ifp may be specified
         * by ll sockaddr when protocol address is ambiguous
         */
-       new_ifa = route_output_get_ifa(*info, rt, &new_ifp, &psref_new_ifa);
+       new_ifa = route_output_get_ifa(*info, rt, &new_ifp, &psref_new_ifp,
+           &psref_new_ifa);
        if (new_ifa != NULL) {
                ifa_release(ifa, &psref_ifa);
                ifa = new_ifa;
@@ -736,6 +746,7 @@
        (void)ifp_changed; /* XXX gcc */
 #endif
 out:
+       if_put(new_ifp, &psref_new_ifp);
        if_put(ifp, &psref_ifp);
 
        return error;



Home | Main Index | Thread Index | Old Index