* vm_map_protect: * * Sets the protection and/or the maximum protection of the * specified address region in the target map. */
| 2737 | * specified address region in the target map. |
| 2738 | */ |
| 2739 | int |
| 2740 | vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end, |
| 2741 | vm_prot_t new_prot, vm_prot_t new_maxprot, int flags) |
| 2742 | { |
| 2743 | vm_map_entry_t entry, first_entry, in_tran, prev_entry; |
| 2744 | vm_object_t obj; |
| 2745 | struct ucred *cred; |
| 2746 | vm_prot_t old_prot; |
| 2747 | int rv; |
| 2748 | |
| 2749 | if (start == end) |
| 2750 | return (KERN_SUCCESS); |
| 2751 | |
| 2752 | if ((flags & (VM_MAP_PROTECT_SET_PROT | VM_MAP_PROTECT_SET_MAXPROT)) == |
| 2753 | (VM_MAP_PROTECT_SET_PROT | VM_MAP_PROTECT_SET_MAXPROT) && |
| 2754 | (new_prot & new_maxprot) != new_prot) |
| 2755 | return (KERN_OUT_OF_BOUNDS); |
| 2756 | |
| 2757 | again: |
| 2758 | in_tran = NULL; |
| 2759 | vm_map_lock(map); |
| 2760 | |
| 2761 | if ((map->flags & MAP_WXORX) != 0 && |
| 2762 | (flags & VM_MAP_PROTECT_SET_PROT) != 0 && |
| 2763 | (new_prot & (VM_PROT_WRITE | VM_PROT_EXECUTE)) == (VM_PROT_WRITE | |
| 2764 | VM_PROT_EXECUTE)) { |
| 2765 | vm_map_unlock(map); |
| 2766 | return (KERN_PROTECTION_FAILURE); |
| 2767 | } |
| 2768 | |
| 2769 | /* |
| 2770 | * Ensure that we are not concurrently wiring pages. vm_map_wire() may |
| 2771 | * need to fault pages into the map and will drop the map lock while |
| 2772 | * doing so, and the VM object may end up in an inconsistent state if we |
| 2773 | * update the protection on the map entry in between faults. |
| 2774 | */ |
| 2775 | vm_map_wait_busy(map); |
| 2776 | |
| 2777 | VM_MAP_RANGE_CHECK(map, start, end); |
| 2778 | |
| 2779 | if (!vm_map_lookup_entry(map, start, &first_entry)) |
| 2780 | first_entry = vm_map_entry_succ(first_entry); |
| 2781 | |
| 2782 | /* |
| 2783 | * Make a first pass to check for protection violations. |
| 2784 | */ |
| 2785 | for (entry = first_entry; entry->start < end; |
| 2786 | entry = vm_map_entry_succ(entry)) { |
| 2787 | if ((entry->eflags & MAP_ENTRY_GUARD) != 0) |
| 2788 | continue; |
| 2789 | if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0) { |
| 2790 | vm_map_unlock(map); |
| 2791 | return (KERN_INVALID_ARGUMENT); |
| 2792 | } |
| 2793 | if ((flags & VM_MAP_PROTECT_SET_PROT) == 0) |
| 2794 | new_prot = entry->protection; |
| 2795 | if ((flags & VM_MAP_PROTECT_SET_MAXPROT) == 0) |
| 2796 | new_maxprot = entry->max_protection; |
no test coverage detected