read_length = recvfrom_status;
expected_length = PKL_ReplyLength(reply);
- bad_length = (read_length < expected_length);
+ bad_length = (read_length < expected_length ||
+ expected_length < offsetof(CMD_Reply, data));
bad_sender = (where_from.u.sa_family != his_addr.u.sa_family ||
(where_from.u.sa_family == AF_INET &&
(where_from.in4.sin_addr.s_addr != his_addr.in4.sin_addr.s_addr ||
}
read_length = status;
- expected_length = PKL_CommandLength(&rx_message);
- rx_command = ntohs(rx_message.command);
LCL_ReadRawTime(&now);
LCL_CookTime(&now, &cooked_now, NULL);
- tx_message.version = PROTO_VERSION_NUMBER;
- tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
- tx_message.res1 = 0;
- tx_message.res2 = 0;
- tx_message.command = rx_message.command;
- tx_message.sequence = rx_message.sequence;
- tx_message.reply = htons(RPY_NULL);
- tx_message.number = htons(1);
- tx_message.total = htons(1);
- tx_message.pad1 = 0;
- tx_message.utoken = htonl(utoken);
- /* Set this to a default (invalid) value. This protects against the
- token field being set to an arbitrary value if we reject the
- message, e.g. due to the host failing the access check. */
- tx_message.token = htonl(0xffffffffUL);
- memset(&tx_message.auth, 0, sizeof(tx_message.auth));
-
switch (where_from.u.sa_family) {
case AF_INET:
remote_ip.family = IPADDR_INET4;
allowed = ADF_IsAllowed(access_auth_table, &remote_ip) || localhost;
- if (read_length < offsetof(CMD_Request, data) ||
+ /* Message size sanity check */
+ if (read_length >= offsetof(CMD_Request, data)) {
+ expected_length = PKL_CommandLength(&rx_message);
+ } else {
+ expected_length = 0;
+ }
+
+ if (expected_length < offsetof(CMD_Request, data) ||
rx_message.pkt_type != PKT_TYPE_CMD_REQUEST ||
rx_message.res1 != 0 ||
rx_message.res2 != 0) {
return;
}
+ rx_command = ntohs(rx_message.command);
+
+ tx_message.version = PROTO_VERSION_NUMBER;
+ tx_message.pkt_type = PKT_TYPE_CMD_REPLY;
+ tx_message.res1 = 0;
+ tx_message.res2 = 0;
+ tx_message.command = rx_message.command;
+ tx_message.sequence = rx_message.sequence;
+ tx_message.reply = htons(RPY_NULL);
+ tx_message.number = htons(1);
+ tx_message.total = htons(1);
+ tx_message.pad1 = 0;
+ tx_message.utoken = htonl(utoken);
+ /* Set this to a default (invalid) value. This protects against the
+ token field being set to an arbitrary value if we reject the
+ message, e.g. due to the host failing the access check. */
+ tx_message.token = htonl(0xffffffffUL);
+ memset(&tx_message.auth, 0, sizeof(tx_message.auth));
+
if (rx_message.version != PROTO_VERSION_NUMBER) {
tx_message.status = htons(STT_NOHOSTACCESS);
if (!LOG_RateLimited()) {
{
unsigned long ns;
ns = ntohl(r->data.subnets_accessed.n_subnets);
+ if (ns > MAX_SUBNETS_ACCESSED)
+ return 0;
return (offsetof(CMD_Request, data.subnets_accessed.subnets) +
ns * sizeof(REQ_SubnetsAccessed_Subnet));
}
{
unsigned long nc;
nc = ntohl(r->data.client_accesses.n_clients);
+ if (nc > MAX_CLIENT_ACCESSES)
+ return 0;
return (offsetof(CMD_Request, data.client_accesses.client_ips) +
nc * sizeof(unsigned long));
}
{
unsigned long ns = ntohl(r->data.subnets_accessed.n_subnets);
if (r->status == htons(STT_SUCCESS)) {
+ if (ns > MAX_SUBNETS_ACCESSED)
+ return 0;
return (offsetof(CMD_Reply, data.subnets_accessed.subnets) +
ns * sizeof(RPY_SubnetsAccessed_Subnet));
} else {
{
unsigned long nc = ntohl(r->data.client_accesses.n_clients);
if (r->status == htons(STT_SUCCESS)) {
+ if (nc > MAX_CLIENT_ACCESSES)
+ return 0;
return (offsetof(CMD_Reply, data.client_accesses.clients) +
nc * sizeof(RPY_ClientAccesses_Client));
} else {
{
unsigned long nc = ntohl(r->data.client_accesses_by_index.n_clients);
if (r->status == htons(STT_SUCCESS)) {
+ if (nc > MAX_CLIENT_ACCESSES)
+ return 0;
return (offsetof(CMD_Reply, data.client_accesses_by_index.clients) +
nc * sizeof(RPY_ClientAccesses_Client));
} else {
case RPY_MANUAL_LIST:
{
unsigned long ns = ntohl(r->data.manual_list.n_samples);
+ if (ns > MAX_MANUAL_LIST_SAMPLES)
+ return 0;
if (r->status == htons(STT_SUCCESS)) {
return (offsetof(CMD_Reply, data.manual_list.samples) +
ns * sizeof(RPY_ManualListSample));