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/19f5e70155eb
branches:  trunk
changeset: 359096:19f5e70155eb
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 70c587871d31 -r 19f5e70155eb 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