| From 8e8efe0379bd93e8219ca0fc6fa80b5dd85b09cb Mon Sep 17 00:00:00 2001 |
| From: Dave Hansen <dave.hansen@linux.intel.com> |
| Date: Mon, 30 Nov 2015 16:31:13 -0800 |
| Subject: x86/mpx: Fix instruction decoder condition |
| |
| From: Dave Hansen <dave.hansen@linux.intel.com> |
| |
| commit 8e8efe0379bd93e8219ca0fc6fa80b5dd85b09cb upstream. |
| |
| MPX decodes instructions in order to tell which bounds register |
| was violated. Part of this decoding involves looking at the "REX |
| prefix" which is a special instrucion prefix used to retrofit |
| support for new registers in to old instructions. |
| |
| The X86_REX_*() macros are defined to return actual bit values: |
| |
| #define X86_REX_R(rex) ((rex) & 4) |
| |
| *not* boolean values. However, the MPX code was checking for |
| them like they were booleans. This might have led to us |
| mis-decoding the "REX prefix" and giving false information out to |
| userspace about bounds violations. X86_REX_B() actually is bit 1, |
| so this is really only broken for the X86_REX_X() case. |
| |
| Fix the conditionals up to tolerate the non-boolean values. |
| |
| Fixes: fcc7ffd67991 "x86, mpx: Decode MPX instruction to get bound violation information" |
| Reported-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> |
| Cc: x86@kernel.org |
| Cc: Dave Hansen <dave@sr71.net> |
| Link: http://lkml.kernel.org/r/20151201003113.D800C1E0@viggo.jf.intel.com |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/mm/mpx.c | 6 +++--- |
| 1 file changed, 3 insertions(+), 3 deletions(-) |
| |
| --- a/arch/x86/mm/mpx.c |
| +++ b/arch/x86/mm/mpx.c |
| @@ -101,19 +101,19 @@ static int get_reg_offset(struct insn *i |
| switch (type) { |
| case REG_TYPE_RM: |
| regno = X86_MODRM_RM(insn->modrm.value); |
| - if (X86_REX_B(insn->rex_prefix.value) == 1) |
| + if (X86_REX_B(insn->rex_prefix.value)) |
| regno += 8; |
| break; |
| |
| case REG_TYPE_INDEX: |
| regno = X86_SIB_INDEX(insn->sib.value); |
| - if (X86_REX_X(insn->rex_prefix.value) == 1) |
| + if (X86_REX_X(insn->rex_prefix.value)) |
| regno += 8; |
| break; |
| |
| case REG_TYPE_BASE: |
| regno = X86_SIB_BASE(insn->sib.value); |
| - if (X86_REX_B(insn->rex_prefix.value) == 1) |
| + if (X86_REX_B(insn->rex_prefix.value)) |
| regno += 8; |
| break; |
| |