Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1715531

[PATCH v8 13/28] x86/insn-eval: Add utility function to get segment descriptor

From Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Newsgroups linux.kernel
Subject [PATCH v8 13/28] x86/insn-eval: Add utility function to get segment descriptor
Date 2017-08-19 02:40 +0200
Message-ID <ufZXX-2C3-13@gated-at.bofh.it> (permalink)
References <ufZOh-2z5-3@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


The segment descriptor contains information that is relevant to how linear
addresses need to be computed. It contains the default size of addresses
as well as the base address of the segment. Thus, given a segment
selector, we ought look at segment descriptor to correctly calculate the
linear address.

In protected mode, the segment selector might indicate a segment
descriptor from either the global descriptor table or a local descriptor
table. Both cases are considered in this function.

This function is a prerequisite for functions in subsequent commits that
will obtain the aforementioned attributes of the segment descriptor.

Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Adam Buchbinder <adam.buchbinder@gmail.com>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Lorenzo Stoakes <lstoakes@gmail.com>
Cc: Qiaowei Ren <qiaowei.ren@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Thomas Garnier <thgarnie@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Ravi V. Shankar <ravi.v.shankar@intel.com>
Cc: x86@kernel.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
 arch/x86/lib/insn-eval.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/x86/lib/insn-eval.c b/arch/x86/lib/insn-eval.c
index 86f58ce6c302..9cf2c49afc15 100644
--- a/arch/x86/lib/insn-eval.c
+++ b/arch/x86/lib/insn-eval.c
@@ -6,9 +6,13 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/ratelimit.h>
+#include <linux/mmu_context.h>
+#include <asm/desc_defs.h>
+#include <asm/desc.h>
 #include <asm/inat.h>
 #include <asm/insn.h>
 #include <asm/insn-eval.h>
+#include <asm/ldt.h>
 #include <asm/vm86.h>
 
 enum reg_type {
@@ -402,6 +406,57 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
 }
 
 /**
+ * get_desc() - Obtain address of segment descriptor
+ * @sel:	Segment selector
+ *
+ * Given a segment selector, obtain a pointer to the segment descriptor.
+ * Both global and local descriptor tables are supported.
+ *
+ * Return: pointer to segment descriptor on success. NULL on error.
+ */
+static struct desc_struct *get_desc(unsigned short sel)
+{
+	struct desc_ptr gdt_desc = {0, 0};
+	struct desc_struct *desc = NULL;
+	unsigned long desc_base;
+
+#ifdef CONFIG_MODIFY_LDT_SYSCALL
+	if ((sel & SEGMENT_TI_MASK) == SEGMENT_LDT) {
+		/* Bits [15:3] contain the index of the desired entry. */
+		sel >>= 3;
+
+		mutex_lock(&current->active_mm->context.lock);
+		/* The size of the LDT refers to the number of entries. */
+		if (!current->active_mm->context.ldt ||
+		    sel >= current->active_mm->context.ldt->nr_entries) {
+			mutex_unlock(&current->active_mm->context.lock);
+			return NULL;
+		}
+
+		desc = &current->active_mm->context.ldt->entries[sel];
+		mutex_unlock(&current->active_mm->context.lock);
+		return desc;
+	}
+#endif
+	native_store_gdt(&gdt_desc);
+
+	/*
+	 * Segment descriptors have a size of 8 bytes. Thus, the index is
+	 * multiplied by 8 to obtain the memory offset of the desired descriptor
+	 * from the base of the GDT. As bits [15:3] of the segment selector
+	 * contain the index, it can be regarded as multiplied by 8 already.
+	 * All that remains is to clear bits [2:0].
+	 */
+	desc_base = sel & ~(SEGMENT_RPL_MASK | SEGMENT_TI_MASK);
+
+	if (desc_base > gdt_desc.size)
+		return NULL;
+
+	desc = (struct desc_struct *)(gdt_desc.address + desc_base);
+	return desc;
+}
+
+/**
  * insn_get_modrm_rm_off() - Obtain register in r/m part of ModRM byte
  * @insn:	Instruction structure containing the ModRM byte
  * @regs:	Structure with register values as seen when entering kernel mode
-- 
2.13.0

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v8 00/28] x86: Enable User-Mode Instruction Prevention Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:30 +0200
  [PATCH v8 18/28] x86/insn-eval: Add support to resolve 32-bit address encodings Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:30 +0200
  [PATCH v8 04/28] uprobes/x86: Use existing definitions for segment override prefixes Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:30 +0200
  [PATCH v8 17/28] x86/insn-eval: Incorporate segment base in linear address computation Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:30 +0200
  [PATCH v8 08/28] x86/mpx, x86/insn: Relocate insn util functions to a new insn-eval file Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:30 +0200
  [PATCH v8 10/28] x86/insn-eval: Add a utility function to get register offsets Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:30 +0200
  [PATCH v8 19/28] x86/insn-eval: Add wrapper function for 32 and 64-bit addresses Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 20/28] x86/insn-eval: Handle 32-bit address encodings in virtual-8086 mode Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 15/28] x86/insn-eval: Add function to get default params of code segment Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 05/28] x86/mpx: Use signed variables to compute effective addresses Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 16/28] x86/insn-eval: Indicate a 32-bit displacement if ModRM.mod is 0 and ModRM.rm is 101b Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 13/28] x86/insn-eval: Add utility function to get segment descriptor Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 03/28] ptrace,x86: Make user_64bit_mode() available to 32-bit builds Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 23/28] x86: Add emulation code for UMIP instructions Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 28/28] selftests/x86: Add tests for instruction str and sldt Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 21/28] x86/insn-eval: Add support to resolve 16-bit addressing encodings Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 12/28] x86/insn-eval: Add utility functions to get segment selector Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 01/28] x86/mm: Relocate page fault error codes to traps.h Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 27/28] selftests/x86: Add tests for User-Mode Instruction Prevention Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 24/28] x86/umip: Force a page fault when unable to copy emulated result to user Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 26/28] x86/traps: Fixup general protection faults caused by UMIP Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 07/28] x86/mpx: Do not use SIB.base if its value is 101b and ModRM.mod = 0 Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 22/28] x86/cpufeature: Add User-Mode Instruction Prevention definitions Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 06/28] x86/mpx: Do not use SIB.index if its value is 100b and ModRM.mod is not 11b Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 14/28] x86/insn-eval: Add utility functions to get segment descriptor base address and limit Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 25/28] x86: Enable User-Mode Instruction Prevention Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200
  [PATCH v8 09/28] x86/insn-eval: Do not BUG on invalid register type Ricardo Neri <ricardo.neri-calderon@linux.intel.com> - 2017-08-19 02:40 +0200

csiph-web