This reduces the degree to which we're exposing the instruction decoder
to malicious user code at very little complexity cost.

Signed-off-by: Andy Lutomirski <[email protected]>
---
 arch/x86/mm/mpx.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index 67ebf5751222..3c3692149e43 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -230,6 +230,22 @@ static int mpx_insn_decode(struct insn *insn,
         */
        if (!nr_copied)
                return -EFAULT;
+
+       /*
+        * We only _really_ need to decode bndcl/bndcn/bndcu
+        * Error out on anything else.  Check this before decoding the
+        * instruction to reduce our exposure to intentionally bad code
+        * to some extent.  Note that this shortcut cat incorrectly return
+        * -EINVAL instead of -EFAULT under some circumstances.  This
+        * discrepency has no effect.
+        */
+       if (nr_copied < 2)
+               goto bad_opcode;
+       if (buf[0] != 0x0f)
+               goto bad_opcode;
+       if (buf[1] != 0x1a && buf[1] != 0x1b)
+               goto bad_opcode;
+
        insn_init(insn, buf, nr_copied, x86_64);
        insn_get_length(insn);
        /*
@@ -244,15 +260,6 @@ static int mpx_insn_decode(struct insn *insn,
                return -EFAULT;
 
        insn_get_opcode(insn);
-       /*
-        * We only _really_ need to decode bndcl/bndcn/bndcu
-        * Error out on anything else.
-        */
-       if (insn->opcode.bytes[0] != 0x0f)
-               goto bad_opcode;
-       if ((insn->opcode.bytes[1] != 0x1a) &&
-           (insn->opcode.bytes[1] != 0x1b))
-               goto bad_opcode;
 
        return 0;
 bad_opcode:
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to