Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 Use existing fill_[pd]rlist() functions to calc...



details:   https://anonhg.NetBSD.org/src/rev/a52967a2a259
branches:  trunk
changeset: 829397:a52967a2a259
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Mon Jan 29 02:02:14 2018 +0000

description:
Use existing fill_[pd]rlist() functions to calculate size of buffer to
allocate, rather than relying on an arbitrary length passed in from
userland.

Allow copyout() of partial results if the user buffer is too small, to
be consistent with the way sysctl(3) is documented.

Garbage-collect now-unused third parrameter in the fill_[pd]rlist()
functions.

As discussed on IRC.
OK kamil@ and christos@

XXX Needs pull-up to netbsd-8 branch.

diffstat:

 sys/netinet6/nd6.c |  53 +++++++++++++++++++++++++++--------------------------
 1 files changed, 27 insertions(+), 26 deletions(-)

diffs (128 lines):

diff -r 02250055cfc8 -r a52967a2a259 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Sun Jan 28 22:24:58 2018 +0000
+++ b/sys/netinet6/nd6.c        Mon Jan 29 02:02:14 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.240 2017/12/15 04:03:46 ozaki-r Exp $        */
+/*     $NetBSD: nd6.c,v 1.241 2018/01/29 02:02:14 pgoyette Exp $       */
 /*     $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $   */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.240 2017/12/15 04:03:46 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.241 2018/01/29 02:02:14 pgoyette Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -124,8 +124,8 @@
 static struct workqueue        *nd6_timer_wq;
 static struct work     nd6_timer_wk;
 
-static int fill_drlist(void *, size_t *, size_t);
-static int fill_prlist(void *, size_t *, size_t);
+static int fill_drlist(void *, size_t *);
+static int fill_prlist(void *, size_t *);
 
 static struct ifnet *nd6_defifp;
 static int nd6_defifindex;
@@ -2491,6 +2491,7 @@
        size_t ol;
        int error;
        size_t bufsize = 0;
+       int (*fill_func)(void *, size_t *);
 
        error = 0;
 
@@ -2500,22 +2501,17 @@
                return EINVAL;
        ol = oldlenp ? *oldlenp : 0;
 
-       if (oldp && *oldlenp > 0) {
-               p = kmem_alloc(*oldlenp, KM_SLEEP);
-               bufsize = *oldlenp;
-       } else
-               p = NULL;
+       p = NULL;
+
+       fill_func = NULL;
+
        switch (name) {
        case ICMPV6CTL_ND6_DRLIST:
-               error = fill_drlist(p, oldlenp, ol);
-               if (!error && p != NULL && oldp != NULL)
-                       error = copyout(p, oldp, *oldlenp);
+               fill_func = fill_drlist;
                break;
 
        case ICMPV6CTL_ND6_PRLIST:
-               error = fill_prlist(p, oldlenp, ol);
-               if (!error && p != NULL && oldp != NULL)
-                       error = copyout(p, oldp, *oldlenp);
+               fill_func = fill_prlist;
                break;
 
        case ICMPV6CTL_ND6_MAXQLEN:
@@ -2525,6 +2521,19 @@
                error = ENOPROTOOPT;
                break;
        }
+
+       if (fill_func) {
+               error = (*fill_func)(p, oldlenp);       /* calc len needed */
+               if (error == 0 && oldp && *oldlenp > 0 ) {
+                       p = kmem_alloc(*oldlenp, KM_SLEEP);
+                       bufsize = *oldlenp;
+                       error = (*fill_func)(p, oldlenp);
+                       if (!error && oldp != NULL)
+                               error = copyout(p, oldp, min(ol, *oldlenp));
+                       if (*oldlenp > ol)
+                               error = ENOMEM;
+               }
+       }
        if (p)
                kmem_free(p, bufsize);
 
@@ -2532,7 +2541,7 @@
 }
 
 static int
-fill_drlist(void *oldp, size_t *oldlenp, size_t ol)
+fill_drlist(void *oldp, size_t *oldlenp)
 {
        int error = 0;
        struct in6_defrouter *d = NULL, *de = NULL;
@@ -2571,10 +2580,6 @@
        }
        ND6_UNLOCK();
 
-       if (oldp) {
-               if (l > ol)
-                       error = ENOMEM;
-       }
        if (oldlenp)
                *oldlenp = l;   /* (void *)d - (void *)oldp */
 
@@ -2582,7 +2587,7 @@
 }
 
 static int
-fill_prlist(void *oldp, size_t *oldlenp, size_t ol)
+fill_prlist(void *oldp, size_t *oldlenp)
 {
        int error = 0;
        struct nd_prefix *pr;
@@ -2678,11 +2683,7 @@
        }
        ND6_UNLOCK();
 
-       if (oldp) {
-               *oldlenp = l;   /* (void *)d - (void *)oldp */
-               if (l > ol)
-                       error = ENOMEM;
-       } else
+       if (oldlenp)
                *oldlenp = l;
 
        return error;



Home | Main Index | Thread Index | Old Index