Harden RTSP handling for malformed Session headers and oversized responses

This commit is contained in:
foxirain
2026-03-24 02:49:55 +09:00
committed by Cameron Gutman
parent 7022b337a9
commit 7b026e77be

View File

@@ -4,6 +4,7 @@
#define RTSP_CONNECT_TIMEOUT_SEC 10
#define RTSP_RECEIVE_TIMEOUT_SEC 15
#define RTSP_RETRY_DELAY_MS 500
#define MAX_RTSP_RESPONSE_SIZE (1024 * 1024)
static int currentSeqNumber;
static char rtspTargetUrl[256];
@@ -310,6 +311,12 @@ static bool transactRtspMessageEnet(PRTSP_MESSAGE request, PRTSP_MESSAGE respons
goto Exit;
}
if (event.packet->dataLength > MAX_RTSP_RESPONSE_SIZE) {
Limelog("RTSP response exceeded maximum allowed size\n");
enet_packet_destroy(event.packet);
goto Exit;
}
responseBuffer = malloc(event.packet->dataLength);
if (responseBuffer == NULL) {
Limelog("Failed to allocate RTSP response buffer\n");
@@ -331,6 +338,12 @@ static bool transactRtspMessageEnet(PRTSP_MESSAGE request, PRTSP_MESSAGE respons
goto Exit;
}
if ((size_t)offset + event.packet->dataLength > MAX_RTSP_RESPONSE_SIZE) {
Limelog("RTSP response exceeded maximum allowed size\n");
enet_packet_destroy(event.packet);
goto Exit;
}
responseBuffer = extendBuffer(responseBuffer, event.packet->dataLength + offset);
if (responseBuffer == NULL) {
Limelog("Failed to extend RTSP response buffer\n");
@@ -436,7 +449,14 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response
struct pollfd pfd;
if (offset >= responseBufferSize) {
if ((size_t)offset >= MAX_RTSP_RESPONSE_SIZE) {
*error = EMSGSIZE;
Limelog("RTSP response exceeded maximum allowed size\n");
goto Exit;
}
responseBufferSize = offset + 16384;
responseBuffer = extendBuffer(responseBuffer, responseBufferSize);
if (responseBuffer == NULL) {
Limelog("Failed to allocate RTSP response buffer\n");
@@ -470,6 +490,12 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response
break;
}
else {
if ((size_t)offset + err > MAX_RTSP_RESPONSE_SIZE) {
*error = EMSGSIZE;
Limelog("RTSP response exceeded maximum allowed size\n");
goto Exit;
}
offset += err;
}
}
@@ -1142,6 +1168,7 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) {
RTSP_MESSAGE response;
char* sessionId;
char* pingPayload;
char* sessionToken;
int error = -1;
char* strtokCtx = NULL;
@@ -1197,12 +1224,20 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) {
// resolves any 454 session not found errors on
// standard RTSP server implementations.
// (i.e - sessionId = "DEADBEEFCAFE;timeout = 90")
sessionIdString = strdup(strtok_r(sessionId, ";", &strtokCtx));
sessionToken = strtok_r(sessionId, ";", &strtokCtx);
if (sessionToken == NULL || sessionToken[0] == '\0') {
Limelog("RTSP SETUP streamid=audio has malformed session attribute\n");
ret = -1;
goto Exit;
}
sessionIdString = strdup(sessionToken);
if (sessionIdString == NULL) {
Limelog("Failed to duplicate session ID string\n");
ret = -1;
goto Exit;
}
hasSessionId = true;