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 <richardcoch...@gmail.com>
---
 tlv.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/tlv.c b/tlv.c
index 2440482..6ab54a5 100644
--- a/tlv.c
+++ b/tlv.c
@@ -18,6 +18,7 @@
  */
 #include <arpa/inet.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -79,6 +80,17 @@ static int64_t net2host64_unaligned(int64_t *p)
        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,
                         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 result = 0;
-       struct management_tlv *mgt;
        struct management_error_status *mes;
        struct TLV *tlv = extra->tlv;
-       struct path_trace_tlv *ptt;
+       struct management_tlv *mgt;
+       int result = 0;
 
        switch (tlv->type) {
        case TLV_MANAGEMENT:
@@ -712,9 +723,8 @@ int tlv_post_recv(struct tlv_extra *extra)
                result = unicast_negotiation_post_recv(extra);
                break;
        case TLV_PATH_TRACE:
-               ptt = (struct path_trace_tlv *) tlv;
-               if (path_length(ptt) > PATH_TRACE_MAX) {
-                       ptt->length = PATH_TRACE_MAX * sizeof(struct 
ClockIdentity);
+               if (tlv_array_invalid(tlv, 0, sizeof(struct ClockIdentity))) {
+                       goto bad_length;
                }
                break;
        case TLV_ALTERNATE_TIME_OFFSET_INDICATOR:
-- 
2.20.1



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to