svn commit: r351150 - stable/12/sys/vm
Doug Moore
dougm at FreeBSD.org
Fri Aug 16 21:54:13 UTC 2019
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
More information about the svn-src-stable-12
mailing list