|
@@ -42,58 +42,21 @@ static inline unsigned long mpx_bt_size_bytes(struct mm_struct *mm)
|
|
|
*/
|
|
|
static unsigned long mpx_mmap(unsigned long len)
|
|
|
{
|
|
|
- unsigned long ret;
|
|
|
- unsigned long addr, pgoff;
|
|
|
struct mm_struct *mm = current->mm;
|
|
|
- vm_flags_t vm_flags;
|
|
|
- struct vm_area_struct *vma;
|
|
|
+ unsigned long addr, populate;
|
|
|
|
|
|
/* Only bounds table can be allocated here */
|
|
|
if (len != mpx_bt_size_bytes(mm))
|
|
|
return -EINVAL;
|
|
|
|
|
|
down_write(&mm->mmap_sem);
|
|
|
-
|
|
|
- /* Too many mappings? */
|
|
|
- if (mm->map_count > sysctl_max_map_count) {
|
|
|
- ret = -ENOMEM;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- /* Obtain the address to map to. we verify (or select) it and ensure
|
|
|
- * that it represents a valid section of the address space.
|
|
|
- */
|
|
|
- addr = get_unmapped_area(NULL, 0, len, 0, MAP_ANONYMOUS | MAP_PRIVATE);
|
|
|
- if (addr & ~PAGE_MASK) {
|
|
|
- ret = addr;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- vm_flags = VM_READ | VM_WRITE | VM_MPX |
|
|
|
- mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
|
|
|
-
|
|
|
- /* Set pgoff according to addr for anon_vma */
|
|
|
- pgoff = addr >> PAGE_SHIFT;
|
|
|
-
|
|
|
- ret = mmap_region(NULL, addr, len, vm_flags, pgoff);
|
|
|
- if (IS_ERR_VALUE(ret))
|
|
|
- goto out;
|
|
|
-
|
|
|
- vma = find_vma(mm, ret);
|
|
|
- if (!vma) {
|
|
|
- ret = -ENOMEM;
|
|
|
- goto out;
|
|
|
- }
|
|
|
-
|
|
|
- if (vm_flags & VM_LOCKED) {
|
|
|
- up_write(&mm->mmap_sem);
|
|
|
- mm_populate(ret, len);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
-out:
|
|
|
+ addr = do_mmap(NULL, 0, len, PROT_READ | PROT_WRITE,
|
|
|
+ MAP_ANONYMOUS | MAP_PRIVATE, VM_MPX, 0, &populate);
|
|
|
up_write(&mm->mmap_sem);
|
|
|
- return ret;
|
|
|
+ if (populate)
|
|
|
+ mm_populate(addr, populate);
|
|
|
+
|
|
|
+ return addr;
|
|
|
}
|
|
|
|
|
|
enum reg_type {
|