Harden RTSP handling for malformed Session headers and oversized responses
This commit is contained in:
+36
-1
@@ -4,6 +4,7 @@
|
|||||||
#define RTSP_CONNECT_TIMEOUT_SEC 10
|
#define RTSP_CONNECT_TIMEOUT_SEC 10
|
||||||
#define RTSP_RECEIVE_TIMEOUT_SEC 15
|
#define RTSP_RECEIVE_TIMEOUT_SEC 15
|
||||||
#define RTSP_RETRY_DELAY_MS 500
|
#define RTSP_RETRY_DELAY_MS 500
|
||||||
|
#define MAX_RTSP_RESPONSE_SIZE (1024 * 1024)
|
||||||
|
|
||||||
static int currentSeqNumber;
|
static int currentSeqNumber;
|
||||||
static char rtspTargetUrl[256];
|
static char rtspTargetUrl[256];
|
||||||
@@ -310,6 +311,12 @@ static bool transactRtspMessageEnet(PRTSP_MESSAGE request, PRTSP_MESSAGE respons
|
|||||||
goto Exit;
|
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);
|
responseBuffer = malloc(event.packet->dataLength);
|
||||||
if (responseBuffer == NULL) {
|
if (responseBuffer == NULL) {
|
||||||
Limelog("Failed to allocate RTSP response buffer\n");
|
Limelog("Failed to allocate RTSP response buffer\n");
|
||||||
@@ -331,6 +338,12 @@ static bool transactRtspMessageEnet(PRTSP_MESSAGE request, PRTSP_MESSAGE respons
|
|||||||
goto Exit;
|
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);
|
responseBuffer = extendBuffer(responseBuffer, event.packet->dataLength + offset);
|
||||||
if (responseBuffer == NULL) {
|
if (responseBuffer == NULL) {
|
||||||
Limelog("Failed to extend RTSP response buffer\n");
|
Limelog("Failed to extend RTSP response buffer\n");
|
||||||
@@ -436,7 +449,14 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response
|
|||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
|
|
||||||
if (offset >= responseBufferSize) {
|
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;
|
responseBufferSize = offset + 16384;
|
||||||
|
|
||||||
responseBuffer = extendBuffer(responseBuffer, responseBufferSize);
|
responseBuffer = extendBuffer(responseBuffer, responseBufferSize);
|
||||||
if (responseBuffer == NULL) {
|
if (responseBuffer == NULL) {
|
||||||
Limelog("Failed to allocate RTSP response buffer\n");
|
Limelog("Failed to allocate RTSP response buffer\n");
|
||||||
@@ -470,6 +490,12 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ((size_t)offset + err > MAX_RTSP_RESPONSE_SIZE) {
|
||||||
|
*error = EMSGSIZE;
|
||||||
|
Limelog("RTSP response exceeded maximum allowed size\n");
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
offset += err;
|
offset += err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1142,6 +1168,7 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) {
|
|||||||
RTSP_MESSAGE response;
|
RTSP_MESSAGE response;
|
||||||
char* sessionId;
|
char* sessionId;
|
||||||
char* pingPayload;
|
char* pingPayload;
|
||||||
|
char* sessionToken;
|
||||||
int error = -1;
|
int error = -1;
|
||||||
char* strtokCtx = NULL;
|
char* strtokCtx = NULL;
|
||||||
|
|
||||||
@@ -1197,12 +1224,20 @@ int performRtspHandshake(PSERVER_INFORMATION serverInfo) {
|
|||||||
// resolves any 454 session not found errors on
|
// resolves any 454 session not found errors on
|
||||||
// standard RTSP server implementations.
|
// standard RTSP server implementations.
|
||||||
// (i.e - sessionId = "DEADBEEFCAFE;timeout = 90")
|
// (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) {
|
if (sessionIdString == NULL) {
|
||||||
Limelog("Failed to duplicate session ID string\n");
|
Limelog("Failed to duplicate session ID string\n");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hasSessionId = true;
|
hasSessionId = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user