pktlength: handle truncated MANUAL_LIST reply
Before reading the n_samples field of the MANUAL_LIST reply, check if it is actually contained in the received message. This does not change the outcome of the client's length check as the returned length was always larger than the length of the truncated reply and it was dropped anyway, but it prevents the client from reading uninitialized memory.
This commit is contained in:
parent
45f27f4f5e
commit
2343e7a89c
4 changed files with 12 additions and 11 deletions
9
client.c
9
client.c
|
@ -1427,14 +1427,9 @@ submit_request(CMD_Request *request, CMD_Reply *reply)
|
||||||
DEBUG_LOG("Received %d bytes", recv_status);
|
DEBUG_LOG("Received %d bytes", recv_status);
|
||||||
|
|
||||||
read_length = recv_status;
|
read_length = recv_status;
|
||||||
if (read_length >= offsetof(CMD_Reply, data)) {
|
expected_length = PKL_ReplyLength(reply, read_length);
|
||||||
expected_length = PKL_ReplyLength(reply);
|
|
||||||
} else {
|
|
||||||
expected_length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bad_length = (read_length < expected_length ||
|
bad_length = !expected_length || read_length < expected_length;
|
||||||
expected_length < offsetof(CMD_Reply, data));
|
|
||||||
|
|
||||||
if (!bad_length) {
|
if (!bad_length) {
|
||||||
bad_sequence = reply->sequence != request->sequence;
|
bad_sequence = reply->sequence != request->sequence;
|
||||||
|
|
4
cmdmon.c
4
cmdmon.c
|
@ -279,7 +279,7 @@ do_size_checks(void)
|
||||||
reply.reply = htons(i);
|
reply.reply = htons(i);
|
||||||
reply.status = STT_SUCCESS;
|
reply.status = STT_SUCCESS;
|
||||||
reply.data.manual_list.n_samples = htonl(MAX_MANUAL_LIST_SAMPLES);
|
reply.data.manual_list.n_samples = htonl(MAX_MANUAL_LIST_SAMPLES);
|
||||||
reply_length = PKL_ReplyLength(&reply);
|
reply_length = PKL_ReplyLength(&reply, sizeof (reply));
|
||||||
if ((reply_length && reply_length < offsetof(CMD_Reply, data)) ||
|
if ((reply_length && reply_length < offsetof(CMD_Reply, data)) ||
|
||||||
reply_length > sizeof (CMD_Reply))
|
reply_length > sizeof (CMD_Reply))
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -393,7 +393,7 @@ transmit_reply(CMD_Reply *msg, union sockaddr_all *where_to)
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
tx_message_length = PKL_ReplyLength(msg);
|
tx_message_length = PKL_ReplyLength(msg, sizeof (*msg));
|
||||||
status = sendto(sock_fd, (void *) msg, tx_message_length, 0,
|
status = sendto(sock_fd, (void *) msg, tx_message_length, 0,
|
||||||
&where_to->sa, addrlen);
|
&where_to->sa, addrlen);
|
||||||
|
|
||||||
|
|
|
@ -183,12 +183,15 @@ PKL_CommandPaddingLength(CMD_Request *r)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
PKL_ReplyLength(CMD_Reply *r)
|
PKL_ReplyLength(CMD_Reply *r, int read_length)
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
|
||||||
assert(sizeof (reply_lengths) / sizeof (reply_lengths[0]) == N_REPLY_TYPES);
|
assert(sizeof (reply_lengths) / sizeof (reply_lengths[0]) == N_REPLY_TYPES);
|
||||||
|
|
||||||
|
if (read_length < (int)offsetof(CMD_Reply, data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
type = ntohs(r->reply);
|
type = ntohs(r->reply);
|
||||||
|
|
||||||
/* Note that reply type codes start from 1, not 0 */
|
/* Note that reply type codes start from 1, not 0 */
|
||||||
|
@ -202,6 +205,9 @@ PKL_ReplyLength(CMD_Reply *r)
|
||||||
if (r->status != htons(STT_SUCCESS))
|
if (r->status != htons(STT_SUCCESS))
|
||||||
return offsetof(CMD_Reply, data);
|
return offsetof(CMD_Reply, data);
|
||||||
|
|
||||||
|
if (read_length < (int)offsetof(CMD_Reply, data.manual_list.samples))
|
||||||
|
return 0;
|
||||||
|
|
||||||
ns = ntohl(r->data.manual_list.n_samples);
|
ns = ntohl(r->data.manual_list.n_samples);
|
||||||
if (ns > MAX_MANUAL_LIST_SAMPLES)
|
if (ns > MAX_MANUAL_LIST_SAMPLES)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -35,6 +35,6 @@ extern int PKL_CommandLength(CMD_Request *r);
|
||||||
|
|
||||||
extern int PKL_CommandPaddingLength(CMD_Request *r);
|
extern int PKL_CommandPaddingLength(CMD_Request *r);
|
||||||
|
|
||||||
extern int PKL_ReplyLength(CMD_Reply *r);
|
extern int PKL_ReplyLength(CMD_Reply *r, int read_length);
|
||||||
|
|
||||||
#endif /* GOT_PKTLENGTH_H */
|
#endif /* GOT_PKTLENGTH_H */
|
||||||
|
|
Loading…
Reference in a new issue