]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 21 Nov 2021 07:50:24 +0000 (08:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 21 Nov 2021 07:50:24 +0000 (08:50 +0100)
added patches:
selftests-x86-iopl-adjust-to-the-faked-iopl-cli-sti-usage.patch

queue-5.10/selftests-x86-iopl-adjust-to-the-faked-iopl-cli-sti-usage.patch [new file with mode: 0644]

diff --git a/queue-5.10/selftests-x86-iopl-adjust-to-the-faked-iopl-cli-sti-usage.patch b/queue-5.10/selftests-x86-iopl-adjust-to-the-faked-iopl-cli-sti-usage.patch
new file mode 100644 (file)
index 0000000..40d5217
--- /dev/null
@@ -0,0 +1,160 @@
+From a72fdfd21e01c626273ddcf5ab740d4caef4be54 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Fri, 29 Oct 2021 19:27:32 +0200
+Subject: selftests/x86/iopl: Adjust to the faked iopl CLI/STI usage
+
+From: Borislav Petkov <bp@suse.de>
+
+commit a72fdfd21e01c626273ddcf5ab740d4caef4be54 upstream.
+
+Commit in Fixes changed the iopl emulation to not #GP on CLI and STI
+because it would break some insane luserspace tools which would toggle
+interrupts.
+
+The corresponding selftest would rely on the fact that executing CLI/STI
+would trigger a #GP and thus detect it this way but since that #GP is
+not happening anymore, the detection is now wrong too.
+
+Extend the test to actually look at the IF flag and whether executing
+those insns had any effect on it. The STI detection needs to have the
+fact that interrupts were previously disabled, passed in so do that from
+the previous CLI test, i.e., STI test needs to follow a previous CLI one
+for it to make sense.
+
+Fixes: b968e84b509d ("x86/iopl: Fake iopl(3) CLI/STI usage")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/r/20211030083939.13073-1-bp@alien8.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/x86/iopl.c |   78 +++++++++++++++++++++++++++----------
+ 1 file changed, 58 insertions(+), 20 deletions(-)
+
+--- a/tools/testing/selftests/x86/iopl.c
++++ b/tools/testing/selftests/x86/iopl.c
+@@ -85,48 +85,88 @@ static void expect_gp_outb(unsigned shor
+       printf("[OK]\toutb to 0x%02hx failed\n", port);
+ }
+-static bool try_cli(void)
++#define RET_FAULTED   0
++#define RET_FAIL      1
++#define RET_EMUL      2
++
++static int try_cli(void)
+ {
++      unsigned long flags;
++
+       sethandler(SIGSEGV, sigsegv, SA_RESETHAND);
+       if (sigsetjmp(jmpbuf, 1) != 0) {
+-              return false;
++              return RET_FAULTED;
+       } else {
+-              asm volatile ("cli");
+-              return true;
++              asm volatile("cli; pushf; pop %[flags]"
++                              : [flags] "=rm" (flags));
++
++              /* X86_FLAGS_IF */
++              if (!(flags & (1 << 9)))
++                      return RET_FAIL;
++              else
++                      return RET_EMUL;
+       }
+       clearhandler(SIGSEGV);
+ }
+-static bool try_sti(void)
++static int try_sti(bool irqs_off)
+ {
++      unsigned long flags;
++
+       sethandler(SIGSEGV, sigsegv, SA_RESETHAND);
+       if (sigsetjmp(jmpbuf, 1) != 0) {
+-              return false;
++              return RET_FAULTED;
+       } else {
+-              asm volatile ("sti");
+-              return true;
++              asm volatile("sti; pushf; pop %[flags]"
++                              : [flags] "=rm" (flags));
++
++              /* X86_FLAGS_IF */
++              if (irqs_off && (flags & (1 << 9)))
++                      return RET_FAIL;
++              else
++                      return RET_EMUL;
+       }
+       clearhandler(SIGSEGV);
+ }
+-static void expect_gp_sti(void)
++static void expect_gp_sti(bool irqs_off)
+ {
+-      if (try_sti()) {
++      int ret = try_sti(irqs_off);
++
++      switch (ret) {
++      case RET_FAULTED:
++              printf("[OK]\tSTI faulted\n");
++              break;
++      case RET_EMUL:
++              printf("[OK]\tSTI NOPped\n");
++              break;
++      default:
+               printf("[FAIL]\tSTI worked\n");
+               nerrs++;
+-      } else {
+-              printf("[OK]\tSTI faulted\n");
+       }
+ }
+-static void expect_gp_cli(void)
++/*
++ * Returns whether it managed to disable interrupts.
++ */
++static bool test_cli(void)
+ {
+-      if (try_cli()) {
++      int ret = try_cli();
++
++      switch (ret) {
++      case RET_FAULTED:
++              printf("[OK]\tCLI faulted\n");
++              break;
++      case RET_EMUL:
++              printf("[OK]\tCLI NOPped\n");
++              break;
++      default:
+               printf("[FAIL]\tCLI worked\n");
+               nerrs++;
+-      } else {
+-              printf("[OK]\tCLI faulted\n");
++              return true;
+       }
++
++      return false;
+ }
+ int main(void)
+@@ -152,8 +192,7 @@ int main(void)
+       }
+       /* Make sure that CLI/STI are blocked even with IOPL level 3 */
+-      expect_gp_cli();
+-      expect_gp_sti();
++      expect_gp_sti(test_cli());
+       expect_ok_outb(0x80);
+       /* Establish an I/O bitmap to test the restore */
+@@ -204,8 +243,7 @@ int main(void)
+       printf("[RUN]\tparent: write to 0x80 (should fail)\n");
+       expect_gp_outb(0x80);
+-      expect_gp_cli();
+-      expect_gp_sti();
++      expect_gp_sti(test_cli());
+       /* Test the capability checks. */
+       printf("\tiopl(3)\n");