diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 7866ac58f4..5a63c1e4f6 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -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) diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 8640a4a720..b48756302a 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -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__); }