dcavalca / rpms / linuxptp

Forked from rpms/linuxptp 2 years ago
Clone

Blame SOURCES/linuxptp-cve-2021-3570.patch

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