0136-x86-insn-eval-Add-utility-functions-to-get-segment-s.patch 5.3 KB

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