-/* $OpenBSD: uvm_map.c,v 1.323 2024/01/21 00:26:14 deraadt Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.324 2024/01/21 16:57:06 deraadt Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
uvm_map_inherit(struct vm_map *map, vaddr_t start, vaddr_t end,
vm_inherit_t new_inheritance)
{
- struct vm_map_entry *entry;
+ struct vm_map_entry *entry, *entry1;
+ int error = EPERM;
switch (new_inheritance) {
case MAP_INHERIT_NONE:
else
entry = RBT_NEXT(uvm_map_addr, entry);
+ /* First check for illegal operations */
+ entry1 = entry;
+ while (entry1 != NULL && entry1->start < end) {
+ if (entry1->etype & UVM_ET_IMMUTABLE)
+ goto out;
+ entry1 = RBT_NEXT(uvm_map_addr, entry1);
+ }
+
while (entry != NULL && entry->start < end) {
UVM_MAP_CLIP_END(map, entry, end);
entry->inheritance = new_inheritance;
entry = RBT_NEXT(uvm_map_addr, entry);
}
+ error = 0;
+out:
vm_map_unlock(map);
- return (0);
+ return (error);
}
#ifdef PMAP_CHECK_COPYIN
int
uvm_map_immutable(struct vm_map *map, vaddr_t start, vaddr_t end, int imut)
{
- struct vm_map_entry *entry;
+ struct vm_map_entry *entry, *entry1;
+ int error = EPERM;
if (start > end)
return EINVAL;
else
entry = RBT_NEXT(uvm_map_addr, entry);
+ /* First check for illegal operations */
+ entry1 = entry;
+ while (entry1 != NULL && entry1->start < end) {
+ if (entry1->inheritance == MAP_INHERIT_ZERO)
+ goto out;
+ entry1 = RBT_NEXT(uvm_map_addr, entry1);
+ }
+
while (entry != NULL && entry->start < end) {
UVM_MAP_CLIP_END(map, entry, end);
if (imut)
}
map->wserial++;
+ error = 0;
+out:
vm_map_unlock(map);
return (0);
}
vm_map_lock(map);
first = uvm_map_entrybyaddr(&map->addr, start);
- /* Make a first pass to check for holes. */
+ /* Make a first pass to check for various conditions. */
for (entry = first; entry != NULL && entry->start < end;
entry = RBT_NEXT(uvm_map_addr, entry)) {
+ if (entry->etype & UVM_ET_IMMUTABLE) {
+ vm_map_unlock(map);
+ return EPERM;
+ }
if (UVM_ET_ISSUBMAP(entry)) {
vm_map_unlock(map);
return EINVAL;