FAILED: patch "[PATCH] x86/uprobes: Do not use prefixes.nbytes when looping over" failed to apply to 4.14-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4e9a5ae8df5b3365183150f6df49e49dece80d8c Mon Sep 17 00:00:00 2001
From: Masami Hiramatsu <[email protected]>
Date: Thu, 3 Dec 2020 13:50:37 +0900
Subject: [PATCH] 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 <[email protected]>.
[ bp: Massage commit message, sync with the respective header in tools/
and drop "we". ]
arch/x86/include/asm/insn.h +15 -0
@@ -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
arch/x86/kernel/uprobes.c +6 -4
@@ -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 ; }
tools/arch/x86/include/asm/insn.h +15 -0
@@ -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
Sudip Mukherjee
Reviewed-by Srikar DronamrajuHi Greg,
Quoted 5 lines · On Wed, Dec 09, 2020 at 10:34:09AM +0100, [email protected] wrote:
The patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Here is the backport.
--
Regards
Sudip
From a5827defc6d1f74b0ea6824b27e4f90c4e4ae387 Mon Sep 17 00:00:00 2001
From: Masami Hiramatsu <[email protected]>
Date: Thu, 3 Dec 2020 13:50:37 +0900
Subject: [PATCH] x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes
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 <[email protected]>.
[ bp: Massage commit message, sync with the respective header in tools/
and drop "we". ]
--- arch/x86/include/asm/insn.h | 15 +++++++++++++++ arch/x86/kernel/uprobes.c | 10 ++++++---- tools/objtool/arch/x86/include/asm/insn.h | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-)
arch/x86/include/asm/insn.h +15 -0
@@ -208,6 +208,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
arch/x86/kernel/uprobes.c +6 -4
@@ -268,10 +268,11 @@ 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++) { -switch (insn->prefixes.bytes[i]) { +for_each_insn_prefix (insn, i, p) { +switch (p) {case 0x26 :/* INAT_PFX_ES */ case 0x2E :/* INAT_PFX_CS */ case 0x36 :/* INAT_PFX_DS */
@@ -711,6 +712,7 @@ static const struct uprobe_xol_ops branch_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) {
@@ -741,8 +743,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 ; }
tools/objtool/arch/x86/include/asm/insn.h +15 -0
@@ -208,6 +208,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
Signature · 1 line
2.11.0