summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2006-06-21 12:59:05 +0000
committerkib <kib@FreeBSD.org>2006-06-21 12:59:05 +0000
commitb90260e7035c8f2d90612cf58c33ab8d1844306b (patch)
tree3d462d902d64bc4d67fcf4e3e81e7830d113826d
parent642780c004cfff4e1209e56ef408282322ff3904 (diff)
downloadFreeBSD-src-b90260e7035c8f2d90612cf58c33ab8d1844306b.zip
FreeBSD-src-b90260e7035c8f2d90612cf58c33ab8d1844306b.tar.gz
Make the mincore(2) return ENOMEM when requested range is not fully mapped.
Requested by: Bruno Haible <bruno at clisp org> Reviewed by: alc Approved by: pjd (mentor) MFC after: 1 month
-rw-r--r--lib/libc/sys/mincore.24
-rw-r--r--sys/vm/vm_mmap.c18
2 files changed, 17 insertions, 5 deletions
diff --git a/lib/libc/sys/mincore.2 b/lib/libc/sys/mincore.2
index 25ad076..75e74a4 100644
--- a/lib/libc/sys/mincore.2
+++ b/lib/libc/sys/mincore.2
@@ -92,12 +92,12 @@ The
.Fn mincore
system call will fail if:
.Bl -tag -width Er
-.It Bq Er EINVAL
+.It Bq Er ENOMEM
The virtual address range specified by the
.Fa addr
and
.Fa len
-arguments is not valid.
+arguments is not fully mapped.
.It Bq Er EFAULT
The
.Fa vec
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 5965d4a..244877e 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -757,7 +757,7 @@ mincore(td, uap)
end = addr + (vm_size_t)round_page(uap->len);
map = &td->td_proc->p_vmspace->vm_map;
if (end > vm_map_max(map) || end < addr)
- return (EINVAL);
+ return (ENOMEM);
/*
* Address of byte vector
@@ -770,8 +770,10 @@ mincore(td, uap)
RestartScan:
timestamp = map->timestamp;
- if (!vm_map_lookup_entry(map, addr, &entry))
- entry = entry->next;
+ if (!vm_map_lookup_entry(map, addr, &entry)) {
+ vm_map_unlock_read(map);
+ return (ENOMEM);
+ }
/*
* Do this on a map entry basis so that if the pages are not
@@ -784,6 +786,16 @@ RestartScan:
current = current->next) {
/*
+ * check for contiguity
+ */
+ if (current->end < end &&
+ (entry->next == &map->header ||
+ current->next->start > current->end)) {
+ vm_map_unlock_read(map);
+ return (ENOMEM);
+ }
+
+ /*
* ignore submaps (for now) or null objects
*/
if ((current->eflags & MAP_ENTRY_IS_SUB_MAP) ||
OpenPOWER on IntegriCloud