Date: Fri, 16 Aug 2019 21:54:12 +0000 (UTC) From: Doug Moore <dougm@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r351150 - stable/12/sys/vm Message-ID: <201908162154.x7GLsCZE066129@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dougm Date: Fri Aug 16 21:54:12 2019 New Revision: 351150 URL: https://svnweb.freebsd.org/changeset/base/351150 Log: MFC r348968: Avoid overflow in computing gap sizes. Approved by: markj (mentor) Modified: stable/12/sys/vm/vm_map.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/vm/vm_map.c ============================================================================== --- stable/12/sys/vm/vm_map.c Fri Aug 16 21:40:39 2019 (r351149) +++ stable/12/sys/vm/vm_map.c Fri Aug 16 21:54:12 2019 (r351150) @@ -1645,13 +1645,14 @@ vm_map_findspace(vm_map_t map, vm_offset_t start, vm_s { vm_map_entry_t llist, rlist, root, y; vm_size_t left_length; + vm_offset_t gap_end; /* * Request must fit within min/max VM address and must avoid * address wrap. */ start = MAX(start, vm_map_min(map)); - if (start + length > vm_map_max(map) || start + length < start) + if (start >= vm_map_max(map) || length > vm_map_max(map) - start) return (vm_map_max(map) - length + 1); /* Empty tree means wide open address space. */ @@ -1659,13 +1660,19 @@ vm_map_findspace(vm_map_t map, vm_offset_t start, vm_s return (start); /* - * After splay, if start comes before root node, then there - * must be a gap from start to the root. + * After splay_split, if start is within an entry, push it to the start + * of the following gap. If rlist is at the end of the gap containing + * start, save the end of that gap in gap_end to see if the gap is big + * enough; otherwise set gap_end to start skip gap-checking and move + * directly to a search of the right subtree. */ root = vm_map_splay_split(map, start, length, &llist, &rlist); - if (root != NULL) + gap_end = rlist->start; + if (root != NULL) { start = root->end; - else if (rlist != &map->header) { + if (root->right != NULL) + gap_end = start; + } else if (rlist != &map->header) { root = rlist; rlist = root->left; root->left = NULL; @@ -1676,18 +1683,9 @@ vm_map_findspace(vm_map_t map, vm_offset_t start, vm_s } vm_map_splay_merge(map, root, llist, rlist); VM_MAP_ASSERT_CONSISTENT(map); - if (start + length <= root->start) + if (length <= gap_end - start) return (start); - /* - * Root is the last node that might begin its gap before - * start, and this is the last comparison where address - * wrap might be a problem. - */ - if (root->right == NULL && - start + length <= vm_map_max(map)) - return (start); - /* With max_free, can immediately tell if no solution. */ if (root->right == NULL || length > root->right->max_free) return (vm_map_max(map) - length + 1); @@ -1804,8 +1802,8 @@ vm_map_alignspace(vm_map_t map, vm_object_t object, vm VM_MAP_ASSERT_LOCKED(map); free_addr = *addr; KASSERT(free_addr == vm_map_findspace(map, free_addr, length), - ("caller failed to provide space %d at address %p", - (int)length, (void*)free_addr)); + ("caller failed to provide space %#jx at address %p", + (uintmax_t)length, (void *)free_addr)); for (;;) { /* * At the start of every iteration, the free space at address
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908162154.x7GLsCZE066129>