@@ -128,6 +128,19 @@ static inline bool is_translation_fault(unsigned int fsr)
128128 return false;
129129}
130130
131+ static inline bool is_permission_fault (unsigned int fsr )
132+ {
133+ int fs = fsr_fs (fsr );
134+ #ifdef CONFIG_ARM_LPAE
135+ if ((fs & FS_MMU_NOLL_MASK ) == FS_PERM_NOLL )
136+ return true;
137+ #else
138+ if (fs == FS_L1_PERM || fs == FS_L2_PERM )
139+ return true;
140+ #endif
141+ return false;
142+ }
143+
131144static void die_kernel_fault (const char * msg , struct mm_struct * mm ,
132145 unsigned long addr , unsigned int fsr ,
133146 struct pt_regs * regs )
@@ -162,6 +175,8 @@ __do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
162175 */
163176 if (addr < PAGE_SIZE ) {
164177 msg = "NULL pointer dereference" ;
178+ } else if (is_permission_fault (fsr ) && fsr & FSR_LNX_PF ) {
179+ msg = "execution of memory" ;
165180 } else {
166181 if (is_translation_fault (fsr ) &&
167182 kfence_handle_page_fault (addr , is_write_fault (fsr ), regs ))
@@ -183,9 +198,6 @@ __do_user_fault(unsigned long addr, unsigned int fsr, unsigned int sig,
183198{
184199 struct task_struct * tsk = current ;
185200
186- if (addr > TASK_SIZE )
187- harden_branch_predictor ();
188-
189201#ifdef CONFIG_DEBUG_USER
190202 if (((user_debug & UDBG_SEGV ) && (sig == SIGSEGV )) ||
191203 ((user_debug & UDBG_BUS ) && (sig == SIGBUS ))) {
@@ -225,19 +237,6 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
225237}
226238
227239#ifdef CONFIG_MMU
228- static inline bool is_permission_fault (unsigned int fsr )
229- {
230- int fs = fsr_fs (fsr );
231- #ifdef CONFIG_ARM_LPAE
232- if ((fs & FS_MMU_NOLL_MASK ) == FS_PERM_NOLL )
233- return true;
234- #else
235- if (fs == FS_L1_PERM || fs == FS_L2_PERM )
236- return true;
237- #endif
238- return false;
239- }
240-
241240#ifdef CONFIG_CPU_TTBR0_PAN
242241static inline bool ttbr0_usermode_access_allowed (struct pt_regs * regs )
243242{
@@ -259,6 +258,37 @@ static inline bool ttbr0_usermode_access_allowed(struct pt_regs *regs)
259258}
260259#endif
261260
261+ static int __kprobes
262+ do_kernel_address_page_fault (struct mm_struct * mm , unsigned long addr ,
263+ unsigned int fsr , struct pt_regs * regs )
264+ {
265+ if (user_mode (regs )) {
266+ /*
267+ * Fault from user mode for a kernel space address. User mode
268+ * should not be faulting in kernel space, which includes the
269+ * vector/khelper page. Handle the branch predictor hardening
270+ * while interrupts are still disabled, then send a SIGSEGV.
271+ */
272+ harden_branch_predictor ();
273+ __do_user_fault (addr , fsr , SIGSEGV , SEGV_MAPERR , regs );
274+ } else {
275+ /*
276+ * Fault from kernel mode. Enable interrupts if they were
277+ * enabled in the parent context. Section (upper page table)
278+ * translation faults are handled via do_translation_fault(),
279+ * so we will only get here for a non-present kernel space
280+ * PTE or PTE permission fault. This may happen in exceptional
281+ * circumstances and need the fixup tables to be walked.
282+ */
283+ if (interrupts_enabled (regs ))
284+ local_irq_enable ();
285+
286+ __do_kernel_fault (mm , addr , fsr , regs );
287+ }
288+
289+ return 0 ;
290+ }
291+
262292static int __kprobes
263293do_page_fault (unsigned long addr , unsigned int fsr , struct pt_regs * regs )
264294{
@@ -272,6 +302,12 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
272302 if (kprobe_page_fault (regs , fsr ))
273303 return 0 ;
274304
305+ /*
306+ * Handle kernel addresses faults separately, which avoids touching
307+ * the mmap lock from contexts that are not able to sleep.
308+ */
309+ if (addr >= TASK_SIZE )
310+ return do_kernel_address_page_fault (mm , addr , fsr , regs );
275311
276312 /* Enable interrupts if they were enabled in the parent context. */
277313 if (interrupts_enabled (regs ))
@@ -448,16 +484,20 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
448484 * We enter here because the first level page table doesn't contain
449485 * a valid entry for the address.
450486 *
451- * If the address is in kernel space (>= TASK_SIZE), then we are
452- * probably faulting in the vmalloc() area.
487+ * If this is a user address (addr < TASK_SIZE), we handle this as a
488+ * normal page fault. This leaves the remainder of the function to handle
489+ * kernel address translation faults.
490+ *
491+ * Since user mode is not permitted to access kernel addresses, pass these
492+ * directly to do_kernel_address_page_fault() to handle.
453493 *
454- * If the init_task's first level page tables contains the relevant
455- * entry, we copy the it to this task. If not, we send the process
456- * a signal, fixup the exception, or oops the kernel .
494+ * Otherwise, we're probably faulting in the vmalloc() area, so try to fix
495+ * that up. Note that we must not take any locks or enable interrupts in
496+ * this case .
457497 *
458- * NOTE! We MUST NOT take any locks for this case. We may be in an
459- * interrupt or a critical region, and should only copy the information
460- * from the master page table, nothing more .
498+ * If vmalloc() fixup fails, that means the non-leaf page tables did not
499+ * contain an entry for this address, so handle this via
500+ * do_kernel_address_page_fault() .
461501 */
462502#ifdef CONFIG_MMU
463503static int __kprobes
@@ -523,7 +563,8 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
523563 return 0 ;
524564
525565bad_area :
526- do_bad_area (addr , fsr , regs );
566+ do_kernel_address_page_fault (current -> mm , addr , fsr , regs );
567+
527568 return 0 ;
528569}
529570#else /* CONFIG_MMU */
@@ -543,7 +584,16 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
543584static int
544585do_sect_fault (unsigned long addr , unsigned int fsr , struct pt_regs * regs )
545586{
587+ /*
588+ * If this is a kernel address, but from user mode, then userspace
589+ * is trying bad stuff. Invoke the branch predictor handling.
590+ * Interrupts are disabled here.
591+ */
592+ if (addr >= TASK_SIZE && user_mode (regs ))
593+ harden_branch_predictor ();
594+
546595 do_bad_area (addr , fsr , regs );
596+
547597 return 0 ;
548598}
549599#endif /* CONFIG_ARM_LPAE */
0 commit comments