LKML Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/5] Minor selftests improvements
@ 2017-11-04 11:19 Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 1/5] selftests/x86/protection_keys: Fix syscall NR redefinition warnings Andy Lutomirski
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Andy Lutomirski @ 2017-11-04 11:19 UTC (permalink / raw)
  To: X86 ML; +Cc: Borislav Petkov, linux-kernel, Andy Lutomirski

This improves and robustifies the ldt_gdt test and fixes compiler warnings
in the protection_keys test.

Andy Lutomirski (5):
  selftests/x86/protection_keys: Fix syscall NR redefinition warnings
  selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR
    oddities
  selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area()
  selftests/x86/ldt_gdt: Run most existing LDT test cases against the
    GDT as well
  selftests/x86/ldt_get: Add a few additional tests for limits

 tools/testing/selftests/x86/ldt_gdt.c         | 88 +++++++++++++++++++++------
 tools/testing/selftests/x86/protection_keys.c | 24 ++++++--
 2 files changed, 88 insertions(+), 24 deletions(-)

-- 
2.13.6

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/5] selftests/x86/protection_keys: Fix syscall NR redefinition warnings
  2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
@ 2017-11-04 11:19 ` Andy Lutomirski
  2017-11-07 10:16   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 2/5] selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities Andy Lutomirski
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Andy Lutomirski @ 2017-11-04 11:19 UTC (permalink / raw)
  To: X86 ML
  Cc: Borislav Petkov, linux-kernel, Andy Lutomirski, Dave Hansen, stable

On new enough glibc, the pkey syscalls numbers are available.  Check
first before defining them to avoid warnings like:

protection_keys.c:198:0: warning: "SYS_pkey_alloc" redefined

Cc: Dave Hansen <dave.hansen@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 tools/testing/selftests/x86/protection_keys.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c
index 23927845518d..8d2760c65920 100644
--- a/tools/testing/selftests/x86/protection_keys.c
+++ b/tools/testing/selftests/x86/protection_keys.c
@@ -188,17 +188,29 @@ void lots_o_noops_around_write(int *write_to_me)
 #define u64 uint64_t
 
 #ifdef __i386__
-#define SYS_mprotect_key 380
-#define SYS_pkey_alloc	 381
-#define SYS_pkey_free	 382
+
+#ifndef SYS_mprotect_key
+# define SYS_mprotect_key 380
+#endif
+#ifndef SYS_pkey_alloc
+# define SYS_pkey_alloc	 381
+# define SYS_pkey_free	 382
+#endif
 #define REG_IP_IDX REG_EIP
 #define si_pkey_offset 0x14
+
 #else
-#define SYS_mprotect_key 329
-#define SYS_pkey_alloc	 330
-#define SYS_pkey_free	 331
+
+#ifndef SYS_mprotect_key
+# define SYS_mprotect_key 329
+#endif
+#ifndef SYS_pkey_alloc
+# define SYS_pkey_alloc	 330
+# define SYS_pkey_free	 331
+#endif
 #define REG_IP_IDX REG_RIP
 #define si_pkey_offset 0x20
+
 #endif
 
 void dump_mem(void *dumpme, int len_bytes)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/5] selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities
  2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 1/5] selftests/x86/protection_keys: Fix syscall NR redefinition warnings Andy Lutomirski
@ 2017-11-04 11:19 ` Andy Lutomirski
  2017-11-07 10:17   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 3/5] selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area() Andy Lutomirski
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Andy Lutomirski @ 2017-11-04 11:19 UTC (permalink / raw)
  To: X86 ML; +Cc: Borislav Petkov, linux-kernel, Andy Lutomirski

Bits 19:16 of LAR's result are undefined, and some upcoming
improvements to the test case seem to trigger this.  Mask off those
bits to avoid spurious failures.

commit 5b781c7e317f ("x86/tls: Forcibly set the accessed bit in TLS
segments") adds a valid case in which LAR's output doesn't quite
agree with set_thread_area()'s input.  This isn't triggered in the
test as is, but it will be if we start calling set_thread_area()
with the accessed bit clear.  Work around this discrepency.

I've added a Fixes tag so that -stable can pick this up if neccesary.

Fixes: 5b781c7e317f ("x86/tls: Forcibly set the accessed bit in TLS segments")
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index b9a22f18566a..b2c54f4673f2 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -114,7 +114,15 @@ static void check_valid_segment(uint16_t index, int ldt,
 		return;
 	}
 
-	if (ar != expected_ar) {
+	/* The SDM says "bits 19:16 are undefined".  Thanks. */
+	ar &= ~0xF0000;
+
+	/*
+	 * NB: Different Linux versions do different things with the
+	 * accessed bit in set_thread_area().
+	 */
+	if (ar != expected_ar &&
+	    (ldt || ar != (expected_ar | AR_ACCESSED))) {
 		printf("[FAIL]\t%s entry %hu has AR 0x%08X but expected 0x%08X\n",
 		       (ldt ? "LDT" : "GDT"), index, ar, expected_ar);
 		nerrs++;
-- 
2.13.6

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/5] selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area()
  2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 1/5] selftests/x86/protection_keys: Fix syscall NR redefinition warnings Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 2/5] selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities Andy Lutomirski
@ 2017-11-04 11:19 ` Andy Lutomirski
  2017-11-07 10:17   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 4/5] selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well Andy Lutomirski
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Andy Lutomirski @ 2017-11-04 11:19 UTC (permalink / raw)
  To: X86 ML; +Cc: Borislav Petkov, linux-kernel, Andy Lutomirski

Much of the test design could apply to set_thread_area() (i.e. GDT),
not just modify_ldt().  Add set_thread_area() to the
install_valid_mode() helper.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 53 ++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index b2c54f4673f2..337f217d0ae9 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -136,30 +136,51 @@ static void check_valid_segment(uint16_t index, int ldt,
 	}
 }
 
-static bool install_valid_mode(const struct user_desc *desc, uint32_t ar,
-			       bool oldmode)
+static bool install_valid_mode(const struct user_desc *d, uint32_t ar,
+			       bool oldmode, bool ldt)
 {
-	int ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11,
-			  desc, sizeof(*desc));
-	if (ret < -1)
-		errno = -ret;
+	struct user_desc desc = *d;
+	int ret;
+
+	if (!ldt) {
+#ifndef __i386__
+		/* No point testing set_thread_area in a 64-bit build */
+		return false;
+#endif
+		if (!gdt_entry_num)
+			return false;
+		desc.entry_number = gdt_entry_num;
+
+		ret = syscall(SYS_set_thread_area, &desc);
+	} else {
+		ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11,
+			      &desc, sizeof(desc));
+
+		if (ret < -1)
+			errno = -ret;
+
+		if (ret != 0 && errno == ENOSYS) {
+			printf("[OK]\tmodify_ldt returned -ENOSYS\n");
+			return false;
+		}
+	}
+
 	if (ret == 0) {
-		uint32_t limit = desc->limit;
-		if (desc->limit_in_pages)
+		uint32_t limit = desc.limit;
+		if (desc.limit_in_pages)
 			limit = (limit << 12) + 4095;
-		check_valid_segment(desc->entry_number, 1, ar, limit, true);
+		check_valid_segment(desc.entry_number, ldt, ar, limit, true);
 		return true;
-	} else if (errno == ENOSYS) {
-		printf("[OK]\tmodify_ldt returned -ENOSYS\n");
-		return false;
 	} else {
-		if (desc->seg_32bit) {
-			printf("[FAIL]\tUnexpected modify_ldt failure %d\n",
+		if (desc.seg_32bit) {
+			printf("[FAIL]\tUnexpected %s failure %d\n",
+			       ldt ? "modify_ldt" : "set_thread_area",
 			       errno);
 			nerrs++;
 			return false;
 		} else {
-			printf("[OK]\tmodify_ldt rejected 16 bit segment\n");
+			printf("[OK]\t%s rejected 16 bit segment\n",
+			       ldt ? "modify_ldt" : "set_thread_area");
 			return false;
 		}
 	}
@@ -167,7 +188,7 @@ static bool install_valid_mode(const struct user_desc *desc, uint32_t ar,
 
 static bool install_valid(const struct user_desc *desc, uint32_t ar)
 {
-	return install_valid_mode(desc, ar, false);
+	return install_valid_mode(desc, ar, false, true);
 }
 
 static void install_invalid(const struct user_desc *desc, bool oldmode)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 4/5] selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well
  2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
                   ` (2 preceding siblings ...)
  2017-11-04 11:19 ` [PATCH 3/5] selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area() Andy Lutomirski
@ 2017-11-04 11:19 ` Andy Lutomirski
  2017-11-07 10:17   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
  2017-11-04 11:19 ` [PATCH 5/5] selftests/x86/ldt_get: Add a few additional tests for limits Andy Lutomirski
  2017-11-07 10:13 ` [PATCH 0/5] Minor selftests improvements Ingo Molnar
  5 siblings, 1 reply; 12+ messages in thread
From: Andy Lutomirski @ 2017-11-04 11:19 UTC (permalink / raw)
  To: X86 ML; +Cc: Borislav Petkov, linux-kernel, Andy Lutomirski

Now that the main test infrastructure supports the GDT, run tests
that will pass the kernel's GDT permission tests against the GDT.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index 337f217d0ae9..05d0d6f49c2c 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -188,7 +188,15 @@ static bool install_valid_mode(const struct user_desc *d, uint32_t ar,
 
 static bool install_valid(const struct user_desc *desc, uint32_t ar)
 {
-	return install_valid_mode(desc, ar, false, true);
+	bool ret = install_valid_mode(desc, ar, false, true);
+
+	if (desc->contents <= 1 && desc->seg_32bit &&
+	    !desc->seg_not_present) {
+		/* Should work in the GDT, too. */
+		install_valid_mode(desc, ar, false, false);
+	}
+
+	return ret;
 }
 
 static void install_invalid(const struct user_desc *desc, bool oldmode)
-- 
2.13.6

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 5/5] selftests/x86/ldt_get: Add a few additional tests for limits
  2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
                   ` (3 preceding siblings ...)
  2017-11-04 11:19 ` [PATCH 4/5] selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well Andy Lutomirski
@ 2017-11-04 11:19 ` Andy Lutomirski
  2017-11-07 10:18   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
  2017-11-07 10:13 ` [PATCH 0/5] Minor selftests improvements Ingo Molnar
  5 siblings, 1 reply; 12+ messages in thread
From: Andy Lutomirski @ 2017-11-04 11:19 UTC (permalink / raw)
  To: X86 ML; +Cc: Borislav Petkov, linux-kernel, Andy Lutomirski

We weren't testing the .limit and .limit_in_pages fields very well.
Add more tests.

This addition seems to trigger the "bits 16:19 are undefined" issue
that was fixed in an earlier patch.  I think that, at least on my
CPU, the high nibble of the limit ends in LAR bits 16:19.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index 05d0d6f49c2c..8e290c9b2c3f 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -403,9 +403,24 @@ static void do_simple_tests(void)
 	install_invalid(&desc, false);
 
 	desc.seg_not_present = 0;
-	desc.read_exec_only = 0;
 	desc.seg_32bit = 1;
+	desc.read_exec_only = 0;
+	desc.limit = 0xfffff;
+
 	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S | AR_P | AR_DB);
+
+	desc.limit_in_pages = 1;
+
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S | AR_P | AR_DB | AR_G);
+	desc.read_exec_only = 1;
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA | AR_S | AR_P | AR_DB | AR_G);
+	desc.contents = 1;
+	desc.read_exec_only = 0;
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA_EXPDOWN | AR_S | AR_P | AR_DB | AR_G);
+	desc.read_exec_only = 1;
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA_EXPDOWN | AR_S | AR_P | AR_DB | AR_G);
+
+	desc.limit = 0;
 	install_invalid(&desc, true);
 }
 
-- 
2.13.6

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/5] Minor selftests improvements
  2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
                   ` (4 preceding siblings ...)
  2017-11-04 11:19 ` [PATCH 5/5] selftests/x86/ldt_get: Add a few additional tests for limits Andy Lutomirski
@ 2017-11-07 10:13 ` Ingo Molnar
  5 siblings, 0 replies; 12+ messages in thread
From: Ingo Molnar @ 2017-11-07 10:13 UTC (permalink / raw)
  To: Andy Lutomirski, Dave Hansen
  Cc: X86 ML, Borislav Petkov, linux-kernel, Thomas Gleixner,
	H. Peter Anvin, Peter Zijlstra


* Andy Lutomirski <luto@kernel.org> wrote:

> This improves and robustifies the ldt_gdt test and fixes compiler warnings
> in the protection_keys test.
> 
> Andy Lutomirski (5):
>   selftests/x86/protection_keys: Fix syscall NR redefinition warnings
>   selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR
>     oddities
>   selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area()
>   selftests/x86/ldt_gdt: Run most existing LDT test cases against the
>     GDT as well
>   selftests/x86/ldt_get: Add a few additional tests for limits
> 
>  tools/testing/selftests/x86/ldt_gdt.c         | 88 +++++++++++++++++++++------
>  tools/testing/selftests/x86/protection_keys.c | 24 ++++++--
>  2 files changed, 88 insertions(+), 24 deletions(-)

I'm still getting this build failure when typing 'make' in tools/testing/selftests/x86:

 gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/protection_keys_32 -O2 -g -std=gnu99 -pthread -Wall -no-pie  protection_keys.c -lrt -ldl -lm
 In file included from /usr/include/signal.h:57:0,
                  from protection_keys.c:33:
 protection_keys.c: In function ‘signal_handler’:
 protection_keys.c:253:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
   u64 si_pkey;
       ^
 protection_keys.c:253:6: error: expected expression before ‘.’ token

 ...
 Makefile:47: recipe for target '/home/mingo/tip/tools/testing/selftests/x86/protection_keys_32' failed

Plus I'm also getting these warnings even with all your fixes applied:

 gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/mpx-mini-test_32 -O2 -g -std=gnu99 -pthread -Wall -no-pie  mpx-mini-test.c -lrt -ldl -lm
 mpx-mini-test.c: In function ‘insn_test_failed’:
 mpx-mini-test.c:1406:3: warning: array subscript is above array bounds [-Warray-bounds]
    printf("bte[1]: %lx\n", bte->contents[1]);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 mpx-mini-test.c:1407:3: warning: array subscript is above array bounds [-Warray-bounds]
    printf("bte[2]: %lx\n", bte->contents[2]);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 mpx-mini-test.c:1408:3: warning: array subscript is above array bounds [-Warray-bounds]
    printf("bte[3]: %lx\n", bte->contents[3]);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip:x86/asm] selftests/x86/protection_keys: Fix syscall NR redefinition warnings
  2017-11-04 11:19 ` [PATCH 1/5] selftests/x86/protection_keys: Fix syscall NR redefinition warnings Andy Lutomirski
@ 2017-11-07 10:16   ` tip-bot for Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Andy Lutomirski @ 2017-11-07 10:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: torvalds, dave.hansen, linux-kernel, bpetkov, mingo, tglx,
	peterz, hpa, luto

Commit-ID:  693cb5580fdb026922363aa103add64b3ecd572e
Gitweb:     https://git.kernel.org/tip/693cb5580fdb026922363aa103add64b3ecd572e
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 4 Nov 2017 04:19:48 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 7 Nov 2017 11:13:42 +0100

selftests/x86/protection_keys: Fix syscall NR redefinition warnings

On new enough glibc, the pkey syscalls numbers are available.  Check
first before defining them to avoid warnings like:

protection_keys.c:198:0: warning: "SYS_pkey_alloc" redefined

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Dave Hansen <dave.hansen@intel.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
Link: http://lkml.kernel.org/r/1fbef53a9e6befb7165ff855fc1a7d4788a191d6.1509794321.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/testing/selftests/x86/protection_keys.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/x86/protection_keys.c b/tools/testing/selftests/x86/protection_keys.c
index 555e43c..7a1cc0e 100644
--- a/tools/testing/selftests/x86/protection_keys.c
+++ b/tools/testing/selftests/x86/protection_keys.c
@@ -189,17 +189,29 @@ void lots_o_noops_around_write(int *write_to_me)
 #define u64 uint64_t
 
 #ifdef __i386__
-#define SYS_mprotect_key 380
-#define SYS_pkey_alloc	 381
-#define SYS_pkey_free	 382
+
+#ifndef SYS_mprotect_key
+# define SYS_mprotect_key 380
+#endif
+#ifndef SYS_pkey_alloc
+# define SYS_pkey_alloc	 381
+# define SYS_pkey_free	 382
+#endif
 #define REG_IP_IDX REG_EIP
 #define si_pkey_offset 0x14
+
 #else
-#define SYS_mprotect_key 329
-#define SYS_pkey_alloc	 330
-#define SYS_pkey_free	 331
+
+#ifndef SYS_mprotect_key
+# define SYS_mprotect_key 329
+#endif
+#ifndef SYS_pkey_alloc
+# define SYS_pkey_alloc	 330
+# define SYS_pkey_free	 331
+#endif
 #define REG_IP_IDX REG_RIP
 #define si_pkey_offset 0x20
+
 #endif
 
 void dump_mem(void *dumpme, int len_bytes)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip:x86/asm] selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities
  2017-11-04 11:19 ` [PATCH 2/5] selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities Andy Lutomirski
@ 2017-11-07 10:17   ` tip-bot for Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Andy Lutomirski @ 2017-11-07 10:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, tglx, luto, torvalds, hpa, peterz, linux-kernel, bpetkov

Commit-ID:  d60ad744c9741586010d4bea286f09a063a90fbd
Gitweb:     https://git.kernel.org/tip/d60ad744c9741586010d4bea286f09a063a90fbd
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 4 Nov 2017 04:19:49 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 7 Nov 2017 11:13:42 +0100

selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities

Bits 19:16 of LAR's result are undefined, and some upcoming
improvements to the test case seem to trigger this.  Mask off those
bits to avoid spurious failures.

commit 5b781c7e317f ("x86/tls: Forcibly set the accessed bit in TLS
segments") adds a valid case in which LAR's output doesn't quite
agree with set_thread_area()'s input.  This isn't triggered in the
test as is, but it will be if we start calling set_thread_area()
with the accessed bit clear.  Work around this discrepency.

I've added a Fixes tag so that -stable can pick this up if neccesary.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Fixes: 5b781c7e317f ("x86/tls: Forcibly set the accessed bit in TLS segments")
Link: http://lkml.kernel.org/r/b82f3f89c034b53580970ac865139fd8863f44e2.1509794321.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index 961e3ee..b033433 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -115,7 +115,15 @@ static void check_valid_segment(uint16_t index, int ldt,
 		return;
 	}
 
-	if (ar != expected_ar) {
+	/* The SDM says "bits 19:16 are undefined".  Thanks. */
+	ar &= ~0xF0000;
+
+	/*
+	 * NB: Different Linux versions do different things with the
+	 * accessed bit in set_thread_area().
+	 */
+	if (ar != expected_ar &&
+	    (ldt || ar != (expected_ar | AR_ACCESSED))) {
 		printf("[FAIL]\t%s entry %hu has AR 0x%08X but expected 0x%08X\n",
 		       (ldt ? "LDT" : "GDT"), index, ar, expected_ar);
 		nerrs++;

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip:x86/asm] selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area()
  2017-11-04 11:19 ` [PATCH 3/5] selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area() Andy Lutomirski
@ 2017-11-07 10:17   ` tip-bot for Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Andy Lutomirski @ 2017-11-07 10:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, mingo, hpa, luto, torvalds, tglx, bpetkov, linux-kernel

Commit-ID:  d744dcad39094c9187075e274d1cdef79c57c8b5
Gitweb:     https://git.kernel.org/tip/d744dcad39094c9187075e274d1cdef79c57c8b5
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 4 Nov 2017 04:19:50 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 7 Nov 2017 11:13:42 +0100

selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area()

Much of the test design could apply to set_thread_area() (i.e. GDT),
not just modify_ldt().  Add set_thread_area() to the
install_valid_mode() helper.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/02c23f8fba5547007f741dc24c3926e5284ede02.1509794321.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 53 ++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index b033433..45f3024 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -137,30 +137,51 @@ static void check_valid_segment(uint16_t index, int ldt,
 	}
 }
 
-static bool install_valid_mode(const struct user_desc *desc, uint32_t ar,
-			       bool oldmode)
+static bool install_valid_mode(const struct user_desc *d, uint32_t ar,
+			       bool oldmode, bool ldt)
 {
-	int ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11,
-			  desc, sizeof(*desc));
-	if (ret < -1)
-		errno = -ret;
+	struct user_desc desc = *d;
+	int ret;
+
+	if (!ldt) {
+#ifndef __i386__
+		/* No point testing set_thread_area in a 64-bit build */
+		return false;
+#endif
+		if (!gdt_entry_num)
+			return false;
+		desc.entry_number = gdt_entry_num;
+
+		ret = syscall(SYS_set_thread_area, &desc);
+	} else {
+		ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11,
+			      &desc, sizeof(desc));
+
+		if (ret < -1)
+			errno = -ret;
+
+		if (ret != 0 && errno == ENOSYS) {
+			printf("[OK]\tmodify_ldt returned -ENOSYS\n");
+			return false;
+		}
+	}
+
 	if (ret == 0) {
-		uint32_t limit = desc->limit;
-		if (desc->limit_in_pages)
+		uint32_t limit = desc.limit;
+		if (desc.limit_in_pages)
 			limit = (limit << 12) + 4095;
-		check_valid_segment(desc->entry_number, 1, ar, limit, true);
+		check_valid_segment(desc.entry_number, ldt, ar, limit, true);
 		return true;
-	} else if (errno == ENOSYS) {
-		printf("[OK]\tmodify_ldt returned -ENOSYS\n");
-		return false;
 	} else {
-		if (desc->seg_32bit) {
-			printf("[FAIL]\tUnexpected modify_ldt failure %d\n",
+		if (desc.seg_32bit) {
+			printf("[FAIL]\tUnexpected %s failure %d\n",
+			       ldt ? "modify_ldt" : "set_thread_area",
 			       errno);
 			nerrs++;
 			return false;
 		} else {
-			printf("[OK]\tmodify_ldt rejected 16 bit segment\n");
+			printf("[OK]\t%s rejected 16 bit segment\n",
+			       ldt ? "modify_ldt" : "set_thread_area");
 			return false;
 		}
 	}
@@ -168,7 +189,7 @@ static bool install_valid_mode(const struct user_desc *desc, uint32_t ar,
 
 static bool install_valid(const struct user_desc *desc, uint32_t ar)
 {
-	return install_valid_mode(desc, ar, false);
+	return install_valid_mode(desc, ar, false, true);
 }
 
 static void install_invalid(const struct user_desc *desc, bool oldmode)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip:x86/asm] selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well
  2017-11-04 11:19 ` [PATCH 4/5] selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well Andy Lutomirski
@ 2017-11-07 10:17   ` tip-bot for Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Andy Lutomirski @ 2017-11-07 10:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, luto, tglx, hpa, linux-kernel, torvalds, bpetkov, peterz

Commit-ID:  adedf2893c192dd09b1cc2f2dcfdd7cad99ec49d
Gitweb:     https://git.kernel.org/tip/adedf2893c192dd09b1cc2f2dcfdd7cad99ec49d
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 4 Nov 2017 04:19:51 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 7 Nov 2017 11:13:43 +0100

selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well

Now that the main test infrastructure supports the GDT, run tests
that will pass the kernel's GDT permission tests against the GDT.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/686a1eda63414da38fcecc2412db8dba1ae40581.1509794321.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index 45f3024..3bb42ff 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -189,7 +189,15 @@ static bool install_valid_mode(const struct user_desc *d, uint32_t ar,
 
 static bool install_valid(const struct user_desc *desc, uint32_t ar)
 {
-	return install_valid_mode(desc, ar, false, true);
+	bool ret = install_valid_mode(desc, ar, false, true);
+
+	if (desc->contents <= 1 && desc->seg_32bit &&
+	    !desc->seg_not_present) {
+		/* Should work in the GDT, too. */
+		install_valid_mode(desc, ar, false, false);
+	}
+
+	return ret;
 }
 
 static void install_invalid(const struct user_desc *desc, bool oldmode)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip:x86/asm] selftests/x86/ldt_get: Add a few additional tests for limits
  2017-11-04 11:19 ` [PATCH 5/5] selftests/x86/ldt_get: Add a few additional tests for limits Andy Lutomirski
@ 2017-11-07 10:18   ` tip-bot for Andy Lutomirski
  0 siblings, 0 replies; 12+ messages in thread
From: tip-bot for Andy Lutomirski @ 2017-11-07 10:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, bpetkov, torvalds, tglx, luto, linux-kernel, mingo, hpa

Commit-ID:  fec8f5ae1715a01c72ad52cb2ecd8aacaf142302
Gitweb:     https://git.kernel.org/tip/fec8f5ae1715a01c72ad52cb2ecd8aacaf142302
Author:     Andy Lutomirski <luto@kernel.org>
AuthorDate: Sat, 4 Nov 2017 04:19:52 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 7 Nov 2017 11:13:43 +0100

selftests/x86/ldt_get: Add a few additional tests for limits

We weren't testing the .limit and .limit_in_pages fields very well.
Add more tests.

This addition seems to trigger the "bits 16:19 are undefined" issue
that was fixed in an earlier patch.  I think that, at least on my
CPU, the high nibble of the limit ends in LAR bits 16:19.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bpetkov@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/5601c15ea9b3113d288953fd2838b18bedf6bc67.1509794321.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 tools/testing/selftests/x86/ldt_gdt.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
index 3bb42ff..66e5ce5 100644
--- a/tools/testing/selftests/x86/ldt_gdt.c
+++ b/tools/testing/selftests/x86/ldt_gdt.c
@@ -404,9 +404,24 @@ static void do_simple_tests(void)
 	install_invalid(&desc, false);
 
 	desc.seg_not_present = 0;
-	desc.read_exec_only = 0;
 	desc.seg_32bit = 1;
+	desc.read_exec_only = 0;
+	desc.limit = 0xfffff;
+
 	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S | AR_P | AR_DB);
+
+	desc.limit_in_pages = 1;
+
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S | AR_P | AR_DB | AR_G);
+	desc.read_exec_only = 1;
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA | AR_S | AR_P | AR_DB | AR_G);
+	desc.contents = 1;
+	desc.read_exec_only = 0;
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA_EXPDOWN | AR_S | AR_P | AR_DB | AR_G);
+	desc.read_exec_only = 1;
+	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA_EXPDOWN | AR_S | AR_P | AR_DB | AR_G);
+
+	desc.limit = 0;
 	install_invalid(&desc, true);
 }
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-04 11:19 [PATCH 0/5] Minor selftests improvements Andy Lutomirski
2017-11-04 11:19 ` [PATCH 1/5] selftests/x86/protection_keys: Fix syscall NR redefinition warnings Andy Lutomirski
2017-11-07 10:16   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2017-11-04 11:19 ` [PATCH 2/5] selftests/x86/ldt_gdt: Robustify against set_thread_area() and LAR oddities Andy Lutomirski
2017-11-07 10:17   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2017-11-04 11:19 ` [PATCH 3/5] selftests/x86/ldt_gdt: Add infrastructure to test set_thread_area() Andy Lutomirski
2017-11-07 10:17   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2017-11-04 11:19 ` [PATCH 4/5] selftests/x86/ldt_gdt: Run most existing LDT test cases against the GDT as well Andy Lutomirski
2017-11-07 10:17   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2017-11-04 11:19 ` [PATCH 5/5] selftests/x86/ldt_get: Add a few additional tests for limits Andy Lutomirski
2017-11-07 10:18   ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2017-11-07 10:13 ` [PATCH 0/5] Minor selftests improvements Ingo Molnar

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git