FAILED: patch "[PATCH] parisc: Fix random data corruption from exception handler" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 8b1d72395635af45410b66cc4c4ab37a12c4a831
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024021939-unreached-bacon-95e0@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
8b1d72395635 ("parisc: Fix random data corruption from exception handler") a80aeb86542a ("parisc: Mark ex_table entries 32-bit aligned in uaccess.h") 01fef8267390 ("parisc: Allow building uncompressed Linux kernel")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 8b1d72395635af45410b66cc4c4ab37a12c4a831 Mon Sep 17 00:00:00 2001
From: Helge Deller <[email protected]>
Date: Sat, 20 Jan 2024 15:29:27 +0100
Subject: [PATCH] parisc: Fix random data corruption from exception handler
The current exception handler implementation, which assists when accessing user space memory, may exhibit random data corruption if the compiler decides to use a different register than the specified register %r29 (defined in ASM_EXCEPTIONTABLE_REG) for the error code. If the compiler choose another register, the fault handler will nevertheless store -EFAULT into %r29 and thus trash whatever this register is used for.
Looking at the assembly I found that this happens sometimes in emulate_ldd().
To solve the issue, the easiest solution would be if it somehow is possible to tell the fault handler which register is used to hold the error code. Using %0 or %1 in the inline assembly is not posssible as it will show up as e.g. %r29 (with the "%r" prefix), which the GNU assembler can not convert to an integer.
This patch takes another, better and more flexible approach:
We extend the __ex_table (which is out of the execution path) by one 32-word. In this word we tell the compiler to insert the assembler instruction "or %r0,%r0,%reg", where %reg references the register which the compiler choosed for the error return code.
In case of an access failure, the fault handler finds the __ex_table entry and can examine the opcode. The used register is encoded in the lowest 5 bits, and the fault handler can then store -EFAULT into this register.
Since we extend the __ex_table to 3 words we can't use the BUILDTIME_TABLE_SORT config option any longer.
arch/parisc/Kconfig +0 -1
@@ -25,7 +25,6 @@ config PARISC select RTC_DRV_GENERIC select INIT_ALL_POSSIBLE select BUG - select BUILDTIME_TABLE_SORT select HAVE_KERNEL_UNCOMPRESSED select HAVE_PCI select HAVE_PERF_EVENTS
arch/parisc/include/asm/assembly.h +1 -0
@@ -576,6 +576,7 @@ .section __ex_table,"aw" ! \ .align 4 ! \ .word (fault_addr - .), (except_addr - .) ! \ + or %r0,%r0,%r0 ! \ .previous
arch/parisc/include/asm/extable.h new file +64 -0
64 lines not on this page · raw message
arch/parisc/include/asm/special_insns.h +4 -2
@@ -8,7 +8,8 @@"copy %%r0,%0\n" \"8:\tlpa %%r0(%1),%0\n" \"9:\n" \ -ASM_EXCEPTIONTABLE_ENTRY (8b ,9b ) \ +ASM_EXCEPTIONTABLE_ENTRY (8b ,9b , \ +"or %%r0,%%r0,%%r0" ) \ : "=&r" (pa) \: " r" (va) \ : " memory" \
@@ -22,7 +23,8 @@"copy %%r0,%0\n" \"8:\tlpa %%r0(%%sr3,%1),%0\n" \"9:\n" \ -ASM_EXCEPTIONTABLE_ENTRY (8b ,9b ) \ +ASM_EXCEPTIONTABLE_ENTRY (8b ,9b , \ +"or %%r0,%%r0,%%r0" ) \ : "=&r" (pa) \: " r" (va) \ : " memory" \
arch/parisc/include/asm/uaccess.h +7 -41
94 lines not on this page · raw message
arch/parisc/kernel/cache.c +2 -2
@@ -854,7 +854,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,#endif " fic,m %3(%4,%0)\n" "2: sync\n" -ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ) +ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ,"%1" ) : "+r" (start), "+r" (error) : "r" (end), "r" (dcache_stride), "i" (SR_USER)); }
@@ -869,7 +869,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,#endif " fdc,m %3(%4,%0)\n" "2: sync\n" -ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ) +ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ,"%1" ) : "+r" (start), "+r" (error) : "r" (end), "r" (icache_stride), "i" (SR_USER)); }
arch/parisc/kernel/unaligned.c +22 -22
92 lines not on this page · raw message
arch/parisc/mm/fault.c +8 -3
@@ -150,11 +150,16 @@ int fixup_exception(struct pt_regs *regs)* Fix up get_user() and put_user(). * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant * bit in the relative address of the fixup routine to indicate -* that gr[ASM_EXCEPTIONTABLE_REG] should be loaded with -* -EFAULT to report a userspace access error. +* that the register encoded in the "or %r0,%r0,register" +* opcode should be loaded with -EFAULT to report a userspace +* access error. */ if (fix->fixup &1 ) { - regs->gr[ASM_EXCEPTIONTABLE_REG ] = -EFAULT ; +int fault_error_reg = fix->err_opcode &0x1f ; +if (!WARN_ON (!fault_error_reg)) + regs->gr[fault_error_reg] = -EFAULT ; +pr_debug ("Unalignment fixup of register %d at %pS\n" , + fault_error_reg, (void *)regs->iaoq[0 ]);/* zero target register for get_user() */ if (parisc_acctyp (0 , regs->iir) ==VM_READ ) {
* [email protected] <[email protected]>:
Quoted 5 lines
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Greg, below is the patch adjusted for stable kernel 6.6. Please apply.
Thanks!
Helge
From 887c1dfae4042324cba3b3e3a4b5bb390c586a1a Mon Sep 17 00:00:00 2001
From: Helge Deller <[email protected]>
Date: Sat, 20 Jan 2024 15:29:27 +0100
Subject: [PATCH] parisc: Fix random data corruption from exception handler
The current exception handler implementation, which assists when accessing user space memory, may exhibit random data corruption if the compiler decides to use a different register than the specified register %r29 (defined in ASM_EXCEPTIONTABLE_REG) for the error code. If the compiler choose another register, the fault handler will nevertheless store -EFAULT into %r29 and thus trash whatever this register is used for.
Looking at the assembly I found that this happens sometimes in emulate_ldd().
To solve the issue, the easiest solution would be if it somehow is possible to tell the fault handler which register is used to hold the error code. Using %0 or %1 in the inline assembly is not posssible as it will show up as e.g. %r29 (with the "%r" prefix), which the GNU assembler can not convert to an integer.
This patch takes another, better and more flexible approach:
We extend the __ex_table (which is out of the execution path) by one 32-word. In this word we tell the compiler to insert the assembler instruction "or %r0,%r0,%reg", where %reg references the register which the compiler choosed for the error return code.
In case of an access failure, the fault handler finds the __ex_table entry and can examine the opcode. The used register is encoded in the lowest 5 bits, and the fault handler can then store -EFAULT into this register.
Since we extend the __ex_table to 3 words we can't use the BUILDTIME_TABLE_SORT config option any longer.
arch/parisc/Kconfig +0 -1
@@ -24,7 +24,6 @@ config PARISC select RTC_DRV_GENERIC select INIT_ALL_POSSIBLE select BUG - select BUILDTIME_TABLE_SORT select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_KERNEL_BZIP2
arch/parisc/include/asm/assembly.h +1 -0
@@ -576,6 +576,7 @@ .section __ex_table,"aw" ! \ .align 4 ! \ .word (fault_addr - .), (except_addr - .) ! \ + or %r0,%r0,%r0 ! \ .previous
arch/parisc/include/asm/extable.h new file +64 -0
64 lines not on this page · raw message
arch/parisc/include/asm/special_insns.h +4 -2
@@ -8,7 +8,8 @@"copy %%r0,%0\n" \"8:\tlpa %%r0(%1),%0\n" \"9:\n" \ -ASM_EXCEPTIONTABLE_ENTRY (8b ,9b ) \ +ASM_EXCEPTIONTABLE_ENTRY (8b ,9b , \ +"or %%r0,%%r0,%%r0" ) \ : "=&r" (pa) \: " r" (va) \ : " memory" \
@@ -22,7 +23,8 @@"copy %%r0,%0\n" \"8:\tlpa %%r0(%%sr3,%1),%0\n" \"9:\n" \ -ASM_EXCEPTIONTABLE_ENTRY (8b ,9b ) \ +ASM_EXCEPTIONTABLE_ENTRY (8b ,9b , \ +"or %%r0,%%r0,%%r0" ) \ : "=&r" (pa) \: " r" (va) \ : " memory" \
arch/parisc/include/asm/uaccess.h +7 -41
94 lines not on this page · raw message
arch/parisc/kernel/cache.c +2 -2
@@ -850,7 +850,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,#endif " fic,m %3(%4,%0)\n" "2: sync\n" -ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ) +ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ,"%1" ) : "+r" (start), "+r" (error) : "r" (end), "r" (dcache_stride), "i" (SR_USER)); }
@@ -865,7 +865,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes,#endif " fdc,m %3(%4,%0)\n" "2: sync\n" -ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ) +ASM_EXCEPTIONTABLE_ENTRY_EFAULT (1b ,2b ,"%1" ) : "+r" (start), "+r" (error) : "r" (end), "r" (icache_stride), "i" (SR_USER)); }
arch/parisc/kernel/unaligned.c +22 -22
92 lines not on this page · raw message
arch/parisc/mm/fault.c +8 -3
@@ -150,11 +150,16 @@ int fixup_exception(struct pt_regs *regs)* Fix up get_user() and put_user(). * ASM_EXCEPTIONTABLE_ENTRY_EFAULT() sets the least-significant * bit in the relative address of the fixup routine to indicate -* that gr[ASM_EXCEPTIONTABLE_REG] should be loaded with -* -EFAULT to report a userspace access error. +* that the register encoded in the "or %r0,%r0,register" +* opcode should be loaded with -EFAULT to report a userspace +* access error. */ if (fix->fixup &1 ) { - regs->gr[ASM_EXCEPTIONTABLE_REG ] = -EFAULT ; +int fault_error_reg = fix->err_opcode &0x1f ; +if (!WARN_ON (!fault_error_reg)) + regs->gr[fault_error_reg] = -EFAULT ; +pr_debug ("Unalignment fixup of register %d at %pS\n" , + fault_error_reg, (void *)regs->iaoq[0 ]);/* zero target register for get_user() */ if (parisc_acctyp (0 , regs->iir) ==VM_READ ) {
Greg KH
maintainerQuoted 8 lines · Helge Deller
* [email protected] <[email protected]>:
Quoted 5 lines
The patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.Greg, below is the patch adjusted for stable kernel 6.6.
Both now queued up, thanks!
greg k-h