All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns
@ 2014-04-24 17:08 Denys Vlasenko
  2014-04-24 17:33 ` Oleg Nesterov
  0 siblings, 1 reply; 4+ messages in thread
From: Denys Vlasenko @ 2014-04-24 17:08 UTC (permalink / raw)
  To: linux-kernel; +Cc: Denys Vlasenko, Oleg Nesterov

All branch insns on x86 can be prefixed with the operand-size
override prefix, 0x66. It was only ever useful for performing
jumps to 32-bit offsets in 16-bit code segments.

In 32-bit code, such instructions are useless since
they cause IP truncation to 16 bits, and in case of call insns,
they save only 16 bits of return address and misalign
the stack pointer as a "bonus".

In 64-bit code, such instructions are treated differently by Intel
and AMD CPUs: Intel ignores the prefix altogether,
AMD treats them the same as in 32-bit mode.

Before this patch, the emulation code would execute
the instructions as if they have no 0x66 prefix.

With this patch, we refuse to attach uprobes to such insns.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Oleg Nesterov <oleg@redhat.com>
---
 arch/x86/kernel/uprobes.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index ace2291..29b152d 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -582,6 +582,7 @@ static struct uprobe_xol_ops branch_xol_ops = {
 /* Returns -ENOSYS if branch_xol_ops doesn't handle this insn */
 static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
 {
+	int i;
 	u8 opc1 = OPCODE1(insn);
 
 	/* has the side-effect of processing the entire instruction */
@@ -612,6 +613,17 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
 			return -ENOSYS;
 	}
 
+	/*
+	 * 16-bit overrides such as CALLW (66 e8 nn nn) are not supported.
+	 * 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)
+			return -ENOTSUPP;
+	}
+
 	auprobe->branch.opc1 = opc1;
 	auprobe->branch.ilen = insn->length;
 	auprobe->branch.offs = insn->immediate.value;
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns
  2014-04-24 17:08 [PATCH] uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns Denys Vlasenko
@ 2014-04-24 17:33 ` Oleg Nesterov
  2014-04-25  0:28   ` Jim Keniston
  2014-04-25  3:23   ` Masami Hiramatsu
  0 siblings, 2 replies; 4+ messages in thread
From: Oleg Nesterov @ 2014-04-24 17:33 UTC (permalink / raw)
  To: Denys Vlasenko; +Cc: linux-kernel, Masami Hiramatsu, Jim Keniston, Ingo Molnar

Thanks!

Masami, Jim, any acks?

On 04/24, Denys Vlasenko wrote:
>
> All branch insns on x86 can be prefixed with the operand-size
> override prefix, 0x66. It was only ever useful for performing
> jumps to 32-bit offsets in 16-bit code segments.
>
> In 32-bit code, such instructions are useless since
> they cause IP truncation to 16 bits, and in case of call insns,
> they save only 16 bits of return address and misalign
> the stack pointer as a "bonus".
>
> In 64-bit code, such instructions are treated differently by Intel
> and AMD CPUs: Intel ignores the prefix altogether,
> AMD treats them the same as in 32-bit mode.
>
> Before this patch, the emulation code would execute
> the instructions as if they have no 0x66 prefix.
>
> With this patch, we refuse to attach uprobes to such insns.
>
> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
> Cc: Oleg Nesterov <oleg@redhat.com>
> ---
>  arch/x86/kernel/uprobes.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index ace2291..29b152d 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -582,6 +582,7 @@ static struct uprobe_xol_ops branch_xol_ops = {
>  /* Returns -ENOSYS if branch_xol_ops doesn't handle this insn */
>  static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
>  {
> +	int i;
>  	u8 opc1 = OPCODE1(insn);
>
>  	/* has the side-effect of processing the entire instruction */
> @@ -612,6 +613,17 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
>  			return -ENOSYS;
>  	}
>
> +	/*
> +	 * 16-bit overrides such as CALLW (66 e8 nn nn) are not supported.
> +	 * 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)
> +			return -ENOTSUPP;
> +	}
> +
>  	auprobe->branch.opc1 = opc1;
>  	auprobe->branch.ilen = insn->length;
>  	auprobe->branch.offs = insn->immediate.value;
> --
> 1.8.1.4
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns
  2014-04-24 17:33 ` Oleg Nesterov
@ 2014-04-25  0:28   ` Jim Keniston
  2014-04-25  3:23   ` Masami Hiramatsu
  1 sibling, 0 replies; 4+ messages in thread
From: Jim Keniston @ 2014-04-25  0:28 UTC (permalink / raw)
  To: Oleg Nesterov; +Cc: Denys Vlasenko, linux-kernel, Masami Hiramatsu, Ingo Molnar

On Thu, 2014-04-24 at 19:33 +0200, Oleg Nesterov wrote:
> Thanks!
> 
> Masami, Jim, any acks?

Acked-by: Jim Keniston <jkenisto@us.ibm.com>

> 
> On 04/24, Denys Vlasenko wrote:
> >
> > All branch insns on x86 can be prefixed with the operand-size
> > override prefix, 0x66. It was only ever useful for performing
> > jumps to 32-bit offsets in 16-bit code segments.
> >
> > In 32-bit code, such instructions are useless since
> > they cause IP truncation to 16 bits, and in case of call insns,
> > they save only 16 bits of return address and misalign
> > the stack pointer as a "bonus".
> >
> > In 64-bit code, such instructions are treated differently by Intel
> > and AMD CPUs: Intel ignores the prefix altogether,
> > AMD treats them the same as in 32-bit mode.
> >
> > Before this patch, the emulation code would execute
> > the instructions as if they have no 0x66 prefix.
> >
> > With this patch, we refuse to attach uprobes to such insns.
> >
> > Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
> > Cc: Oleg Nesterov <oleg@redhat.com>
> > ---
> >  arch/x86/kernel/uprobes.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> > index ace2291..29b152d 100644
> > --- a/arch/x86/kernel/uprobes.c
> > +++ b/arch/x86/kernel/uprobes.c
> > @@ -582,6 +582,7 @@ static struct uprobe_xol_ops branch_xol_ops = {
> >  /* Returns -ENOSYS if branch_xol_ops doesn't handle this insn */
> >  static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
> >  {
> > +	int i;
> >  	u8 opc1 = OPCODE1(insn);
> >
> >  	/* has the side-effect of processing the entire instruction */
> > @@ -612,6 +613,17 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
> >  			return -ENOSYS;
> >  	}
> >
> > +	/*
> > +	 * 16-bit overrides such as CALLW (66 e8 nn nn) are not supported.
> > +	 * 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)
> > +			return -ENOTSUPP;
> > +	}
> > +
> >  	auprobe->branch.opc1 = opc1;
> >  	auprobe->branch.ilen = insn->length;
> >  	auprobe->branch.offs = insn->immediate.value;
> > --
> > 1.8.1.4
> >
> 



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Re: [PATCH] uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns
  2014-04-24 17:33 ` Oleg Nesterov
  2014-04-25  0:28   ` Jim Keniston
@ 2014-04-25  3:23   ` Masami Hiramatsu
  1 sibling, 0 replies; 4+ messages in thread
From: Masami Hiramatsu @ 2014-04-25  3:23 UTC (permalink / raw)
  To: Oleg Nesterov; +Cc: Denys Vlasenko, linux-kernel, Jim Keniston, Ingo Molnar

(2014/04/25 2:33), Oleg Nesterov wrote:
> Thanks!
> 
> Masami, Jim, any acks?
> 
> On 04/24, Denys Vlasenko wrote:
>>
>> All branch insns on x86 can be prefixed with the operand-size
>> override prefix, 0x66. It was only ever useful for performing
>> jumps to 32-bit offsets in 16-bit code segments.
>>
>> In 32-bit code, such instructions are useless since
>> they cause IP truncation to 16 bits, and in case of call insns,
>> they save only 16 bits of return address and misalign
>> the stack pointer as a "bonus".
>>
>> In 64-bit code, such instructions are treated differently by Intel
>> and AMD CPUs: Intel ignores the prefix altogether,
>> AMD treats them the same as in 32-bit mode.
>>
>> Before this patch, the emulation code would execute
>> the instructions as if they have no 0x66 prefix.
>>
>> With this patch, we refuse to attach uprobes to such insns.
>>
>> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
>> Cc: Oleg Nesterov <oleg@redhat.com>

Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

Thank you :)

>> ---
>>  arch/x86/kernel/uprobes.c | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
>> index ace2291..29b152d 100644
>> --- a/arch/x86/kernel/uprobes.c
>> +++ b/arch/x86/kernel/uprobes.c
>> @@ -582,6 +582,7 @@ static struct uprobe_xol_ops branch_xol_ops = {
>>  /* Returns -ENOSYS if branch_xol_ops doesn't handle this insn */
>>  static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
>>  {
>> +	int i;
>>  	u8 opc1 = OPCODE1(insn);
>>
>>  	/* has the side-effect of processing the entire instruction */
>> @@ -612,6 +613,17 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
>>  			return -ENOSYS;
>>  	}
>>
>> +	/*
>> +	 * 16-bit overrides such as CALLW (66 e8 nn nn) are not supported.
>> +	 * 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)
>> +			return -ENOTSUPP;
>> +	}
>> +
>>  	auprobe->branch.opc1 = opc1;
>>  	auprobe->branch.ilen = insn->length;
>>  	auprobe->branch.offs = insn->immediate.value;
>> --
>> 1.8.1.4
>>
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


-- 
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Research Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu.pt@hitachi.com



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-04-25  3:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-24 17:08 [PATCH] uprobes/x86: Refuse to attach uprobe to "word-sized" branch insns Denys Vlasenko
2014-04-24 17:33 ` Oleg Nesterov
2014-04-25  0:28   ` Jim Keniston
2014-04-25  3:23   ` Masami Hiramatsu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.