diff --git a/src/rcon.c b/src/rcon.c index 08d1672..19c85a7 100644 --- a/src/rcon.c +++ b/src/rcon.c @@ -111,24 +111,34 @@ int recv_packet(int sockfd, rcon_packet_t *packet) { } packet->type = le32toh(packet->type); - int body_size = packet->size - sizeof(int32_t) * 2 - 2; - if (body_size > 0 && body_size < (int)sizeof(packet->body)) { - bytes = recv(sockfd, packet->body, body_size, MSG_WAITALL); + int expected_body_size = packet->size - sizeof(int32_t) * 2 - 2; + if (expected_body_size < 0 || expected_body_size >= (int)sizeof(packet->body)) { + fprintf(stderr, "invalid packet body size: %d\n", expected_body_size); + return -1; + } + + if (expected_body_size > 0) { + bytes = recv(sockfd, packet->body, expected_body_size, MSG_WAITALL); if (bytes <= 0) { perror("recv body failed"); return -1; } - packet->body[body_size] = '\0'; - - bytes = recv(sockfd, &packet->_padding, 1, MSG_WAITALL); - if (bytes <= 0) { - perror("recv padding failed"); - return -1; - } - } else { - packet->size = sizeof(int32_t) * 2 + 2; - packet->body[0] = '\0'; } + packet->body[expected_body_size] = '\0'; + + uint8_t padding[2]; + bytes = recv(sockfd, padding, sizeof(padding), MSG_WAITALL); + if (bytes <= 0) { + perror("recv padding failed"); + return -1; + } + + if (padding[0] != 0 || padding[1] != 0) { + fprintf(stderr, "invalid packet padding\n"); + return -1; + } + + packet->_padding = padding[1]; return 0; }