diff options
author | iximeow <me@iximeow.net> | 2021-12-16 19:58:15 -0800 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2021-12-16 20:01:26 -0800 |
commit | f063f747c21548329170fd09fd09d391b2277aed (patch) | |
tree | 38159b9379c7f7c081554d431f78872b5a465e92 | |
parent | cd987288f0334b9888174f4ccc2d1f564388e994 (diff) |
displacements are stored as unsigned, but are functionally signed ints
so multiplying to expand EVEX compressed offsets can overflow, and that
needs to be okay.
-rw-r--r-- | CHANGELOG | 4 | ||||
-rw-r--r-- | src/long_mode/evex.rs | 2 | ||||
-rw-r--r-- | src/protected_mode/evex.rs | 2 | ||||
-rw-r--r-- | src/real_mode/evex.rs | 2 | ||||
-rw-r--r-- | test/long_mode/mod.rs | 6 | ||||
-rw-r--r-- | test/protected_mode/mod.rs | 6 | ||||
-rw-r--r-- | test/real_mode/mod.rs | 6 |
7 files changed, 25 insertions, 3 deletions
@@ -1,3 +1,7 @@ +## 1.1.2 +* fix panic when evex instructions with compressed displacements are decoded in + debug builds + ## 1.1.1 * support `endbr64` and `endbr32` - these are interpretations of `nop` (`0f1e` wide nop), so the only issue diff --git a/src/long_mode/evex.rs b/src/long_mode/evex.rs index 7f456e7..5c0967b 100644 --- a/src/long_mode/evex.rs +++ b/src/long_mode/evex.rs @@ -11,7 +11,7 @@ fn isa_has_qwords() -> bool { } fn apply_disp_scale(inst: &mut Instruction) { - inst.disp *= inst.mem_size as u64; + inst.disp = ((inst.disp as i64) * (inst.mem_size as i64)) as u64; } include!("../shared/generated_evex.in"); diff --git a/src/protected_mode/evex.rs b/src/protected_mode/evex.rs index cb0a4ba..2ef91b6 100644 --- a/src/protected_mode/evex.rs +++ b/src/protected_mode/evex.rs @@ -11,7 +11,7 @@ fn isa_has_qwords() -> bool { } fn apply_disp_scale(inst: &mut Instruction) { - inst.disp *= inst.mem_size as u32; + inst.disp = ((inst.disp as i32) * (inst.mem_size as i32)) as u32; } include!("../shared/generated_evex.in"); diff --git a/src/real_mode/evex.rs b/src/real_mode/evex.rs index 9840b35..b63c08d 100644 --- a/src/real_mode/evex.rs +++ b/src/real_mode/evex.rs @@ -11,7 +11,7 @@ fn isa_has_qwords() -> bool { } fn apply_disp_scale(inst: &mut Instruction) { - inst.disp *= inst.mem_size as u32; + inst.disp = ((inst.disp as i32) * (inst.mem_size as i32)) as u32; } include!("../shared/generated_evex.in"); diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index 1efa74e..ee0ab4e 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -3390,3 +3390,9 @@ fn test_sevsnp() { fn from_llvm() { test_display(&[0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x01], "hreset 0x1"); } + +#[test] +fn from_reports() { + // negative compressed evex displacements should not overflow and panic + test_display(&[0x62, 0xf2, 0x6d, 0xac, 0x00, 0x59, 0xa7], "vpshufb ymm3{k4}{z}, ymm2, ymmword [rcx - 0xb20]"); +} diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 4b8ca8d..70dfb78 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -3077,3 +3077,9 @@ fn test_sevsnp() { fn from_llvm() { test_display(&[0xf3, 0x0f, 0x3a, 0xf0, 0xc0, 0x01], "hreset 0x1"); } + +#[test] +fn from_reports() { + // negative compressed evex displacements should not overflow and panic + test_display(&[0x62, 0xf2, 0x6d, 0xac, 0x00, 0x59, 0xa7], "vpshufb ymm3{k4}{z}, ymm2, ymmword [ecx - 0xb20]"); +} diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs index 6dcc3a2..b13358a 100644 --- a/test/real_mode/mod.rs +++ b/test/real_mode/mod.rs @@ -18362,3 +18362,9 @@ fn test_invalid_sequences() { test_invalid(&[0xf3, 0xf2, 0x0f, 0xae, 0x8f, 0x54, 0x3c, 0x58, 0xb7]); test_invalid(&[0xff, 0xd8]); } + +#[test] +fn from_reports() { + // negative compressed evex displacements should not overflow and panic + test_display(&[0x62, 0xf2, 0x6d, 0xac, 0x00, 0x59, 0xa7], "vpshufb ymm3{k4}{z}, ymm2, ymmword [bx + di - 0xb20]"); +} |