From 1141ccdf79f52ca8529232960fc3b48e1953f8e7 Mon Sep 17 00:00:00 2001 From: matejcik Date: Mon, 24 Apr 2023 12:40:48 +0200 Subject: [PATCH] fix(python/trezorctl): limit memory for one field (fixes #2439) --- python/.changelog.d/2439.fixed | 1 + python/src/trezorlib/protobuf.py | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 python/.changelog.d/2439.fixed diff --git a/python/.changelog.d/2439.fixed b/python/.changelog.d/2439.fixed new file mode 100644 index 0000000000..e9c2a598f4 --- /dev/null +++ b/python/.changelog.d/2439.fixed @@ -0,0 +1 @@ +Limit memory exhaustion in protobuf parser. diff --git a/python/src/trezorlib/protobuf.py b/python/src/trezorlib/protobuf.py index 101bfccfe1..e6fdcdbf0e 100644 --- a/python/src/trezorlib/protobuf.py +++ b/python/src/trezorlib/protobuf.py @@ -35,6 +35,8 @@ from typing_extensions import Protocol, TypeGuard T = TypeVar("T", bound=type) MT = TypeVar("MT", bound="MessageType") +MAX_FIELD_SIZE = 1024 * 1024 # 1 MB + class Reader(Protocol): def readinto(self, __buf: bytearray) -> int: @@ -335,6 +337,9 @@ def decode_length_delimited_field( field: Field, reader: Reader ) -> Union[bytes, str, MessageType]: value = load_uvarint(reader) + if value > MAX_FIELD_SIZE: + raise ValueError(f"Field {field.name} contents too large ({value} bytes)") + if field.type == "bytes": buf = bytearray(value) reader.readinto(buf) @@ -375,6 +380,8 @@ def load_message(reader: Reader, msg_type: Type[MT]) -> MT: load_uvarint(reader) elif wtype == WIRE_TYPE_LENGTH: ivalue = load_uvarint(reader) + if ivalue > MAX_FIELD_SIZE: + raise ValueError(f"Unknown field {ftag} too large ({ivalue} bytes)") reader.readinto(bytearray(ivalue)) else: raise ValueError