]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Feb 2021 10:27:33 +0000 (11:27 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Feb 2021 10:27:33 +0000 (11:27 +0100)
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

queue-4.14/series
queue-4.14/x86-entry-64-compat-fix-x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch [new file with mode: 0644]
queue-4.14/x86-entry-64-compat-preserve-r8-r11-in-int-0x80.patch [new file with mode: 0644]

index 28864872853f4158e1175fea591b7778343445fa..b632f247b7718385bdb503f70ea0be7f45f5db21 100644 (file)
@@ -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 (file)
index 0000000..9b961b4
--- /dev/null
@@ -0,0 +1,94 @@
+From 22cd978e598618e82c3c3348d2069184f6884182 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+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 <luto@kernel.org>
+
+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 <luto@kernel.org>
+Cc: Arjan van de Ven <arjan@linux.intel.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: David Woodhouse <dwmw2@infradead.org>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+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 <mingo@kernel.org>
+Signed-off-by: Alistair Delva <adelva@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..6f052a3
--- /dev/null
@@ -0,0 +1,131 @@
+From 8bb2610bc4967f19672444a7b0407367f1540028 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Tue, 17 Apr 2018 07:36:36 -0700
+Subject: x86/entry/64/compat: Preserve r8-r11 in int $0x80
+
+From: Andy Lutomirski <luto@kernel.org>
+
+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 <dvlasenk@redhat.com>
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Dominik Brodowski <linux@dominikbrodowski.net>
+Link: https://lkml.kernel.org/r/d4c4d9985fbe64f8c9e19291886453914b48caee.1523975710.git.luto@kernel.org
+Signed-off-by: Alistair Delva <adelva@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 = &regs64.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++;