mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 10:38:05 +00:00
zebra: fix multiple bfd buffer issues
Whatever this BFD re-transmission function is had a few problems. 1. Used memcpy instead of the (more concise) stream APIs, which include bounds checking. 2. Did not sufficiently check packet sizes. Actually, 2) is mitigated but is still a problem, because the BFD header is 2 bytes larger than the "normal" ZAPI header, while the overall message size remains the same. So if the source message being duplicated is actually right up against the ZAPI_MAX_PACKET_SIZ, you still can't fit the whole message into your duplicated message. I have no idea what the intent was here but at least there's a warning if it happens now. Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
b833cc1ff4
commit
ab12ca856c
@ -1402,37 +1402,25 @@ static void _zebra_ptm_reroute(struct zserv *zs, struct zebra_vrf *zvrf,
|
|||||||
struct stream *msg, uint32_t command)
|
struct stream *msg, uint32_t command)
|
||||||
{
|
{
|
||||||
struct stream *msgc;
|
struct stream *msgc;
|
||||||
size_t zmsglen, zhdrlen;
|
char buf[ZEBRA_MAX_PACKET_SIZ];
|
||||||
pid_t ppid;
|
pid_t ppid;
|
||||||
|
|
||||||
/*
|
/* Create BFD header */
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
msgc = stream_new(ZEBRA_MAX_PACKET_SIZ);
|
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);
|
zclient_create_header(msgc, ZEBRA_BFD_DEST_REPLAY, zvrf->vrf->vrf_id);
|
||||||
stream_putl(msgc, command);
|
stream_putl(msgc, command);
|
||||||
|
|
||||||
/* Update the data pointers. */
|
if (STREAM_READABLE(msg) > STREAM_WRITEABLE(msgc)) {
|
||||||
msgc->getp = 0;
|
zlog_warn("Cannot fit extended BFD header plus original message contents into ZAPI packet; dropping message");
|
||||||
msgc->endp = zhdrlen + zmsglen;
|
goto stream_failure;
|
||||||
stream_putw_at(msgc, 0, stream_get_endp(msgc));
|
}
|
||||||
|
|
||||||
|
/* 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);
|
zebra_ptm_send_bfdd(msgc);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user