Patch "powerpc/mm/fault: Fix kfence page fault reporting" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    powerpc/mm/fault: Fix kfence page fault reporting

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     powerpc-mm-fault-fix-kfence-page-fault-reporting.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit aace37315ad09222c6c35db12bc33941f0673534
Author: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx>
Date:   Fri Oct 18 22:59:42 2024 +0530

    powerpc/mm/fault: Fix kfence page fault reporting
    
    [ Upstream commit 06dbbb4d5f7126b6307ab807cbf04ecfc459b933 ]
    
    copy_from_kernel_nofault() can be called when doing read of /proc/kcore.
    /proc/kcore can have some unmapped kfence objects which when read via
    copy_from_kernel_nofault() can cause page faults. Since *_nofault()
    functions define their own fixup table for handling fault, use that
    instead of asking kfence to handle such faults.
    
    Hence we search the exception tables for the nip which generated the
    fault. If there is an entry then we let the fixup table handler handle the
    page fault by returning an error from within ___do_page_fault().
    
    This can be easily triggered if someone tries to do dd from /proc/kcore.
    eg. dd if=/proc/kcore of=/dev/null bs=1M
    
    Some example false negatives:
    
      ===============================
      BUG: KFENCE: invalid read in copy_from_kernel_nofault+0x9c/0x1a0
      Invalid read at 0xc0000000fdff0000:
       copy_from_kernel_nofault+0x9c/0x1a0
       0xc00000000665f950
       read_kcore_iter+0x57c/0xa04
       proc_reg_read_iter+0xe4/0x16c
       vfs_read+0x320/0x3ec
       ksys_read+0x90/0x154
       system_call_exception+0x120/0x310
       system_call_vectored_common+0x15c/0x2ec
    
      BUG: KFENCE: use-after-free read in copy_from_kernel_nofault+0x9c/0x1a0
      Use-after-free read at 0xc0000000fe050000 (in kfence-#2):
       copy_from_kernel_nofault+0x9c/0x1a0
       0xc00000000665f950
       read_kcore_iter+0x57c/0xa04
       proc_reg_read_iter+0xe4/0x16c
       vfs_read+0x320/0x3ec
       ksys_read+0x90/0x154
       system_call_exception+0x120/0x310
       system_call_vectored_common+0x15c/0x2ec
    
    Fixes: 90cbac0e995d ("powerpc: Enable KFENCE for PPC32")
    Suggested-by: Christophe Leroy <christophe.leroy@xxxxxxxxxx>
    Reported-by: Disha Goel <disgoel@xxxxxxxxxxxxx>
    Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx>
    Reviewed-by: Christophe Leroy <christophe.leroy@xxxxxxxxxx>
    Signed-off-by: Michael Ellerman <mpe@xxxxxxxxxxxxxx>
    Link: https://patch.msgid.link/a411788081d50e3b136c6270471e35aba3dfafa3.1729271995.git.ritesh.list@xxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 644e4ec6ce99d..4b59315cb820a 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -431,10 +431,16 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
 	/*
 	 * The kernel should never take an execute fault nor should it
 	 * take a page fault to a kernel address or a page fault to a user
-	 * address outside of dedicated places
+	 * address outside of dedicated places.
+	 *
+	 * Rather than kfence directly reporting false negatives, search whether
+	 * the NIP belongs to the fixup table for cases where fault could come
+	 * from functions like copy_from_kernel_nofault().
 	 */
 	if (unlikely(!is_user && bad_kernel_fault(regs, error_code, address, is_write))) {
-		if (kfence_handle_page_fault(address, is_write, regs))
+		if (is_kfence_address((void *)address) &&
+		    !search_exception_tables(instruction_pointer(regs)) &&
+		    kfence_handle_page_fault(address, is_write, regs))
 			return 0;
 
 		return SIGSEGV;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux