cmdmon: check response length before sending

Before sending a cmdmon response, make sure it is not longer than the
request to avoid amplification in case the response/padding length is
incorrectly specified for a request.
This commit is contained in:
Miroslav Lichvar 2020-09-07 10:42:33 +02:00
parent adebb027be
commit 9c36236742

View file

@ -294,10 +294,16 @@ CAM_OpenUnixSocket(void)
/* ================================================== */ /* ================================================== */
static void static void
transmit_reply(int sock_fd, SCK_Message *message) transmit_reply(int sock_fd, int request_length, SCK_Message *message)
{ {
message->length = PKL_ReplyLength((CMD_Reply *)message->data); message->length = PKL_ReplyLength((CMD_Reply *)message->data);
if (request_length < message->length) {
DEBUG_LOG("Response longer than request req_len=%d res_len=%d",
request_length, message->length);
return;
}
/* Don't require responses to non-link-local addresses to use the same /* Don't require responses to non-link-local addresses to use the same
interface */ interface */
if (!SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr)) if (!SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr))
@ -1427,7 +1433,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) { if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) {
tx_message.status = htons(STT_BADPKTVERSION); tx_message.status = htons(STT_BADPKTVERSION);
transmit_reply(sock_fd, sck_message); transmit_reply(sock_fd, read_length, sck_message);
} }
return; return;
} }
@ -1437,7 +1443,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
DEBUG_LOG("Command packet has invalid command %d", rx_command); DEBUG_LOG("Command packet has invalid command %d", rx_command);
tx_message.status = htons(STT_INVALID); tx_message.status = htons(STT_INVALID);
transmit_reply(sock_fd, sck_message); transmit_reply(sock_fd, read_length, sck_message);
return; return;
} }
@ -1446,7 +1452,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
expected_length); expected_length);
tx_message.status = htons(STT_BADPKTLENGTH); tx_message.status = htons(STT_BADPKTLENGTH);
transmit_reply(sock_fd, sck_message); transmit_reply(sock_fd, read_length, sck_message);
return; return;
} }
@ -1739,7 +1745,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
static int do_it=1; static int do_it=1;
if (do_it) { if (do_it) {
transmit_reply(sock_fd, sck_message); transmit_reply(sock_fd, read_length, sck_message);
} }
#if 0 #if 0