aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-08-03 00:50:18 -0700
committeriximeow <me@iximeow.net>2020-08-09 01:38:57 -0700
commit959c61e28e05a37aa19cc226d0f5b525610d47d7 (patch)
tree0423b2926395e6ad50e5536ea0c3dd500dda2f59
parent70585db861e03ec76648070ed4e3fc88b9808c48 (diff)
long instructions
-rw-r--r--src/long_mode/mod.rs6
-rw-r--r--test/long_mode/mod.rs12
2 files changed, 18 insertions, 0 deletions
diff --git a/src/long_mode/mod.rs b/src/long_mode/mod.rs
index 2f5fe5d..e79c8cb 100644
--- a/src/long_mode/mod.rs
+++ b/src/long_mode/mod.rs
@@ -5516,6 +5516,9 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
match bytes_iter.next() {
Some(b) => {
length += 1;
+ if length > 15 {
+ return Err(DecodeError::TooLong);
+ }
let record = OPCODES[b as usize];
if (b & 0xf0) == 0x40 {
prefixes.rex_from(b);
@@ -5649,6 +5652,9 @@ fn read_instr<T: Iterator<Item=u8>>(decoder: &InstDecoder, mut bytes_iter: T, in
}
instruction.prefixes = prefixes;
read_operands(decoder, bytes_iter, instruction, record.1, &mut length)?;
+ if length > 15 {
+ return Err(DecodeError::TooLong);
+ }
instruction.length = length;
if decoder != &InstDecoder::default() {
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index 7c4c5fa..0d81d02 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -1107,6 +1107,18 @@ fn test_control_flow() {
}
#[test]
+fn bad_instructions() {
+ // too long
+ test_invalid(&[
+ 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x33, 0xc0,
+ ]);
+}
+
+#[test]
fn test_test_cmp() {
test_display(&[0xf6, 0x05, 0x2c, 0x9b, 0xff, 0xff, 0x01], "test [rip - 0x64d4], 0x1");
test_display(&[0x48, 0x3d, 0x01, 0xf0, 0xff, 0xff], "cmp rax, -0xfff");