x86/asm/decoder: Fix and enforce max instruction size in the insn decoder
x86 instructions cannot exceed 15 bytes, and the instruction decoder should enforce that. Prior to6ba48ff46f
, the instruction length limit was implicitly set to 16, which was an approximation of 15, but there is currently no limit at all. Fix MAX_INSN_SIZE (it should be 15, not 16), and fix the decoder to reject instructions that exceed MAX_INSN_SIZE. Other than potentially confusing some of the decoder sanity checks, I'm not aware of any actual problems that omitting this check would cause, nor am I aware of any practical problems caused by the MAX_INSN_SIZE error. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Fixes:6ba48ff46f
("x86: Remove arbitrary instruction size limit ... Link: http://lkml.kernel.org/r/f8f0bc9b8c58cfd6830f7d88400bf1396cbdcd0f.1422403511.git.luto@amacapital.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Родитель
cbb53b9623
Коммит
91e5ed49fc
|
@ -69,7 +69,7 @@ struct insn {
|
||||||
const insn_byte_t *next_byte;
|
const insn_byte_t *next_byte;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_INSN_SIZE 16
|
#define MAX_INSN_SIZE 15
|
||||||
|
|
||||||
#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
|
#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
|
||||||
#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
|
#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
|
||||||
|
|
|
@ -52,6 +52,13 @@
|
||||||
*/
|
*/
|
||||||
void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
|
void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Instructions longer than MAX_INSN_SIZE (15 bytes) are invalid
|
||||||
|
* even if the input buffer is long enough to hold them.
|
||||||
|
*/
|
||||||
|
if (buf_len > MAX_INSN_SIZE)
|
||||||
|
buf_len = MAX_INSN_SIZE;
|
||||||
|
|
||||||
memset(insn, 0, sizeof(*insn));
|
memset(insn, 0, sizeof(*insn));
|
||||||
insn->kaddr = kaddr;
|
insn->kaddr = kaddr;
|
||||||
insn->end_kaddr = kaddr + buf_len;
|
insn->end_kaddr = kaddr + buf_len;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче