Merge pull request #5624 from qlyoung/fix-zebra-ptm-buffer-overrun

Fix PTM ZAPI stream parsing
This commit is contained in:
Rafael Zalamena 2020-01-07 17:02:07 -03:00 committed by GitHub
commit 6e882c5c55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 25 deletions

View File

@ -2622,6 +2622,14 @@ void zserv_handle_commands(struct zserv *client, struct stream *msg)
struct zmsghdr hdr;
struct zebra_vrf *zvrf;
if (STREAM_READABLE(msg) > ZEBRA_MAX_PACKET_SIZ) {
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)
zlog_debug(
"ZAPI message is %zu bytes long but the maximum packet size is %u; dropping",
STREAM_READABLE(msg), ZEBRA_MAX_PACKET_SIZ);
return;
}
zapi_parse_header(msg, &hdr);
if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV)

View File

@ -1400,37 +1400,25 @@ static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
struct stream *msg, uint32_t command)
{
struct stream *msgc;
size_t zmsglen, zhdrlen;
char buf[ZEBRA_MAX_PACKET_SIZ];
pid_t ppid;
/*
* Don't modify message in the zebra API. In order to do that we
* need to allocate a new message stream and copy the message
* provided by zebra.
*/
/* Create BFD header */
msgc = stream_new(ZEBRA_MAX_PACKET_SIZ);
if (msgc == NULL) {
zlog_debug("%s: not enough memory", __func__);
return;
}
/* Calculate our header size plus the message contents. */
zhdrlen = ZEBRA_HEADER_SIZE + sizeof(uint32_t);
zmsglen = msg->endp - msg->getp;
memcpy(msgc->data + zhdrlen, msg->data + msg->getp, zmsglen);
/*
* The message type will be BFD_DEST_REPLY so we can use only
* one callback at the `bfdd` side, however the real command
* number will be included right after the zebra header.
*/
zclient_create_header(msgc, ZEBRA_BFD_DEST_REPLAY, zvrf->vrf->vrf_id);
stream_putl(msgc, command);
/* Update the data pointers. */
msgc->getp = 0;
msgc->endp = zhdrlen + zmsglen;
stream_putw_at(msgc, 0, stream_get_endp(msgc));
if (STREAM_READABLE(msg) > STREAM_WRITEABLE(msgc)) {
zlog_warn("Cannot fit extended BFD header plus original message contents into ZAPI packet; dropping message");
goto stream_failure;
}
/* Copy original message, excluding header, into new message */
stream_get_from(buf, msg, stream_get_getp(msg), STREAM_READABLE(msg));
stream_put(msgc, buf, STREAM_READABLE(msg));
/* Update length field */
stream_putw_at(msgc, 0, STREAM_READABLE(msgc));
zebra_ptm_send_bfdd(msgc);
@ -1441,6 +1429,7 @@ static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
return;
stream_failure:
stream_free(msgc);
zlog_err("%s:%d failed to registrate client pid", __FILE__, __LINE__);
}