On Fri, 04 Dec 2020 15:04:03 -0000 "tip-bot2 for Masami Hiramatsu" <tip-bot2@xxxxxxxxxxxxx> wrote: > The following commit has been merged into the x86/urgent branch of tip: > > Commit-ID: 9dc23f960adb9ce410ef835b32a2398fdb09c828 > Gitweb: https://git.kernel.org/tip/9dc23f960adb9ce410ef835b32a2398fdb09c828 > Author: Masami Hiramatsu <mhiramat@xxxxxxxxxx> > AuthorDate: Thu, 03 Dec 2020 13:50:37 +09:00 > Committer: Borislav Petkov <bp@xxxxxxx> > CommitterDate: Fri, 04 Dec 2020 14:32:57 +01:00 > > x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes > > 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 <keescook@xxxxxxxxxxxx>. > > [ 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@xxxxxxxxxxxxxxxxxxxxxxxxx > Signed-off-by: Masami Hiramatsu <mhiramat@xxxxxxxxxx> > Signed-off-by: Borislav Petkov <bp@xxxxxxx> > Reviewed-by: Srikar Dronamraju <srikar@xxxxxxxxxxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > Link: https://lkml.kernel.org/r/160697103739.3146288.7437620795200799020.stgit@devnote2 > --- > arch/x86/include/asm/insn.h | 15 +++++++++++++++ > arch/x86/kernel/uprobes.c | 10 ++++++---- > tools/arch/x86/include/asm/insn.h | 17 ++++++++++++++++- > 3 files changed, 37 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/include/asm/insn.h b/arch/x86/include/asm/insn.h > index 5c1ae3e..a8c3d28 100644 > --- a/arch/x86/include/asm/insn.h > +++ b/arch/x86/include/asm/insn.h > @@ -201,6 +201,21 @@ static inline int insn_offset_immediate(struct insn *insn) > 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 > > diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c > index 3fdaa04..138bdb1 100644 > --- a/arch/x86/kernel/uprobes.c > +++ b/arch/x86/kernel/uprobes.c > @@ -255,12 +255,13 @@ static volatile u32 good_2byte_insns[256 / 32] = { > > 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): > @@ -715,6 +716,7 @@ static const struct uprobe_xol_ops push_xol_ops = { > 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) { > @@ -746,8 +748,8 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) > * 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; > } > > diff --git a/tools/arch/x86/include/asm/insn.h b/tools/arch/x86/include/asm/insn.h > index 568854b..a8c3d28 100644 > --- a/tools/arch/x86/include/asm/insn.h > +++ b/tools/arch/x86/include/asm/insn.h > @@ -8,7 +8,7 @@ > */ > > /* insn_attr_t is defined in inat.h */ > -#include "inat.h" > +#include <asm/inat.h> This may break tools/objtool build. Please keep "inat.h". Thank you, -- Masami Hiramatsu <mhiramat@xxxxxxxxxx>