lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231219151200.2878271-2-vegard.nossum@oracle.com>
Date: Tue, 19 Dec 2023 16:11:56 +0100
From: Vegard Nossum <vegard.nossum@...cle.com>
To: Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>,
        Borislav Petkov <bp@...en8.de>,
        Dave Hansen <dave.hansen@...ux.intel.com>, x86@...nel.org
Cc: "H. Peter Anvin" <hpa@...or.com>, linux-kernel@...r.kernel.org,
        Brian Gerst <brgerst@...il.com>, Peter Zijlstra <peterz@...radead.org>,
        Linus Torvalds <torvalds@...uxfoundation.org>,
        Vegard Nossum <vegard.nossum@...cle.com>
Subject: [PATCH 1/5] x86: provide new infrastructure for GDT descriptors

Linus suggested replacing the magic numbers in the GDT descriptors
using preprocessor macros. Designing the interface properly is actually
pretty hard -- there are several constraints:

- you want the final expressions to be readable at a glance; something
  like GDT_ENTRY_FLAGS(5, 1, 0, 1, 0, 1, 1, 0) isn't because you need
  to visit the definition to understand what each parameter represents
  and then match up parameters in the user and the definition (which is
  hard when there are so many of them)

- you want the final expressions to be fairly short/information-dense;
  something like GDT_ENTRY_PRESENT | GDT_ENTRY_DATA_WRITABLE |
  GDT_ENTRY_SYSTEM | GDT_ENTRY_DB | GDT_ENTRY_GRANULARITY_4K is a bit
  too verbose to write out every time and is actually hard to read as
  well because of all the repetition

- you may want to assume defaults for some things (e.g. entries are
  DPL-0 a.k.a. kernel segments by default) and allow the user to
  override the default -- but this works best if you can OR in the
  override; if you want DPL-3 by default and override with DPL-0 you
  would need to start masking off bits instead of OR-ing them in and
  that just becomes harder to read

- you may want to parameterize some things (e.g. CODE vs. DATA or
  KERNEL vs. USER) since both values are used and you don't really
  want prefer either one by default -- or DPL, which is always some
  value that is always specified

This patch tries to balance these requirements and has two layers of
definitions -- low-level and high-level:

- the low-level defines are the mapping between human-readable names
  and the actual bit numbers

- the high-level defines are the mapping from high-level intent to
  combinations of low-level flags, representing roughly a tuple
  (data/code/tss, 64/32/16-bits) plus an override for DPL-3 (= USER),
  since that's relatively rare but still very important to mark
  properly for those segments.

- we have *_BIOS variants for 32-bit code and data segments that don't
  have the G flag set and give the limit in terms of bytes instead of
  pages

Link: https://lore.kernel.org/all/CAHk-=wib5XLebuEra7y2YH96wxdk=8vJnA8XoVq0FExpzVvN=Q@mail.gmail.com/
Signed-off-by: Vegard Nossum <vegard.nossum@...cle.com>
---
 arch/x86/include/asm/desc_defs.h | 66 ++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
index f7e7099af595..b33f5bb240eb 100644
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -8,6 +8,56 @@
  * archs.
  */
 
+/*
+ * Low-level interface mapping flags/field names to bits
+ */
+
+/* Flags for _DESC_S (non-system) descriptors */
+#define _DESC_ACCESSED		0x0001
+#define _DESC_DATA_WRITABLE	0x0002
+#define _DESC_CODE_READABLE	0x0002
+#define _DESC_DATA_EXPAND_DOWN	0x0004
+#define _DESC_CODE_CONFORMING	0x0004
+#define _DESC_CODE_EXECUTABLE	0x0008
+
+/* Common flags */
+#define _DESC_S			0x0010
+#define _DESC_DPL(dpl)		((dpl) << 5)
+#define _DESC_PRESENT		0x0080
+
+#define _DESC_LONG_CODE		0x2000
+#define _DESC_DB		0x4000
+#define _DESC_GRANULARITY_4K	0x8000
+
+/* System descriptors have a numeric "type" field instead of flags */
+#define _DESC_SYSTEM(code)	(code)
+
+/*
+ * High-level interface mapping intended usage to low-level combinations
+ * of flags
+ */
+
+#define _DESC_DATA		(_DESC_S | _DESC_PRESENT | \
+				 _DESC_DATA_WRITABLE)
+#define _DESC_CODE		(_DESC_S | _DESC_PRESENT | \
+				 _DESC_CODE_READABLE | _DESC_CODE_EXECUTABLE)
+
+#define DESC_DATA16		(_DESC_DATA)
+#define DESC_CODE16		(_DESC_CODE)
+
+#define DESC_DATA32		(_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB)
+#define DESC_DATA32_BIOS	(_DESC_DATA | _DESC_DB)
+
+#define DESC_CODE32		(_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_DB)
+#define DESC_CODE32_BIOS	(_DESC_CODE | _DESC_DB)
+
+#define DESC_TSS32		(_DESC_SYSTEM(9) | _DESC_PRESENT)
+
+#define DESC_DATA64		(_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB)
+#define DESC_CODE64		(_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_LONG_CODE)
+
+#define DESC_USER		(_DESC_DPL(3))
+
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
@@ -27,14 +77,14 @@ struct desc_struct {
 		.base0		= (u16) (base),			\
 		.base1		= ((base) >> 16) & 0xFF,	\
 		.base2		= ((base) >> 24) & 0xFF,	\
-		.type		= (flags & 0x0f),		\
-		.s		= (flags >> 4) & 0x01,		\
-		.dpl		= (flags >> 5) & 0x03,		\
-		.p		= (flags >> 7) & 0x01,		\
-		.avl		= (flags >> 12) & 0x01,		\
-		.l		= (flags >> 13) & 0x01,		\
-		.d		= (flags >> 14) & 0x01,		\
-		.g		= (flags >> 15) & 0x01,		\
+		.type		= ((flags) & 0x0f),		\
+		.s		= ((flags) >> 4) & 0x01,	\
+		.dpl		= ((flags) >> 5) & 0x03,	\
+		.p		= ((flags) >> 7) & 0x01,	\
+		.avl		= ((flags) >> 12) & 0x01,	\
+		.l		= ((flags) >> 13) & 0x01,	\
+		.d		= ((flags) >> 14) & 0x01,	\
+		.g		= ((flags) >> 15) & 0x01,	\
 	}
 
 enum {
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ