Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
linuxptp
validate-the-messagelength-field-of-incoming-me...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File validate-the-messagelength-field-of-incoming-message.patch of Package linuxptp
From: Richard Cochran <richardcochran@gmail.com> Subject: Validate the messageLength field of incoming messages. Git-commit: 77e7abd7e9b0f480372989848541ddf8cb0350aa Patch-mainline: v1.5.1~1 References: bsc#1187646, CVE-2021-3570 Acked-by: Jiri Bohac <jbohac@suse.cz> The PTP messageLength field is redundant because the length of a PTP message is precisely determined by the message type and the appended TLVs. The current implementation validates the sizes of both the main message (according to the fixed header length and fixed length by type) and the TLVs (by using the 'L' of the TLV). However, when forwarding a message, the messageLength field is used. If a message arrives with a messageLength field larger than the actual message size, the code will read and possibly write data beyond the allocated buffer. Fix the issue by validating the field on ingress. This prevents reading and sending data past the message buffer when forwarding a management message or other messages when operating as a transparent clock, and it also prevents a memory corruption in msg_post_recv() after forwarding a management message. Reported-by: Miroslav Lichvar <mlichvar@redhat.com> Signed-off-by: Richard Cochran <richardcochran@gmail.com> diff --git a/msg.c b/msg.c index 06a3812..b643f78 100644 --- a/msg.c +++ b/msg.c @@ -118,11 +118,13 @@ static void port_id_pre_send(struct PortIdentity *pid) pid->portNumber = htons(pid->portNumber); } -static int suffix_post_recv(uint8_t *ptr, int len, struct tlv_extra *last) +static int suffix_post_recv(uint8_t *ptr, int len, struct tlv_extra *last, int *suffix_len) { int cnt, err; struct TLV *tlv; + *suffix_len = 0; + if (!ptr) return 0; @@ -133,11 +135,13 @@ static int suffix_post_recv(uint8_t *ptr, int len, struct tlv_extra *last) if (tlv->length % 2) { return -EBADMSG; } + *suffix_len += sizeof(struct TLV); len -= sizeof(struct TLV); ptr += sizeof(struct TLV); if (tlv->length > len) { return -EBADMSG; } + *suffix_len += tlv->length; len -= tlv->length; ptr += tlv->length; err = tlv_post_recv(tlv, len ? NULL : last); @@ -225,7 +229,7 @@ void msg_get(struct ptp_message *m) int msg_post_recv(struct ptp_message *m, int cnt) { - int pdulen, type, err; + int err, pdulen, type, suffix_len; uint8_t *suffix = NULL; if (cnt < sizeof(struct ptp_header)) @@ -318,9 +322,12 @@ int msg_post_recv(struct ptp_message *m, int cnt) if (msg_sots_missing(m)) return -ETIME; - m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv); + m->tlv_count = suffix_post_recv(suffix, cnt - pdulen, &m->last_tlv, &suffix_len); if (m->tlv_count < 0) return m->tlv_count; + if (pdulen + suffix_len != m->header.messageLength) { + return -EBADMSG; + } return 0; } -- 2.32.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor