|
|
056dc8 |
From 4b05d4b5d70c1ba76d95f94f1f4821c4b715fefe Mon Sep 17 00:00:00 2001
|
|
|
056dc8 |
From: Richard Cochran <richardcochran@gmail.com>
|
|
|
056dc8 |
Date: Sat, 17 Apr 2021 15:15:18 -0700
|
|
|
056dc8 |
Subject: [PATCH 2/2] Validate the messageLength field of incoming messages.
|
|
|
056dc8 |
|
|
|
056dc8 |
The PTP messageLength field is redundant because the length of a PTP
|
|
|
056dc8 |
message is precisely determined by the message type and the appended
|
|
|
056dc8 |
TLVs. The current implementation validates the sizes of both the main
|
|
|
056dc8 |
message (according to the fixed header length and fixed length by
|
|
|
056dc8 |
type) and the TLVs (by using the 'L' of the TLV).
|
|
|
056dc8 |
|
|
|
056dc8 |
However, when forwarding a message, the messageLength field is used.
|
|
|
056dc8 |
If a message arrives with a messageLength field larger than the actual
|
|
|
056dc8 |
message size, the code will read and possibly write data beyond the
|
|
|
056dc8 |
allocated buffer.
|
|
|
056dc8 |
|
|
|
056dc8 |
Fix the issue by validating the field on ingress. This prevents
|
|
|
056dc8 |
reading and sending data past the message buffer when forwarding a
|
|
|
056dc8 |
management message or other messages when operating as a transparent
|
|
|
056dc8 |
clock, and it also prevents a memory corruption in msg_post_recv()
|
|
|
056dc8 |
after forwarding a management message.
|
|
|
056dc8 |
|
|
|
056dc8 |
Reported-by: Miroslav Lichvar <mlichvar@redhat.com>
|
|
|
056dc8 |
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
|
|
|
056dc8 |
---
|
|
|
056dc8 |
msg.c | 18 ++++++++++++------
|
|
|
056dc8 |
1 file changed, 12 insertions(+), 6 deletions(-)
|
|
|
056dc8 |
|
|
|
056dc8 |
diff --git a/msg.c b/msg.c
|
|
|
056dc8 |
index dcb397c..c2d358b 100644
|
|
|
056dc8 |
--- a/msg.c
|
|
|
056dc8 |
+++ b/msg.c
|
|
|
056dc8 |
@@ -184,7 +184,7 @@ static int suffix_post_recv(struct ptp_message *msg, int len)
|
|
|
056dc8 |
{
|
|
|
056dc8 |
uint8_t *ptr = msg_suffix(msg);
|
|
|
056dc8 |
struct tlv_extra *extra;
|
|
|
056dc8 |
- int err;
|
|
|
056dc8 |
+ int err, suffix_len = 0;
|
|
|
056dc8 |
|
|
|
056dc8 |
if (!ptr)
|
|
|
056dc8 |
return 0;
|
|
|
056dc8 |
@@ -202,12 +202,14 @@ static int suffix_post_recv(struct ptp_message *msg, int len)
|
|
|
056dc8 |
tlv_extra_recycle(extra);
|
|
|
056dc8 |
return -EBADMSG;
|
|
|
056dc8 |
}
|
|
|
056dc8 |
+ suffix_len += sizeof(struct TLV);
|
|
|
056dc8 |
len -= sizeof(struct TLV);
|
|
|
056dc8 |
ptr += sizeof(struct TLV);
|
|
|
056dc8 |
if (extra->tlv->length > len) {
|
|
|
056dc8 |
tlv_extra_recycle(extra);
|
|
|
056dc8 |
return -EBADMSG;
|
|
|
056dc8 |
}
|
|
|
056dc8 |
+ suffix_len += extra->tlv->length;
|
|
|
056dc8 |
len -= extra->tlv->length;
|
|
|
056dc8 |
ptr += extra->tlv->length;
|
|
|
056dc8 |
err = tlv_post_recv(extra);
|
|
|
056dc8 |
@@ -217,7 +219,7 @@ static int suffix_post_recv(struct ptp_message *msg, int len)
|
|
|
056dc8 |
}
|
|
|
056dc8 |
msg_tlv_attach(msg, extra);
|
|
|
056dc8 |
}
|
|
|
056dc8 |
- return 0;
|
|
|
056dc8 |
+ return suffix_len;
|
|
|
056dc8 |
}
|
|
|
056dc8 |
|
|
|
056dc8 |
static void suffix_pre_send(struct ptp_message *msg)
|
|
|
056dc8 |
@@ -335,7 +337,7 @@ void msg_get(struct ptp_message *m)
|
|
|
056dc8 |
|
|
|
056dc8 |
int msg_post_recv(struct ptp_message *m, int cnt)
|
|
|
056dc8 |
{
|
|
|
056dc8 |
- int pdulen, type, err;
|
|
|
056dc8 |
+ int err, pdulen, suffix_len, type;
|
|
|
056dc8 |
|
|
|
056dc8 |
if (cnt < sizeof(struct ptp_header))
|
|
|
056dc8 |
return -EBADMSG;
|
|
|
056dc8 |
@@ -420,9 +422,13 @@ int msg_post_recv(struct ptp_message *m, int cnt)
|
|
|
056dc8 |
break;
|
|
|
056dc8 |
}
|
|
|
056dc8 |
|
|
|
056dc8 |
- err = suffix_post_recv(m, cnt - pdulen);
|
|
|
056dc8 |
- if (err)
|
|
|
056dc8 |
- return err;
|
|
|
056dc8 |
+ suffix_len = suffix_post_recv(m, cnt - pdulen);
|
|
|
056dc8 |
+ if (suffix_len < 0) {
|
|
|
056dc8 |
+ return suffix_len;
|
|
|
056dc8 |
+ }
|
|
|
056dc8 |
+ if (pdulen + suffix_len != m->header.messageLength) {
|
|
|
056dc8 |
+ return -EBADMSG;
|
|
|
056dc8 |
+ }
|
|
|
056dc8 |
|
|
|
056dc8 |
return 0;
|
|
|
056dc8 |
}
|
|
|
056dc8 |
--
|
|
|
056dc8 |
2.20.1
|
|
|
056dc8 |
|