Reject path trace TLVs with excessive elements.
The current code truncates the size of path trace TLVs which exceed the expected maximum based on the largest possible message size. However if another TLV follows, then a gap would appear, that is, an area in the message buffer not pointed to by any TLV descriptor. In order to avoid forwarding such malformed messages, this patch changes the logic to reject them. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
8f523e4d62
commit
faea24aa32
22
tlv.c
22
tlv.c
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -79,6 +80,17 @@ static int64_t net2host64_unaligned(int64_t *p)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tlv_array_invalid(struct TLV *tlv, size_t base_size, size_t item_size)
|
||||||
|
{
|
||||||
|
size_t expected_length, n_items;
|
||||||
|
|
||||||
|
n_items = (tlv->length - base_size) / item_size;
|
||||||
|
|
||||||
|
expected_length = base_size + n_items * item_size;
|
||||||
|
|
||||||
|
return (tlv->length == expected_length) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
|
static int mgt_post_recv(struct management_tlv *m, uint16_t data_len,
|
||||||
struct tlv_extra *extra)
|
struct tlv_extra *extra)
|
||||||
{
|
{
|
||||||
|
@ -678,11 +690,10 @@ void tlv_extra_recycle(struct tlv_extra *extra)
|
||||||
|
|
||||||
int tlv_post_recv(struct tlv_extra *extra)
|
int tlv_post_recv(struct tlv_extra *extra)
|
||||||
{
|
{
|
||||||
int result = 0;
|
|
||||||
struct management_tlv *mgt;
|
|
||||||
struct management_error_status *mes;
|
struct management_error_status *mes;
|
||||||
struct TLV *tlv = extra->tlv;
|
struct TLV *tlv = extra->tlv;
|
||||||
struct path_trace_tlv *ptt;
|
struct management_tlv *mgt;
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
switch (tlv->type) {
|
switch (tlv->type) {
|
||||||
case TLV_MANAGEMENT:
|
case TLV_MANAGEMENT:
|
||||||
|
@ -712,9 +723,8 @@ int tlv_post_recv(struct tlv_extra *extra)
|
||||||
result = unicast_negotiation_post_recv(extra);
|
result = unicast_negotiation_post_recv(extra);
|
||||||
break;
|
break;
|
||||||
case TLV_PATH_TRACE:
|
case TLV_PATH_TRACE:
|
||||||
ptt = (struct path_trace_tlv *) tlv;
|
if (tlv_array_invalid(tlv, 0, sizeof(struct ClockIdentity))) {
|
||||||
if (path_length(ptt) > PATH_TRACE_MAX) {
|
goto bad_length;
|
||||||
ptt->length = PATH_TRACE_MAX * sizeof(struct ClockIdentity);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TLV_ALTERNATE_TIME_OFFSET_INDICATOR:
|
case TLV_ALTERNATE_TIME_OFFSET_INDICATOR:
|
||||||
|
|
Loading…
Reference in New Issue