From 04090c311005774b77922351553bea6997f02025 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Dec 2020 10:57:47 +0100 Subject: [PATCH] 4.19-stable patches added patches: x86-uprobes-do-not-use-prefixes.nbytes-when-looping-over-prefixes.bytes.patch --- queue-4.19/series | 1 + ...tes-when-looping-over-prefixes.bytes.patch | 148 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 queue-4.19/x86-uprobes-do-not-use-prefixes.nbytes-when-looping-over-prefixes.bytes.patch diff --git a/queue-4.19/series b/queue-4.19/series index eea6879cc27..1bc7a1ec9b6 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -21,3 +21,4 @@ dm-writecache-fix-the-maximum-number-of-arguments.patch dm-remove-invalid-sparse-__acquires-and-__releases-annotations.patch mm-list_lru-set-shrinker-map-bit-when-child-nr_items-is-not-zero.patch mm-swapfile-do-not-sleep-with-a-spin-lock-held.patch +x86-uprobes-do-not-use-prefixes.nbytes-when-looping-over-prefixes.bytes.patch diff --git a/queue-4.19/x86-uprobes-do-not-use-prefixes.nbytes-when-looping-over-prefixes.bytes.patch b/queue-4.19/x86-uprobes-do-not-use-prefixes.nbytes-when-looping-over-prefixes.bytes.patch new file mode 100644 index 00000000000..578e9b59903 --- /dev/null +++ b/queue-4.19/x86-uprobes-do-not-use-prefixes.nbytes-when-looping-over-prefixes.bytes.patch @@ -0,0 +1,148 @@ +From 4e9a5ae8df5b3365183150f6df49e49dece80d8c Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Thu, 3 Dec 2020 13:50:37 +0900 +Subject: x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes + +From: Masami Hiramatsu + +commit 4e9a5ae8df5b3365183150f6df49e49dece80d8c upstream. + +Since insn.prefixes.nbytes can be bigger than the size of +insn.prefixes.bytes[] when a prefix is repeated, the proper check must +be + + insn.prefixes.bytes[i] != 0 and i < 4 + +instead of using insn.prefixes.nbytes. + +Introduce a for_each_insn_prefix() macro for this purpose. Debugged by +Kees Cook . + + [ bp: Massage commit message, sync with the respective header in tools/ + and drop "we". ] + +Fixes: 2b1444983508 ("uprobes, mm, x86: Add the ability to install and remove uprobes breakpoints") +Reported-by: syzbot+9b64b619f10f19d19a7c@syzkaller.appspotmail.com +Signed-off-by: Masami Hiramatsu +Signed-off-by: Borislav Petkov +Reviewed-by: Srikar Dronamraju +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/160697103739.3146288.7437620795200799020.stgit@devnote2 +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/insn.h | 15 +++++++++++++++ + arch/x86/kernel/uprobes.c | 10 ++++++---- + tools/objtool/arch/x86/include/asm/insn.h | 15 +++++++++++++++ + tools/perf/util/intel-pt-decoder/insn.h | 15 +++++++++++++++ + 4 files changed, 51 insertions(+), 4 deletions(-) + +--- a/arch/x86/include/asm/insn.h ++++ b/arch/x86/include/asm/insn.h +@@ -208,6 +208,21 @@ static inline int insn_offset_immediate( + return insn_offset_displacement(insn) + insn->displacement.nbytes; + } + ++/** ++ * for_each_insn_prefix() -- Iterate prefixes in the instruction ++ * @insn: Pointer to struct insn. ++ * @idx: Index storage. ++ * @prefix: Prefix byte. ++ * ++ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix ++ * and the index is stored in @idx (note that this @idx is just for a cursor, ++ * do not change it.) ++ * Since prefixes.nbytes can be bigger than 4 if some prefixes ++ * are repeated, it cannot be used for looping over the prefixes. ++ */ ++#define for_each_insn_prefix(insn, idx, prefix) \ ++ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) ++ + #define POP_SS_OPCODE 0x1f + #define MOV_SREG_OPCODE 0x8e + +--- a/arch/x86/kernel/uprobes.c ++++ b/arch/x86/kernel/uprobes.c +@@ -268,12 +268,13 @@ static volatile u32 good_2byte_insns[256 + + static bool is_prefix_bad(struct insn *insn) + { ++ insn_byte_t p; + int i; + +- for (i = 0; i < insn->prefixes.nbytes; i++) { ++ for_each_insn_prefix(insn, i, p) { + insn_attr_t attr; + +- attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]); ++ attr = inat_get_opcode_attribute(p); + switch (attr) { + case INAT_MAKE_PREFIX(INAT_PFX_ES): + case INAT_MAKE_PREFIX(INAT_PFX_CS): +@@ -728,6 +729,7 @@ static const struct uprobe_xol_ops push_ + static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) + { + u8 opc1 = OPCODE1(insn); ++ insn_byte_t p; + int i; + + switch (opc1) { +@@ -758,8 +760,8 @@ static int branch_setup_xol_ops(struct a + * Intel and AMD behavior differ in 64-bit mode: Intel ignores 66 prefix. + * No one uses these insns, reject any branch insns with such prefix. + */ +- for (i = 0; i < insn->prefixes.nbytes; i++) { +- if (insn->prefixes.bytes[i] == 0x66) ++ for_each_insn_prefix(insn, i, p) { ++ if (p == 0x66) + return -ENOTSUPP; + } + +--- a/tools/objtool/arch/x86/include/asm/insn.h ++++ b/tools/objtool/arch/x86/include/asm/insn.h +@@ -208,6 +208,21 @@ static inline int insn_offset_immediate( + return insn_offset_displacement(insn) + insn->displacement.nbytes; + } + ++/** ++ * for_each_insn_prefix() -- Iterate prefixes in the instruction ++ * @insn: Pointer to struct insn. ++ * @idx: Index storage. ++ * @prefix: Prefix byte. ++ * ++ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix ++ * and the index is stored in @idx (note that this @idx is just for a cursor, ++ * do not change it.) ++ * Since prefixes.nbytes can be bigger than 4 if some prefixes ++ * are repeated, it cannot be used for looping over the prefixes. ++ */ ++#define for_each_insn_prefix(insn, idx, prefix) \ ++ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) ++ + #define POP_SS_OPCODE 0x1f + #define MOV_SREG_OPCODE 0x8e + +--- a/tools/perf/util/intel-pt-decoder/insn.h ++++ b/tools/perf/util/intel-pt-decoder/insn.h +@@ -208,6 +208,21 @@ static inline int insn_offset_immediate( + return insn_offset_displacement(insn) + insn->displacement.nbytes; + } + ++/** ++ * for_each_insn_prefix() -- Iterate prefixes in the instruction ++ * @insn: Pointer to struct insn. ++ * @idx: Index storage. ++ * @prefix: Prefix byte. ++ * ++ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix ++ * and the index is stored in @idx (note that this @idx is just for a cursor, ++ * do not change it.) ++ * Since prefixes.nbytes can be bigger than 4 if some prefixes ++ * are repeated, it cannot be used for looping over the prefixes. ++ */ ++#define for_each_insn_prefix(insn, idx, prefix) \ ++ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) ++ + #define POP_SS_OPCODE 0x1f + #define MOV_SREG_OPCODE 0x8e + -- 2.47.3