From ec3d576b6e6afed02792c35bfa4f59c0e3be2583 Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Sun, 9 Dec 2018 20:14:56 -0200 Subject: [PATCH 1/7] removed ReadVarBytes from VM --- src/neo-vm/ExecutionEngine.cs | 3 ++- src/neo-vm/Helper.cs | 22 ++++------------------ 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/neo-vm/ExecutionEngine.cs b/src/neo-vm/ExecutionEngine.cs index 8f2251a9..93a211c3 100644 --- a/src/neo-vm/ExecutionEngine.cs +++ b/src/neo-vm/ExecutionEngine.cs @@ -189,7 +189,8 @@ private void ExecuteOp(OpCode opcode, ExecutionContext context) } break; case OpCode.SYSCALL: - if (Service?.Invoke(context.OpReader.ReadVarBytes(252), this) != true) + int length = context.OpReader.ReadByte(); + if ((length > 252) || (Service?.Invoke(context.OpReader.SafeReadBytes(length), this) != true)) State |= VMState.FAULT; break; diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index df12eb31..959776f8 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -5,25 +5,11 @@ namespace Neo.VM { internal static class Helper { - public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0X7fffffc7) + public static byte[] SafeReadBytes(this BinaryReader reader, int max = 0x1000000) { - return reader.ReadBytes((int)reader.ReadVarInt((ulong)max)); - } - - public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) - { - byte fb = reader.ReadByte(); - ulong value; - if (fb == 0xFD) - value = reader.ReadUInt16(); - else if (fb == 0xFE) - value = reader.ReadUInt32(); - else if (fb == 0xFF) - value = reader.ReadUInt64(); - else - value = fb; - if (value > max) throw new FormatException(); - return value; + if((max > 0x1000000) || (!reader.BaseStream.CanSeek) || (reader.BaseStream.Length - reader.BaseStream.Position) < max)) + throw new FormatException; + return reader.reader.ReadBytes(max); } } } From aedcf10bab720b3bf3ae9259078dd3d0e4505ad1 Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Sun, 9 Dec 2018 20:26:42 -0200 Subject: [PATCH 2/7] using SafeReadBytes instead of ReadBytes --- src/neo-vm/ExecutionEngine.cs | 12 ++++++------ src/neo-vm/Helper.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/neo-vm/ExecutionEngine.cs b/src/neo-vm/ExecutionEngine.cs index 93a211c3..29fb6c0c 100644 --- a/src/neo-vm/ExecutionEngine.cs +++ b/src/neo-vm/ExecutionEngine.cs @@ -58,7 +58,7 @@ public void Execute() private void ExecuteOp(OpCode opcode, ExecutionContext context) { if (opcode >= OpCode.PUSHBYTES1 && opcode <= OpCode.PUSHBYTES75) - context.EvaluationStack.Push(context.OpReader.ReadBytes((byte)opcode)); + context.EvaluationStack.Push(context.OpReader.SafeReadBytes((byte)opcode)); else switch (opcode) { @@ -67,13 +67,13 @@ private void ExecuteOp(OpCode opcode, ExecutionContext context) context.EvaluationStack.Push(new byte[0]); break; case OpCode.PUSHDATA1: - context.EvaluationStack.Push(context.OpReader.ReadBytes(context.OpReader.ReadByte())); + context.EvaluationStack.Push(context.OpReader.SafeReadBytes(context.OpReader.ReadByte())); break; case OpCode.PUSHDATA2: - context.EvaluationStack.Push(context.OpReader.ReadBytes(context.OpReader.ReadUInt16())); + context.EvaluationStack.Push(context.OpReader.SafeReadBytes(context.OpReader.ReadUInt16())); break; case OpCode.PUSHDATA4: - context.EvaluationStack.Push(context.OpReader.ReadBytes(context.OpReader.ReadInt32())); + context.EvaluationStack.Push(context.OpReader.SafeReadBytes(context.OpReader.ReadInt32())); break; case OpCode.PUSHM1: case OpCode.PUSH1: @@ -166,7 +166,7 @@ private void ExecuteOp(OpCode opcode, ExecutionContext context) return; } - byte[] script_hash = context.OpReader.ReadBytes(20); + byte[] script_hash = context.OpReader.SafeReadBytes(20); if (script_hash.All(p => p == 0)) { script_hash = context.EvaluationStack.Pop().GetByteArray(); @@ -988,7 +988,7 @@ private void ExecuteOp(OpCode opcode, ExecutionContext context) if (opcode == OpCode.CALL_ED || opcode == OpCode.CALL_EDT) script_hash = context.EvaluationStack.Pop().GetByteArray(); else - script_hash = context.OpReader.ReadBytes(20); + script_hash = context.OpReader.SafeReadBytes(20); byte[] script = table.GetScript(script_hash); if (script == null) { diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index 959776f8..9c63563c 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -9,7 +9,7 @@ public static byte[] SafeReadBytes(this BinaryReader reader, int max = 0x1000000 { if((max > 0x1000000) || (!reader.BaseStream.CanSeek) || (reader.BaseStream.Length - reader.BaseStream.Position) < max)) throw new FormatException; - return reader.reader.ReadBytes(max); + return reader.ReadBytes(max); } } } From a369e790f3aa66c1bac0ad36d9975564da3be5d8 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Mon, 10 Dec 2018 19:20:25 +0800 Subject: [PATCH 3/7] Fix compilation error --- src/neo-vm/Helper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index 9c63563c..7e06cf1d 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -7,8 +7,8 @@ internal static class Helper { public static byte[] SafeReadBytes(this BinaryReader reader, int max = 0x1000000) { - if((max > 0x1000000) || (!reader.BaseStream.CanSeek) || (reader.BaseStream.Length - reader.BaseStream.Position) < max)) - throw new FormatException; + if (max > 0x1000000 || !reader.BaseStream.CanSeek || reader.BaseStream.Length - reader.BaseStream.Position < max) + throw new FormatException(); return reader.ReadBytes(max); } } From 3cab9abac1fd3edfd5e4f45c8ff45cda147a2c30 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Mon, 10 Dec 2018 19:52:19 +0800 Subject: [PATCH 4/7] re-add `ReadVarBytes()` --- src/neo-vm/ExecutionEngine.cs | 3 +-- src/neo-vm/Helper.cs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/neo-vm/ExecutionEngine.cs b/src/neo-vm/ExecutionEngine.cs index 29fb6c0c..366b193c 100644 --- a/src/neo-vm/ExecutionEngine.cs +++ b/src/neo-vm/ExecutionEngine.cs @@ -189,8 +189,7 @@ private void ExecuteOp(OpCode opcode, ExecutionContext context) } break; case OpCode.SYSCALL: - int length = context.OpReader.ReadByte(); - if ((length > 252) || (Service?.Invoke(context.OpReader.SafeReadBytes(length), this) != true)) + if (Service?.Invoke(context.OpReader.ReadVarBytes(252), this) != true) State |= VMState.FAULT; break; diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index 7e06cf1d..e063f855 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -5,6 +5,27 @@ namespace Neo.VM { internal static class Helper { + public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0X7fffffc7) + { + return reader.ReadBytes((int)reader.ReadVarInt((ulong)max)); + } + + public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) + { + byte fb = reader.ReadByte(); + ulong value; + if (fb == 0xFD) + value = reader.ReadUInt16(); + else if (fb == 0xFE) + value = reader.ReadUInt32(); + else if (fb == 0xFF) + value = reader.ReadUInt64(); + else + value = fb; + if (value > max) throw new FormatException(); + return value; + } + public static byte[] SafeReadBytes(this BinaryReader reader, int max = 0x1000000) { if (max > 0x1000000 || !reader.BaseStream.CanSeek || reader.BaseStream.Length - reader.BaseStream.Position < max) From c899f1527506dc73d695d8328ebdc886471fccfb Mon Sep 17 00:00:00 2001 From: erikzhang Date: Mon, 10 Dec 2018 19:55:04 +0800 Subject: [PATCH 5/7] Update `SafeReadBytes()` --- src/neo-vm/Helper.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index e063f855..08a6de38 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -26,11 +26,12 @@ public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxVa return value; } - public static byte[] SafeReadBytes(this BinaryReader reader, int max = 0x1000000) + public static byte[] SafeReadBytes(this BinaryReader reader, int count) { - if (max > 0x1000000 || !reader.BaseStream.CanSeek || reader.BaseStream.Length - reader.BaseStream.Position < max) + byte[] data = reader.ReadBytes(count); + if (data.Length < count) throw new FormatException(); - return reader.ReadBytes(max); + return data; } } } From 6384e150404268d94c36bd69492818359009b473 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Mon, 10 Dec 2018 19:56:20 +0800 Subject: [PATCH 6/7] Update `ReadVarBytes()` --- src/neo-vm/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index 08a6de38..7059f16c 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -7,7 +7,7 @@ internal static class Helper { public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0X7fffffc7) { - return reader.ReadBytes((int)reader.ReadVarInt((ulong)max)); + return reader.SafeReadBytes((int)reader.ReadVarInt((ulong)max)); } public static ulong ReadVarInt(this BinaryReader reader, ulong max = ulong.MaxValue) From 67df28c8bb42a88f0de20ddefc3fcc6b988de8c6 Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 10 Dec 2018 13:09:17 +0100 Subject: [PATCH 7/7] Fix max value --- src/neo-vm/Helper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo-vm/Helper.cs b/src/neo-vm/Helper.cs index 7059f16c..48285176 100644 --- a/src/neo-vm/Helper.cs +++ b/src/neo-vm/Helper.cs @@ -5,7 +5,7 @@ namespace Neo.VM { internal static class Helper { - public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0X7fffffc7) + public static byte[] ReadVarBytes(this BinaryReader reader, int max = 0x10000000) { return reader.SafeReadBytes((int)reader.ReadVarInt((ulong)max)); }