port: fix buffer overflow in net_sync_resp_append()

The PortAddress structure has no space for the actual address and should
be used only as a pointer to a larger buffer.

The issue was reported by gcc with enabled source fortification.

[ RC: Replace magic number with sizeof() macro. ]

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
master
Miroslav Lichvar 2018-04-06 12:30:08 +02:00 committed by Richard Cochran
parent 74cdaafd5b
commit 73c4d9a3c7
1 changed files with 16 additions and 13 deletions

29
port.c
View File

@ -403,32 +403,35 @@ static int net_sync_resp_append(struct port *p, struct ptp_message *m)
struct port *best = clock_best_port(p->clock);
struct nsm_resp_tlv_head *head;
struct Timestamp last_sync;
struct PortAddress paddr;
struct PortAddress *paddr;
struct ptp_message *tmp;
struct tlv_extra *extra;
unsigned char *ptr;
int tlv_len;
uint8_t buf[sizeof(*paddr) + sizeof(struct sockaddr_storage)];
last_sync = tmv_to_Timestamp(clock_ingress_time(p->clock));
pid = dad->pds.parentPortIdentity.clockIdentity;
paddr = (struct PortAddress *)buf;
if (best && memcmp(&cid, &pid, sizeof(cid))) {
/* Extract the parent's protocol address. */
paddr.networkProtocol = transport_type(best->trp);
paddr.addressLength =
transport_protocol_addr(best->trp, paddr.address);
paddr->networkProtocol = transport_type(best->trp);
paddr->addressLength =
transport_protocol_addr(best->trp, paddr->address);
if (best->best) {
tmp = TAILQ_FIRST(&best->best->messages);
extract_address(tmp, &paddr);
extract_address(tmp, paddr);
}
} else {
/* We are our own parent. */
paddr.networkProtocol = transport_type(p->trp);
paddr.addressLength =
transport_protocol_addr(p->trp, paddr.address);
paddr->networkProtocol = transport_type(p->trp);
paddr->addressLength =
transport_protocol_addr(p->trp, paddr->address);
}
tlv_len = sizeof(*head) + sizeof(*extra->foot) + paddr.addressLength;
tlv_len = sizeof(*head) + sizeof(*extra->foot) + paddr->addressLength;
extra = msg_tlv_append(m, tlv_len);
if (!extra) {
@ -439,12 +442,12 @@ static int net_sync_resp_append(struct port *p, struct ptp_message *m)
head->type = TLV_PTPMON_RESP;
head->length = tlv_len - sizeof(head->type) - sizeof(head->length);
head->port_state = p->state == PS_GRAND_MASTER ? PS_MASTER : p->state;
head->parent_addr.networkProtocol = paddr.networkProtocol;
head->parent_addr.addressLength = paddr.addressLength;
memcpy(head->parent_addr.address, paddr.address, paddr.addressLength);
head->parent_addr.networkProtocol = paddr->networkProtocol;
head->parent_addr.addressLength = paddr->addressLength;
memcpy(head->parent_addr.address, paddr->address, paddr->addressLength);
ptr = (unsigned char *) head;
ptr += sizeof(*head) + paddr.addressLength;
ptr += sizeof(*head) + paddr->addressLength;
extra->foot = (struct nsm_resp_tlv_foot *) ptr;
memcpy(&extra->foot->parent, &dad->pds, sizeof(extra->foot->parent));