Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145319235
D28117.id82156.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D28117.id82156.diff
View Options
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c
--- a/sys/i386/linux/imgact_linux.c
+++ b/sys/i386/linux/imgact_linux.c
@@ -158,7 +158,8 @@
* remove write enable on the 'text' part
*/
error = vm_map_protect(&vmspace->vm_map, vmaddr,
- vmaddr + a_out->a_text, VM_PROT_EXECUTE|VM_PROT_READ, TRUE);
+ vmaddr + a_out->a_text, 0, VM_PROT_EXECUTE | VM_PROT_READ,
+ VM_MAP_PROTECT_SET_MAXPROT);
if (error)
goto fail;
} else {
@@ -185,7 +186,8 @@
* allow read/write of data
*/
error = vm_map_protect(&vmspace->vm_map, vmaddr + a_out->a_text,
- vmaddr + a_out->a_text + a_out->a_data, VM_PROT_ALL, FALSE);
+ vmaddr + a_out->a_text + a_out->a_data, VM_PROT_ALL, 0,
+ VM_MAP_PROTECT_SET_PROT);
if (error)
goto fail;
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -692,7 +692,7 @@
*/
if ((prot & VM_PROT_WRITE) == 0)
vm_map_protect(map, trunc_page(map_addr), round_page(map_addr +
- map_len), prot, FALSE);
+ map_len), prot, 0, VM_MAP_PROTECT_SET_PROT);
return (0);
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -770,7 +770,8 @@
addr = trunc_page(addr);
size = round_page(size);
(void)vm_map_protect(&p->p_vmspace->vm_map,
- addr, addr + size, prot, FALSE);
+ addr, addr + size, prot, 0,
+ VM_MAP_PROTECT_SET_PROT);
}
}
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -1224,7 +1224,7 @@
error = vm_map_protect(kernel_map,
(vm_offset_t)segbase,
(vm_offset_t)segbase + round_page(segs[i]->p_memsz),
- prot, FALSE);
+ prot, 0, VM_MAP_PROTECT_SET_PROT);
if (error != KERN_SUCCESS) {
error = ENOMEM;
goto out;
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -219,7 +219,8 @@
#endif
return;
}
- error = vm_map_protect(kernel_map, start, end, prot, FALSE);
+ error = vm_map_protect(kernel_map, start, end, prot, 0,
+ VM_MAP_PROTECT_SET_PROT);
KASSERT(error == KERN_SUCCESS,
("link_elf_protect_range: vm_map_protect() returned %d", error));
}
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -510,7 +510,12 @@
for ((it) = vm_map_entry_first(map); \
(it) != &(map)->header; \
(it) = vm_map_entry_succ(it))
-int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
+
+#define VM_MAP_PROTECT_SET_PROT 0x0001
+#define VM_MAP_PROTECT_SET_MAXPROT 0x0002
+
+int vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
+ vm_prot_t new_prot, vm_prot_t new_maxprot, int flags);
int vm_map_remove (vm_map_t, vm_offset_t, vm_offset_t);
void vm_map_try_merge_entries(vm_map_t map, vm_map_entry_t prev,
vm_map_entry_t entry);
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2733,14 +2733,12 @@
/*
* vm_map_protect:
*
- * Sets the protection of the specified address
- * region in the target map. If "set_max" is
- * specified, the maximum protection is to be set;
- * otherwise, only the current protection is affected.
+ * Sets the protection and/or the maximum protection of the
+ * specified address region in the target map.
*/
int
vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end,
- vm_prot_t new_prot, boolean_t set_max)
+ vm_prot_t new_prot, vm_prot_t new_maxprot, int flags)
{
vm_map_entry_t entry, first_entry, in_tran, prev_entry;
vm_object_t obj;
@@ -2751,12 +2749,18 @@
if (start == end)
return (KERN_SUCCESS);
+ if ((flags & (VM_MAP_PROTECT_SET_PROT | VM_MAP_PROTECT_SET_MAXPROT)) ==
+ (VM_MAP_PROTECT_SET_PROT | VM_MAP_PROTECT_SET_MAXPROT) &&
+ (new_prot & new_maxprot) != new_prot)
+ return (KERN_INVALID_ARGUMENT);
+
again:
in_tran = NULL;
vm_map_lock(map);
- if ((map->flags & MAP_WXORX) != 0 && (new_prot &
- (VM_PROT_WRITE | VM_PROT_EXECUTE)) == (VM_PROT_WRITE |
+ if ((map->flags & MAP_WXORX) != 0 &&
+ (flags & VM_MAP_PROTECT_SET_PROT) != 0 &&
+ (new_prot & (VM_PROT_WRITE | VM_PROT_EXECUTE)) == (VM_PROT_WRITE |
VM_PROT_EXECUTE)) {
vm_map_unlock(map);
return (KERN_PROTECTION_FAILURE);
@@ -2786,7 +2790,12 @@
vm_map_unlock(map);
return (KERN_INVALID_ARGUMENT);
}
- if ((new_prot & entry->max_protection) != new_prot) {
+ if ((flags & VM_MAP_PROTECT_SET_PROT) == 0)
+ new_prot = entry->protection;
+ if ((flags & VM_MAP_PROTECT_SET_MAXPROT) == 0)
+ new_maxprot = entry->max_protection;
+ if ((new_prot & entry->max_protection) != new_prot ||
+ (new_maxprot & entry->max_protection) != new_maxprot) {
vm_map_unlock(map);
return (KERN_PROTECTION_FAILURE);
}
@@ -2827,12 +2836,16 @@
return (rv);
}
- if (set_max ||
+ if ((flags & VM_MAP_PROTECT_SET_PROT) == 0)
+ new_prot = entry->protection;
+ if ((flags & VM_MAP_PROTECT_SET_MAXPROT) == 0)
+ new_maxprot = entry->max_protection;
+
+ if ((flags & VM_MAP_PROTECT_SET_PROT) == 0 ||
((new_prot & ~entry->protection) & VM_PROT_WRITE) == 0 ||
ENTRY_CHARGED(entry) ||
- (entry->eflags & MAP_ENTRY_GUARD) != 0) {
+ (entry->eflags & MAP_ENTRY_GUARD) != 0)
continue;
- }
cred = curthread->td_ucred;
obj = entry->object.vm_object;
@@ -2893,11 +2906,11 @@
old_prot = entry->protection;
- if (set_max)
- entry->protection =
- (entry->max_protection = new_prot) &
- old_prot;
- else
+ if ((flags & VM_MAP_PROTECT_SET_MAXPROT) != 0) {
+ entry->max_protection = new_maxprot;
+ entry->protection = new_maxprot & old_prot;
+ }
+ if ((flags & VM_MAP_PROTECT_SET_PROT) != 0)
entry->protection = new_prot;
/*
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -653,6 +653,7 @@
vm_offset_t addr;
vm_size_t pageoff;
int vm_error, max_prot;
+ int flags;
addr = addr0;
if ((prot & ~(_PROT_ALL | PROT_MAX(_PROT_ALL))) != 0)
@@ -672,16 +673,11 @@
if (addr + size < addr)
return (EINVAL);
- vm_error = KERN_SUCCESS;
- if (max_prot != 0) {
- if ((max_prot & prot) != prot)
- return (ENOTSUP);
- vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map,
- addr, addr + size, max_prot, TRUE);
- }
- if (vm_error == KERN_SUCCESS)
- vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map,
- addr, addr + size, prot, FALSE);
+ flags = VM_MAP_PROTECT_SET_PROT;
+ if (max_prot != 0)
+ flags |= VM_MAP_PROTECT_SET_MAXPROT;
+ vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map,
+ addr, addr + size, prot, max_prot, flags);
switch (vm_error) {
case KERN_SUCCESS:
@@ -690,6 +686,8 @@
return (EACCES);
case KERN_RESOURCE_SHORTAGE:
return (ENOMEM);
+ case KERN_INVALID_ARGUMENT:
+ return (ENOTSUP);
}
return (EINVAL);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 19, 8:53 AM (5 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28874580
Default Alt Text
D28117.id82156.diff (6 KB)
Attached To
Mode
D28117: vm_map_protect: allow to set prot and max_prot in one go.
Attached
Detach File
Event Timeline
Log In to Comment