Control: harden socket against malformed data and buffer overflows
- immediate close on bad size/type/payload - recv_len guard to prevent overflow - unknown commands now close without response
This commit is contained in:
1 parent
c8bac5d322
commit
fd815150f6
1 file changed
+23
-10
+23
-10
@@ -528,8 +528,11 @@ static void client_read_callback(socket_t fd, void* arg) {
|
||||
}
|
||||
|
||||
client->recv_len += received;
|
||||
|
||||
/* Process messages */
|
||||
if (client->recv_len > ETCPMON_MAX_MSG_SIZE) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Control recv buffer overflow");
|
||||
if (server) close_client(server, client);
|
||||
return;
|
||||
}
|
||||
if (server) {
|
||||
handle_client_data(server, client);
|
||||
}
|
||||
@@ -601,6 +604,17 @@ static void handle_client_data(struct control_server* server, struct control_cli
|
||||
while (client->recv_len >= sizeof(struct etcpmon_msg_header)) {
|
||||
struct etcpmon_msg_header* hdr = (struct etcpmon_msg_header*)client->recv_buffer;
|
||||
|
||||
if (hdr->size == 0 || hdr->size > ETCPMON_MAX_MSG_SIZE) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Invalid message size from client: %u", hdr->size);
|
||||
close_client(server, client);
|
||||
return;
|
||||
}
|
||||
if (hdr->type < ETCPMON_CMD_LIST_CONN || hdr->type > ETCPMON_CMD_DISCONNECT) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Invalid command type from client: 0x%02X", hdr->type);
|
||||
close_client(server, client);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate header */
|
||||
if (etcpmon_validate_header(hdr) != 0) {
|
||||
if (server->log_file) {
|
||||
@@ -646,6 +660,10 @@ static void handle_client_data(struct control_server* server, struct control_cli
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Client selected connection: %016llX",
|
||||
(unsigned long long)cmd->peer_node_id);
|
||||
} else {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Bad SELECT_CONN payload size %u", payload_size);
|
||||
close_client(server, client);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -668,14 +686,9 @@ static void handle_client_data(struct control_server* server, struct control_cli
|
||||
return;
|
||||
|
||||
default:
|
||||
if (server->log_file) {
|
||||
fprintf(server->log_file, "%llu: [ERROR] Unknown command from client: 0x%02X\n",
|
||||
(unsigned long long)get_timestamp_ms(), hdr->type);
|
||||
fflush(server->log_file);
|
||||
}
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "Unknown command from client: 0x%02X", hdr->type);
|
||||
send_error(client, ETCPMON_ERR_INVALID_CMD, "Unknown command", req_seq);
|
||||
break;
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Unknown command from client: 0x%02X", hdr->type);
|
||||
close_client(server, client);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove processed message from buffer */
|
||||
|
||||
Reference in new issue
Block a user