aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2021-12-16 19:58:15 -0800
committeriximeow <me@iximeow.net>2021-12-16 20:01:26 -0800
commitf063f747c21548329170fd09fd09d391b2277aed (patch)
tree38159b9379c7f7c081554d431f78872b5a465e92
parentcd987288f0334b9888174f4ccc2d1f564388e994 (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--CHANGELOG4
-rw-r--r--src/long_mode/evex.rs2
-rw-r--r--src/protected_mode/evex.rs2
-rw-r--r--src/real_mode/evex.rs2
-rw-r--r--test/long_mode/mod.rs6
-rw-r--r--test/protected_mode/mod.rs6
-rw-r--r--test/real_mode/mod.rs6
7 files changed, 25 insertions, 3 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b963b69..73af131 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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]");
+}