]>
Commit | Line | Data |
---|---|---|
321d628a FG |
1 | From 27298389d9d09bcebf06ea47206141b22fabcaca Mon Sep 17 00:00:00 2001 |
2 | From: Ingo Molnar <mingo@kernel.org> | |
3 | Date: Sat, 23 Dec 2017 13:14:25 +0100 | |
e4cdf2a5 | 4 | Subject: [PATCH 136/241] x86/insn-eval: Add utility functions to get segment |
321d628a FG |
5 | selector |
6 | MIME-Version: 1.0 | |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | CVE-2017-5754 | |
11 | ||
12 | When computing a linear address and segmentation is used, we need to know | |
13 | the base address of the segment involved in the computation. In most of | |
14 | the cases, the segment base address will be zero as in USER_DS/USER32_DS. | |
15 | However, it may be possible that a user space program defines its own | |
16 | segments via a local descriptor table. In such a case, the segment base | |
17 | address may not be zero. Thus, the segment base address is needed to | |
18 | calculate correctly the linear address. | |
19 | ||
20 | If running in protected mode, the segment selector to be used when | |
21 | computing a linear address is determined by either any of segment override | |
22 | prefixes in the instruction or inferred from the registers involved in the | |
23 | computation of the effective address; in that order. Also, there are cases | |
24 | when the segment override prefixes shall be ignored (i.e., code segments | |
25 | are always selected by the CS segment register; string instructions always | |
26 | use the ES segment register when using rDI register as operand). In long | |
27 | mode, segment registers are ignored, except for FS and GS. In these two | |
28 | cases, base addresses are obtained from the respective MSRs. | |
29 | ||
30 | For clarity, this process can be split into four steps (and an equal | |
31 | number of functions): determine if segment prefixes overrides can be used; | |
32 | parse the segment override prefixes, and use them if found; if not found | |
33 | or cannot be used, use the default segment registers associated with the | |
34 | operand registers. Once the segment register to use has been identified, | |
35 | read its value to obtain the segment selector. | |
36 | ||
37 | The method to obtain the segment selector depends on several factors. In | |
38 | 32-bit builds, segment selectors are saved into a pt_regs structure | |
39 | when switching to kernel mode. The same is also true for virtual-8086 | |
40 | mode. In 64-bit builds, segmentation is mostly ignored, except when | |
41 | running a program in 32-bit legacy mode. In this case, CS and SS can be | |
42 | obtained from pt_regs. DS, ES, FS and GS can be read directly from | |
43 | the respective segment registers. | |
44 | ||
45 | In order to identify the segment registers, a new set of #defines is | |
46 | introduced. It also includes two special identifiers. One of them | |
47 | indicates when the default segment register associated with instruction | |
48 | operands shall be used. Another one indicates that the contents of the | |
49 | segment register shall be ignored; this identifier is used when in long | |
50 | mode. | |
51 | ||
52 | Improvements-by: Borislav Petkov <bp@suse.de> | |
53 | Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> | |
54 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
55 | Reviewed-by: Borislav Petkov <bp@suse.de> | |
56 | Cc: "Michael S. Tsirkin" <mst@redhat.com> | |
57 | Cc: Peter Zijlstra <peterz@infradead.org> | |
58 | Cc: Dave Hansen <dave.hansen@linux.intel.com> | |
59 | Cc: ricardo.neri@intel.com | |
60 | Cc: Adrian Hunter <adrian.hunter@intel.com> | |
61 | Cc: Paul Gortmaker <paul.gortmaker@windriver.com> | |
62 | Cc: Huang Rui <ray.huang@amd.com> | |
63 | Cc: Qiaowei Ren <qiaowei.ren@intel.com> | |
64 | Cc: Shuah Khan <shuah@kernel.org> | |
65 | Cc: Kees Cook <keescook@chromium.org> | |
66 | Cc: Jonathan Corbet <corbet@lwn.net> | |
67 | Cc: Jiri Slaby <jslaby@suse.cz> | |
68 | Cc: Dmitry Vyukov <dvyukov@google.com> | |
69 | Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com> | |
70 | Cc: Chris Metcalf <cmetcalf@mellanox.com> | |
71 | Cc: Brian Gerst <brgerst@gmail.com> | |
72 | Cc: Arnaldo Carvalho de Melo <acme@redhat.com> | |
73 | Cc: Andy Lutomirski <luto@kernel.org> | |
74 | Cc: Colin Ian King <colin.king@canonical.com> | |
75 | Cc: Chen Yucong <slaoub@gmail.com> | |
76 | Cc: Adam Buchbinder <adam.buchbinder@gmail.com> | |
77 | Cc: Vlastimil Babka <vbabka@suse.cz> | |
78 | Cc: Lorenzo Stoakes <lstoakes@gmail.com> | |
79 | Cc: Masami Hiramatsu <mhiramat@kernel.org> | |
80 | Cc: Paolo Bonzini <pbonzini@redhat.com> | |
81 | Cc: Andrew Morton <akpm@linux-foundation.org> | |
82 | Cc: Thomas Garnier <thgarnie@google.com> | |
83 | Link: https://lkml.kernel.org/r/1509135945-13762-14-git-send-email-ricardo.neri-calderon@linux.intel.com | |
84 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
85 | ||
86 | (Partially cherry picked from commit 32d0b95300db03c2b23b2ea2c94769a4a138e79d) | |
87 | ||
88 | (cherry picked from commit ca2c18cb10c8beb56dfe21321abdddc724cec4de) | |
89 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
90 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
91 | (cherry picked from commit abd7780592a3687eacc0a295d4d2959bb11ff75f) | |
92 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
93 | --- | |
94 | arch/x86/include/asm/inat.h | 10 ++++++++++ | |
95 | 1 file changed, 10 insertions(+) | |
96 | ||
97 | diff --git a/arch/x86/include/asm/inat.h b/arch/x86/include/asm/inat.h | |
98 | index 02aff0867211..1c78580e58be 100644 | |
99 | --- a/arch/x86/include/asm/inat.h | |
100 | +++ b/arch/x86/include/asm/inat.h | |
101 | @@ -97,6 +97,16 @@ | |
102 | #define INAT_MAKE_GROUP(grp) ((grp << INAT_GRP_OFFS) | INAT_MODRM) | |
103 | #define INAT_MAKE_IMM(imm) (imm << INAT_IMM_OFFS) | |
104 | ||
105 | +/* Identifiers for segment registers */ | |
106 | +#define INAT_SEG_REG_IGNORE 0 | |
107 | +#define INAT_SEG_REG_DEFAULT 1 | |
108 | +#define INAT_SEG_REG_CS 2 | |
109 | +#define INAT_SEG_REG_SS 3 | |
110 | +#define INAT_SEG_REG_DS 4 | |
111 | +#define INAT_SEG_REG_ES 5 | |
112 | +#define INAT_SEG_REG_FS 6 | |
113 | +#define INAT_SEG_REG_GS 7 | |
114 | + | |
115 | /* Attribute search APIs */ | |
116 | extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); | |
117 | extern int inat_get_last_prefix_id(insn_byte_t last_pfx); | |
118 | -- | |
119 | 2.14.2 | |
120 |