diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java index 2d915883cc..48cd559eaa 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java @@ -75,6 +75,8 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection { */ public static final String VERSION = "12.1"; + public static final int MAX_MSG_LENGTH = 1 << 16; // 64K should be plenty and not cause OOM + protected static class VersionMismatchError extends TraceRmiError { public VersionMismatchError(String remote) { super("Mismatched versions: Front-end: %s, back-end: %s.".formatted(VERSION, remote)); @@ -416,7 +418,11 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection { protected static void sendDelimited(OutputStream out, RootMessage msg, long dbgSeq) throws IOException { ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES); - buf.putInt(msg.getSerializedSize()); + int len = msg.getSerializedSize(); + if (len > MAX_MSG_LENGTH) { + throw new TraceRmiError("Cannot send TraceRmi message with excessive length"); + } + buf.putInt(len); out.write(buf.array()); msg.writeTo(out); out.flush(); @@ -441,6 +447,10 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection { return null; } int len = ByteBuffer.wrap(lenBuf).getInt(); + if (len > MAX_MSG_LENGTH) { + throw new TraceRmiError( + "Cannot receive TraceRmi message with excessive message length"); + } byte[] datBuf = recvAll(in, len); if (datBuf == null) { return null; @@ -504,10 +514,10 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection { protected void negotiate() { RootMessage req = receive(); - RootMessage rep = dispatchNegotiate.handle(req); if (req == null) { throw new TraceRmiError("Could not receive negotiation request"); } + RootMessage rep = dispatchNegotiate.handle(req); if (!send(rep)) { throw new TraceRmiError("Could not respond during negotiation"); } diff --git a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/util.py b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/util.py index aec359ae7a..0ccdc598cd 100644 --- a/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/util.py +++ b/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/util.py @@ -20,6 +20,7 @@ from typing import TypeVar from google.protobuf import message as _message M = TypeVar('M', bound=_message.Message) +MAX_MSG_LENGTH = 1 << 16 # Plenty and shouldn't cause OOM def send_length(s: socket.socket, value: int) -> None: @@ -28,7 +29,10 @@ def send_length(s: socket.socket, value: int) -> None: def send_delimited(s: socket.socket, msg: _message.Message) -> None: data = msg.SerializeToString() - send_length(s, len(data)) + size = len(data) + if size > MAX_MSG_LENGTH: + raise TraceRmiError("Cannot send TraceRmi message with excessive length") + send_length(s, size) s.sendall(data) @@ -52,6 +56,8 @@ def recv_length(s: socket.socket) -> int: def recv_delimited(s: socket.socket, msg: M, dbg_seq: int) -> M: size = recv_length(s) + if size > MAX_MSG_LENGTH: + raise TraceRmiError("Cannot receive TraceRmi message with excessive message length") buf = recv_all(s, size) if len(buf) < size: raise Exception("Socket closed")