Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm PR/52078: Don't panic on 0 allocation, check more bo...



details:   https://anonhg.NetBSD.org/src/rev/b1b58c501d12
branches:  trunk
changeset: 352100:b1b58c501d12
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Mar 15 20:25:41 2017 +0000

description:
PR/52078: Don't panic on 0 allocation, check more bounds.

diffstat:

 sys/uvm/uvm_map.c |  32 ++++++++++++++++++++------------
 1 files changed, 20 insertions(+), 12 deletions(-)

diffs (78 lines):

diff -r 21598ff653c2 -r b1b58c501d12 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Wed Mar 15 16:42:18 2017 +0000
+++ b/sys/uvm/uvm_map.c Wed Mar 15 20:25:41 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_map.c,v 1.342 2016/12/01 02:09:03 mrg Exp $        */
+/*     $NetBSD: uvm_map.c,v 1.343 2017/03/15 20:25:41 christos Exp $   */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.342 2016/12/01 02:09:03 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.343 2017/03/15 20:25:41 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_uvmhist.h"
@@ -4892,15 +4892,25 @@
        char *dp;
        size_t count, vmesize;
 
-       vme = NULL;
-       vmesize = *oldlenp;
-       count = 0;
-       if (oldp && *oldlenp > 1024 * 1024)
-               return E2BIG;
+       if (elem_size == 0 || elem_size > 2 * sizeof(*vme))
+               return EINVAL;
+
+       if (oldp) {
+               if (*oldlenp > 1024 * 1024)
+                       return E2BIG;
+               count = *oldlenp / elem_size;
+               if (count == 0)
+                       return ENOMEM;
+               vmesize = count * sizeof(*vme);
+       } else
+               vmesize = 0;
 
        if ((error = proc_find_locked(l, &p, pid)) != 0)
                return error;
 
+       vme = NULL;
+       count = 0;
+
        if ((error = proc_vmspace_getref(p, &vm)) != 0)
                goto out;
 
@@ -4912,7 +4922,7 @@
                vme = kmem_alloc(vmesize, KM_SLEEP);
        for (entry = map->header.next; entry != &map->header;
            entry = entry->next) {
-               if (oldp && (dp - (char *)oldp) < *oldlenp + elem_size) {
+               if (oldp && (dp - (char *)oldp) < *oldlenp) {
                        error = fill_vmentry(l, p, &vme[count], map, entry);
                        if (error)
                                goto out;
@@ -4930,8 +4940,7 @@
                const u_int esize = min(sizeof(*vme), elem_size);
                dp = oldp;
                for (size_t i = 0; i < count; i++) {
-                       if (oldp && (dp - (char *)oldp) < *oldlenp + elem_size)
-                       {
+                       if (oldp && (dp - (char *)oldp) < *oldlenp) {
                                error = sysctl_copyout(l, &vme[i], dp, esize);
                                if (error)
                                        break;
@@ -4965,8 +4974,7 @@
                if (namelen != 3)
                        return EINVAL;
                sysctl_unlock();
-               error = fill_vmentries(l, name[1], name[2],
-                   oldp, oldlenp);
+               error = fill_vmentries(l, name[1], name[2], oldp, oldlenp);
                sysctl_relock();
                return error;
        default:



Home | Main Index | Thread Index | Old Index