mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 19:57:26 +08:00
GP-6718: Add protections around TraceRmi message lengths.
This commit is contained in:
+12
-2
@@ -75,6 +75,8 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
|
|||||||
*/
|
*/
|
||||||
public static final String VERSION = "12.1";
|
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 {
|
protected static class VersionMismatchError extends TraceRmiError {
|
||||||
public VersionMismatchError(String remote) {
|
public VersionMismatchError(String remote) {
|
||||||
super("Mismatched versions: Front-end: %s, back-end: %s.".formatted(VERSION, 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)
|
protected static void sendDelimited(OutputStream out, RootMessage msg, long dbgSeq)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
|
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());
|
out.write(buf.array());
|
||||||
msg.writeTo(out);
|
msg.writeTo(out);
|
||||||
out.flush();
|
out.flush();
|
||||||
@@ -441,6 +447,10 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int len = ByteBuffer.wrap(lenBuf).getInt();
|
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);
|
byte[] datBuf = recvAll(in, len);
|
||||||
if (datBuf == null) {
|
if (datBuf == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -504,10 +514,10 @@ public class TraceRmiHandler extends AbstractTraceRmiConnection {
|
|||||||
|
|
||||||
protected void negotiate() {
|
protected void negotiate() {
|
||||||
RootMessage req = receive();
|
RootMessage req = receive();
|
||||||
RootMessage rep = dispatchNegotiate.handle(req);
|
|
||||||
if (req == null) {
|
if (req == null) {
|
||||||
throw new TraceRmiError("Could not receive negotiation request");
|
throw new TraceRmiError("Could not receive negotiation request");
|
||||||
}
|
}
|
||||||
|
RootMessage rep = dispatchNegotiate.handle(req);
|
||||||
if (!send(rep)) {
|
if (!send(rep)) {
|
||||||
throw new TraceRmiError("Could not respond during negotiation");
|
throw new TraceRmiError("Could not respond during negotiation");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from typing import TypeVar
|
|||||||
from google.protobuf import message as _message
|
from google.protobuf import message as _message
|
||||||
|
|
||||||
M = TypeVar('M', bound=_message.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:
|
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:
|
def send_delimited(s: socket.socket, msg: _message.Message) -> None:
|
||||||
data = msg.SerializeToString()
|
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)
|
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:
|
def recv_delimited(s: socket.socket, msg: M, dbg_seq: int) -> M:
|
||||||
size = recv_length(s)
|
size = recv_length(s)
|
||||||
|
if size > MAX_MSG_LENGTH:
|
||||||
|
raise TraceRmiError("Cannot receive TraceRmi message with excessive message length")
|
||||||
buf = recv_all(s, size)
|
buf = recv_all(s, size)
|
||||||
if len(buf) < size:
|
if len(buf) < size:
|
||||||
raise Exception("Socket closed")
|
raise Exception("Socket closed")
|
||||||
|
|||||||
Reference in New Issue
Block a user