a0f7ab8a6a
cherry-pick from upstream 4.14
119 lines
5.2 KiB
Diff
119 lines
5.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Ingo Molnar <mingo@kernel.org>
|
|
Date: Sat, 23 Dec 2017 13:14:25 +0100
|
|
Subject: [PATCH] x86/insn-eval: Add utility functions to get segment selector
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
CVE-2017-5754
|
|
|
|
When computing a linear address and segmentation is used, we need to know
|
|
the base address of the segment involved in the computation. In most of
|
|
the cases, the segment base address will be zero as in USER_DS/USER32_DS.
|
|
However, it may be possible that a user space program defines its own
|
|
segments via a local descriptor table. In such a case, the segment base
|
|
address may not be zero. Thus, the segment base address is needed to
|
|
calculate correctly the linear address.
|
|
|
|
If running in protected mode, the segment selector to be used when
|
|
computing a linear address is determined by either any of segment override
|
|
prefixes in the instruction or inferred from the registers involved in the
|
|
computation of the effective address; in that order. Also, there are cases
|
|
when the segment override prefixes shall be ignored (i.e., code segments
|
|
are always selected by the CS segment register; string instructions always
|
|
use the ES segment register when using rDI register as operand). In long
|
|
mode, segment registers are ignored, except for FS and GS. In these two
|
|
cases, base addresses are obtained from the respective MSRs.
|
|
|
|
For clarity, this process can be split into four steps (and an equal
|
|
number of functions): determine if segment prefixes overrides can be used;
|
|
parse the segment override prefixes, and use them if found; if not found
|
|
or cannot be used, use the default segment registers associated with the
|
|
operand registers. Once the segment register to use has been identified,
|
|
read its value to obtain the segment selector.
|
|
|
|
The method to obtain the segment selector depends on several factors. In
|
|
32-bit builds, segment selectors are saved into a pt_regs structure
|
|
when switching to kernel mode. The same is also true for virtual-8086
|
|
mode. In 64-bit builds, segmentation is mostly ignored, except when
|
|
running a program in 32-bit legacy mode. In this case, CS and SS can be
|
|
obtained from pt_regs. DS, ES, FS and GS can be read directly from
|
|
the respective segment registers.
|
|
|
|
In order to identify the segment registers, a new set of #defines is
|
|
introduced. It also includes two special identifiers. One of them
|
|
indicates when the default segment register associated with instruction
|
|
operands shall be used. Another one indicates that the contents of the
|
|
segment register shall be ignored; this identifier is used when in long
|
|
mode.
|
|
|
|
Improvements-by: Borislav Petkov <bp@suse.de>
|
|
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Reviewed-by: Borislav Petkov <bp@suse.de>
|
|
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
|
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
Cc: Dave Hansen <dave.hansen@linux.intel.com>
|
|
Cc: ricardo.neri@intel.com
|
|
Cc: Adrian Hunter <adrian.hunter@intel.com>
|
|
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
|
|
Cc: Huang Rui <ray.huang@amd.com>
|
|
Cc: Qiaowei Ren <qiaowei.ren@intel.com>
|
|
Cc: Shuah Khan <shuah@kernel.org>
|
|
Cc: Kees Cook <keescook@chromium.org>
|
|
Cc: Jonathan Corbet <corbet@lwn.net>
|
|
Cc: Jiri Slaby <jslaby@suse.cz>
|
|
Cc: Dmitry Vyukov <dvyukov@google.com>
|
|
Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
|
|
Cc: Chris Metcalf <cmetcalf@mellanox.com>
|
|
Cc: Brian Gerst <brgerst@gmail.com>
|
|
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Cc: Andy Lutomirski <luto@kernel.org>
|
|
Cc: Colin Ian King <colin.king@canonical.com>
|
|
Cc: Chen Yucong <slaoub@gmail.com>
|
|
Cc: Adam Buchbinder <adam.buchbinder@gmail.com>
|
|
Cc: Vlastimil Babka <vbabka@suse.cz>
|
|
Cc: Lorenzo Stoakes <lstoakes@gmail.com>
|
|
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
|
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
|
Cc: Andrew Morton <akpm@linux-foundation.org>
|
|
Cc: Thomas Garnier <thgarnie@google.com>
|
|
Link: https://lkml.kernel.org/r/1509135945-13762-14-git-send-email-ricardo.neri-calderon@linux.intel.com
|
|
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
|
|
(Partially cherry picked from commit 32d0b95300db03c2b23b2ea2c94769a4a138e79d)
|
|
|
|
(cherry picked from commit ca2c18cb10c8beb56dfe21321abdddc724cec4de)
|
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
|
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
|
|
(cherry picked from commit abd7780592a3687eacc0a295d4d2959bb11ff75f)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
arch/x86/include/asm/inat.h | 10 ++++++++++
|
|
1 file changed, 10 insertions(+)
|
|
|
|
diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h
|
|
index 02aff0867211..1c78580e58be 100644
|
|
--- a/arch/x86/include/asm/inat.h
|
|
+++ b/arch/x86/include/asm/inat.h
|
|
@@ -97,6 +97,16 @@
|
|
#define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM)
|
|
#define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS)
|
|
|
|
+/* Identifiers for segment registers */
|
|
+#define INAT_SEG_REG_IGNORE 0
|
|
+#define INAT_SEG_REG_DEFAULT 1
|
|
+#define INAT_SEG_REG_CS 2
|
|
+#define INAT_SEG_REG_SS 3
|
|
+#define INAT_SEG_REG_DS 4
|
|
+#define INAT_SEG_REG_ES 5
|
|
+#define INAT_SEG_REG_FS 6
|
|
+#define INAT_SEG_REG_GS 7
|
|
+
|
|
/* Attribute search APIs */
|
|
extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
|
|
extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
|
|
--
|
|
2.14.2
|
|
|