[v5 01/20] x86/mpx: Use signed variables to compute effective addresses
From: Ricardo Neri
Date: Fri Mar 03 2017 - 16:47:25 EST
Even though memory addresses are unsigned. The operands used to compute the
effective address do have a sign. This is true for the r/m part of the
ModRM byte, the base and index parts of the SiB byte as well as the
displacement. Thus, signed variables shall be used when computing the
effective address from these operands. Once the signed effective address
has been computed, it is casted to an unsigned long to determine the
linear address.
Variables are renamed to better reflect the type of address being
computed.
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: Adam Buchbinder <adam.buchbinder@xxxxxxxxx>
Cc: Colin Ian King <colin.king@xxxxxxxxxxxxx>
Cc: Lorenzo Stoakes <lstoakes@xxxxxxxxx>
Cc: Qiaowei Ren <qiaowei.ren@xxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Nathan Howard <liverlint@xxxxxxxxx>
Cc: Adan Hawthorn <adanhawthorn@xxxxxxxxx>
Cc: Joe Perches <joe@xxxxxxxxxxx>
Cc: Ravi V. Shankar <ravi.v.shankar@xxxxxxxxx>
Cc: x86@xxxxxxxxxx
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@xxxxxxxxxxxxxxx>
---
arch/x86/mm/mpx.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index 5126dfd..ff112e3 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -138,7 +138,8 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
*/
static void __user *mpx_get_addr_ref(struct insn *insn, struct pt_regs *regs)
{
- unsigned long addr, base, indx;
+ unsigned long linear_addr;
+ long eff_addr, base, indx;
int addr_offset, base_offset, indx_offset;
insn_byte_t sib;
@@ -150,7 +151,7 @@ static void __user *mpx_get_addr_ref(struct insn *insn, struct pt_regs *regs)
addr_offset = get_reg_offset(insn, regs, REG_TYPE_RM);
if (addr_offset < 0)
goto out_err;
- addr = regs_get_register(regs, addr_offset);
+ eff_addr = regs_get_register(regs, addr_offset);
} else {
if (insn->sib.nbytes) {
base_offset = get_reg_offset(insn, regs, REG_TYPE_BASE);
@@ -163,16 +164,18 @@ static void __user *mpx_get_addr_ref(struct insn *insn, struct pt_regs *regs)
base = regs_get_register(regs, base_offset);
indx = regs_get_register(regs, indx_offset);
- addr = base + indx * (1 << X86_SIB_SCALE(sib));
+ eff_addr = base + indx * (1 << X86_SIB_SCALE(sib));
} else {
addr_offset = get_reg_offset(insn, regs, REG_TYPE_RM);
if (addr_offset < 0)
goto out_err;
- addr = regs_get_register(regs, addr_offset);
+ eff_addr = regs_get_register(regs, addr_offset);
}
- addr += insn->displacement.value;
+ eff_addr += insn->displacement.value;
}
- return (void __user *)addr;
+ linear_addr = (unsigned long)eff_addr;
+
+ return (void __user *)linear_addr;
out_err:
return (void __user *)-1;
}
--
2.9.3