/* * Free unused bounds tables covered in a virtual address region being * munmap()ed. Assume end > start. * * This function will be called by do_munmap(), and the VMAs covering * the virtual address region start...end have already been split if * necessary, and the 'vma' is the first vma in this range (start -> end). */ void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long start, unsigned long end) { int ret; /* * Refuse to do anything unless userspace has asked * the kernel to help manage the bounds tables, */ if (!kernel_managing_mpx_tables(current->mm)) return; /* * This will look across the entire 'start -> end' range, * and find all of the non-VM_MPX VMAs. * * To avoid recursion, if a VM_MPX vma is found in the range * (start->end), we will not continue follow-up work. This * recursion represents having bounds tables for bounds tables, * which should not occur normally. Being strict about it here * helps ensure that we do not have an exploitable stack overflow. */ do { if (vma->vm_flags & VM_MPX) return; vma = vma->vm_next; } while (vma && vma->vm_start < end); ret = mpx_unmap_tables(mm, start, end); if (ret) force_sig(SIGSEGV, current); }
int mpx_handle_bd_fault(void) { /* * Userspace never asked us to manage the bounds tables, * so refuse to help. */ if (!kernel_managing_mpx_tables(current->mm)) return -EINVAL; return do_mpx_bt_fault(); }
int mpx_handle_bd_fault(void) { /* * Userspace never asked us to manage the bounds tables, * so refuse to help. */ if (!kernel_managing_mpx_tables(current->mm)) return -EINVAL; if (do_mpx_bt_fault()) { force_sig(SIGSEGV, current); /* * The force_sig() is essentially "handling" this * exception, so we do not pass up the error * from do_mpx_bt_fault(). */ } return 0; }