From: Greg Kroah-Hartman Date: Tue, 2 Feb 2021 10:27:33 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.255~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f60780919b92456ddbc9ce2b0ba840a097ec0869;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: x86-entry-64-compat-fix-x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch --- diff --git a/queue-4.14/series b/queue-4.14/series index 28864872853..b632f247b77 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -20,3 +20,5 @@ iwlwifi-pcie-use-jiffies-for-memory-read-spin-time-l.patch iwlwifi-pcie-reschedule-in-long-running-memory-reads.patch mac80211-pause-tx-while-changing-interface-type.patch can-dev-prevent-potential-information-leak-in-can_fi.patch +x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch +x86-entry-64-compat-fix-x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch diff --git a/queue-4.14/x86-entry-64-compat-fix-x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch b/queue-4.14/x86-entry-64-compat-fix-x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch new file mode 100644 index 00000000000..9b961b432ad --- /dev/null +++ b/queue-4.14/x86-entry-64-compat-fix-x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch @@ -0,0 +1,94 @@ +From 22cd978e598618e82c3c3348d2069184f6884182 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Tue, 26 Jun 2018 22:45:52 -0700 +Subject: x86/entry/64/compat: Fix "x86/entry/64/compat: Preserve r8-r11 in int $0x80" + +From: Andy Lutomirski + +commit 22cd978e598618e82c3c3348d2069184f6884182 upstream. + +Commit: + + 8bb2610bc496 ("x86/entry/64/compat: Preserve r8-r11 in int $0x80") + +was busted: my original patch had a minor conflict with +some of the nospec changes, but "git apply" is very clever +and silently accepted the patch by making the same changes +to a different function in the same file. There was obviously +a huge offset, but "git apply" for some reason doesn't feel +any need to say so. + +Move the changes to the correct function. Now the +test_syscall_vdso_32 selftests passes. + +If anyone cares to observe the original problem, try applying the +patch at: + + https://lore.kernel.org/lkml/d4c4d9985fbe64f8c9e19291886453914b48caee.1523975710.git.luto@kernel.org/raw + +to the kernel at 316d097c4cd4e7f2ef50c40cff2db266593c4ec4: + + - "git am" and "git apply" accept the patch without any complaints at all + - "patch -p1" at least prints out a message about the huge offset. + +Reported-by: zhijianx.li@intel.com +Signed-off-by: Andy Lutomirski +Cc: Arjan van de Ven +Cc: Borislav Petkov +Cc: Dan Williams +Cc: Dave Hansen +Cc: David Woodhouse +Cc: Greg Kroah-Hartman +Cc: Josh Poimboeuf +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: stable@vger.kernel.org #v4.17+ +Fixes: 8bb2610bc496 ("x86/entry/64/compat: Preserve r8-r11 in int $0x80") +Link: http://lkml.kernel.org/r/6012b922485401bc42676e804171ded262fc2ef2.1530078306.git.luto@kernel.org +Signed-off-by: Ingo Molnar +Signed-off-by: Alistair Delva +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/entry/entry_64_compat.S | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat) + pushq %rdx /* pt_regs->dx */ + pushq %rcx /* pt_regs->cx */ + pushq $-ENOSYS /* pt_regs->ax */ +- pushq %r8 /* pt_regs->r8 */ ++ pushq $0 /* pt_regs->r8 = 0 */ + xorl %r8d, %r8d /* nospec r8 */ +- pushq %r9 /* pt_regs->r9 */ ++ pushq $0 /* pt_regs->r9 = 0 */ + xorl %r9d, %r9d /* nospec r9 */ +- pushq %r10 /* pt_regs->r10 */ ++ pushq $0 /* pt_regs->r10 = 0 */ + xorl %r10d, %r10d /* nospec r10 */ +- pushq %r11 /* pt_regs->r11 */ ++ pushq $0 /* pt_regs->r11 = 0 */ + xorl %r11d, %r11d /* nospec r11 */ + pushq %rbx /* pt_regs->rbx */ + xorl %ebx, %ebx /* nospec rbx */ +@@ -357,13 +357,13 @@ ENTRY(entry_INT80_compat) + pushq %rdx /* pt_regs->dx */ + pushq %rcx /* pt_regs->cx */ + pushq $-ENOSYS /* pt_regs->ax */ +- pushq $0 /* pt_regs->r8 = 0 */ ++ pushq %r8 /* pt_regs->r8 */ + xorl %r8d, %r8d /* nospec r8 */ +- pushq $0 /* pt_regs->r9 = 0 */ ++ pushq %r9 /* pt_regs->r9 */ + xorl %r9d, %r9d /* nospec r9 */ +- pushq $0 /* pt_regs->r10 = 0 */ ++ pushq %r10 /* pt_regs->r10*/ + xorl %r10d, %r10d /* nospec r10 */ +- pushq $0 /* pt_regs->r11 = 0 */ ++ pushq %r11 /* pt_regs->r11 */ + xorl %r11d, %r11d /* nospec r11 */ + pushq %rbx /* pt_regs->rbx */ + xorl %ebx, %ebx /* nospec rbx */ diff --git a/queue-4.14/x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch b/queue-4.14/x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch new file mode 100644 index 00000000000..6f052a352e8 --- /dev/null +++ b/queue-4.14/x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch @@ -0,0 +1,131 @@ +From 8bb2610bc4967f19672444a7b0407367f1540028 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Tue, 17 Apr 2018 07:36:36 -0700 +Subject: x86/entry/64/compat: Preserve r8-r11 in int $0x80 + +From: Andy Lutomirski + +commit 8bb2610bc4967f19672444a7b0407367f1540028 upstream. + +32-bit user code that uses int $80 doesn't care about r8-r11. There is, +however, some 64-bit user code that intentionally uses int $0x80 to invoke +32-bit system calls. From what I've seen, basically all such code assumes +that r8-r15 are all preserved, but the kernel clobbers r8-r11. Since I +doubt that there's any code that depends on int $0x80 zeroing r8-r11, +change the kernel to preserve them. + +I suspect that very little user code is broken by the old clobber, since +r8-r11 are only rarely allocated by gcc, and they're clobbered by function +calls, so they only way we'd see a problem is if the same function that +invokes int $0x80 also spills something important to one of these +registers. + +The current behavior seems to date back to the historical commit +"[PATCH] x86-64 merge for 2.6.4". Before that, all regs were +preserved. I can't find any explanation of why this change was made. + +Update the test_syscall_vdso_32 testcase as well to verify the new +behavior, and it strengthens the test to make sure that the kernel doesn't +accidentally permute r8..r15. + +Suggested-by: Denys Vlasenko +Signed-off-by: Andy Lutomirski +Signed-off-by: Thomas Gleixner +Cc: Borislav Petkov +Cc: Dominik Brodowski +Link: https://lkml.kernel.org/r/d4c4d9985fbe64f8c9e19291886453914b48caee.1523975710.git.luto@kernel.org +Signed-off-by: Alistair Delva +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/entry/entry_64_compat.S | 8 ++--- + tools/testing/selftests/x86/test_syscall_vdso.c | 35 ++++++++++++++---------- + 2 files changed, 25 insertions(+), 18 deletions(-) + +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -84,13 +84,13 @@ ENTRY(entry_SYSENTER_compat) + pushq %rdx /* pt_regs->dx */ + pushq %rcx /* pt_regs->cx */ + pushq $-ENOSYS /* pt_regs->ax */ +- pushq $0 /* pt_regs->r8 = 0 */ ++ pushq %r8 /* pt_regs->r8 */ + xorl %r8d, %r8d /* nospec r8 */ +- pushq $0 /* pt_regs->r9 = 0 */ ++ pushq %r9 /* pt_regs->r9 */ + xorl %r9d, %r9d /* nospec r9 */ +- pushq $0 /* pt_regs->r10 = 0 */ ++ pushq %r10 /* pt_regs->r10 */ + xorl %r10d, %r10d /* nospec r10 */ +- pushq $0 /* pt_regs->r11 = 0 */ ++ pushq %r11 /* pt_regs->r11 */ + xorl %r11d, %r11d /* nospec r11 */ + pushq %rbx /* pt_regs->rbx */ + xorl %ebx, %ebx /* nospec rbx */ +--- a/tools/testing/selftests/x86/test_syscall_vdso.c ++++ b/tools/testing/selftests/x86/test_syscall_vdso.c +@@ -100,12 +100,19 @@ asm ( + " shl $32, %r8\n" + " orq $0x7f7f7f7f, %r8\n" + " movq %r8, %r9\n" +- " movq %r8, %r10\n" +- " movq %r8, %r11\n" +- " movq %r8, %r12\n" +- " movq %r8, %r13\n" +- " movq %r8, %r14\n" +- " movq %r8, %r15\n" ++ " incq %r9\n" ++ " movq %r9, %r10\n" ++ " incq %r10\n" ++ " movq %r10, %r11\n" ++ " incq %r11\n" ++ " movq %r11, %r12\n" ++ " incq %r12\n" ++ " movq %r12, %r13\n" ++ " incq %r13\n" ++ " movq %r13, %r14\n" ++ " incq %r14\n" ++ " movq %r14, %r15\n" ++ " incq %r15\n" + " ret\n" + " .code32\n" + " .popsection\n" +@@ -128,12 +135,13 @@ int check_regs64(void) + int err = 0; + int num = 8; + uint64_t *r64 = ®s64.r8; ++ uint64_t expected = 0x7f7f7f7f7f7f7f7fULL; + + if (!kernel_is_64bit) + return 0; + + do { +- if (*r64 == 0x7f7f7f7f7f7f7f7fULL) ++ if (*r64 == expected++) + continue; /* register did not change */ + if (syscall_addr != (long)&int80) { + /* +@@ -147,18 +155,17 @@ int check_regs64(void) + continue; + } + } else { +- /* INT80 syscall entrypoint can be used by ++ /* ++ * INT80 syscall entrypoint can be used by + * 64-bit programs too, unlike SYSCALL/SYSENTER. + * Therefore it must preserve R12+ + * (they are callee-saved registers in 64-bit C ABI). + * +- * This was probably historically not intended, +- * but R8..11 are clobbered (cleared to 0). +- * IOW: they are the only registers which aren't +- * preserved across INT80 syscall. ++ * Starting in Linux 4.17 (and any kernel that ++ * backports the change), R8..11 are preserved. ++ * Historically (and probably unintentionally), they ++ * were clobbered or zeroed. + */ +- if (*r64 == 0 && num <= 11) +- continue; + } + printf("[FAIL]\tR%d has changed:%016llx\n", num, *r64); + err++;