[PATCH v7 03/26] x86/mpx: Use signed variables to compute effective addresses

Ricardo Neri ricardo.neri-calderon at linux.intel.com
Fri May 5 13:17:01 CDT 2017


Even though memory addresses are unsigned, the operands used to compute the
effective address do have a sign. This is true for the ModRM.rm, SIB.base,
SIB.index as well as the displacement bytes. 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: Borislav Petkov <bp at suse.de>
Cc: Andy Lutomirski <luto at kernel.org>
Cc: Dave Hansen <dave.hansen at linux.intel.com>
Cc: Adam Buchbinder <adam.buchbinder at gmail.com>
Cc: Colin Ian King <colin.king at canonical.com>
Cc: Lorenzo Stoakes <lstoakes at gmail.com>
Cc: Qiaowei Ren <qiaowei.ren at intel.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Nathan Howard <liverlint at gmail.com>
Cc: Adan Hawthorn <adanhawthorn at gmail.com>
Cc: Joe Perches <joe at perches.com>
Cc: Ravi V. Shankar <ravi.v.shankar at intel.com>
Cc: x86 at kernel.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon at linux.intel.com>
---
 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 1c34b76..ebdead8 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




More information about the wine-devel mailing list