|
| 1 | +From d5777f8c38a9c61d8992d6ede9a6ea9697fd5ba0 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Ritika Chopra <ritika0313@gmail.com> |
| 3 | +Date: Sun, 5 Oct 2025 21:41:46 -0700 |
| 4 | +Subject: [PATCH] eigrpd: Handling for malformed update packets |
| 5 | + |
| 6 | +-EIGRP daemon was crashing when the code was attempting to read more data from EIGRP update malformed packets than is available in the packets stream. |
| 7 | +-Safety checks have been added before reading from the stream to prevent any crashes |
| 8 | +-This patch addresses the Update packets carrying routes other than IPv4 Internal routes |
| 9 | + |
| 10 | +Signed-off-by: Ritika Chopra <ritika0313@gmail.com> |
| 11 | +--- |
| 12 | + eigrpd/eigrp_packet.c | 6 ++++++ |
| 13 | + eigrpd/eigrp_update.c | 46 ++++++++++++++++++++++++++++++++++++++++--- |
| 14 | + 2 files changed, 49 insertions(+), 3 deletions(-) |
| 15 | + |
| 16 | +diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c |
| 17 | +index e930e8f3c1..f4c16efca5 100644 |
| 18 | +--- a/eigrpd/eigrp_packet.c |
| 19 | ++++ b/eigrpd/eigrp_packet.c |
| 20 | +@@ -551,6 +551,12 @@ void eigrp_read(struct event *thread) |
| 21 | + /* Advance from IP header to EIGRP header (iph->ip_hl has been verified |
| 22 | + by eigrp_recv_packet() to be correct). */ |
| 23 | + |
| 24 | ++ if ((iph->ip_hl * 4) + EIGRP_HEADER_LEN > stream_get_endp(ibuf)) { |
| 25 | ++ zlog_warn("Malformed packet: IP header extends beyond packet data. IP header len = %u endp = %zu", |
| 26 | ++ iph->ip_hl * 4, stream_get_endp(ibuf)); |
| 27 | ++ return; |
| 28 | ++ } |
| 29 | ++ |
| 30 | + stream_forward_getp(ibuf, (iph->ip_hl * 4)); |
| 31 | + eigrph = (struct eigrp_header *)stream_pnt(ibuf); |
| 32 | + |
| 33 | +diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c |
| 34 | +index 7348231c3b..df03ee2d90 100644 |
| 35 | +--- a/eigrpd/eigrp_update.c |
| 36 | ++++ b/eigrpd/eigrp_update.c |
| 37 | +@@ -279,6 +279,13 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, |
| 38 | + |
| 39 | + /*If there is topology information*/ |
| 40 | + while (s->endp > s->getp) { |
| 41 | ++ /* Ensure we have at least 4 bytes for TLV header */ |
| 42 | ++ if (STREAM_READABLE(s) < 4) { |
| 43 | ++ zlog_warn("Malformed packet: Unexpected early end of packet reached, stopping TLV processing"); |
| 44 | ++ stream_forward_getp(s, STREAM_READABLE(s)); |
| 45 | ++ break; |
| 46 | ++ } |
| 47 | ++ |
| 48 | + type = stream_getw(s); |
| 49 | + switch (type) { |
| 50 | + case EIGRP_TLV_IPv4_INT: |
| 51 | +@@ -369,11 +376,44 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, |
| 52 | + * for now, lets just not creash the box |
| 53 | + */ |
| 54 | + default: |
| 55 | ++ /* Handle unknown TLV types gracefully */ |
| 56 | ++ zlog_warn("Unknown TLV type: 0x%04x", type); |
| 57 | ++ |
| 58 | ++ /* Validate we have enough data for TLV length */ |
| 59 | ++ if (STREAM_READABLE(s) < 2) { |
| 60 | ++ zlog_warn("Malformed packet: insufficient data for TLV length, skipping to end"); |
| 61 | ++ stream_forward_getp(s, STREAM_READABLE(s)); |
| 62 | ++ break; |
| 63 | ++ } |
| 64 | ++ |
| 65 | + length = stream_getw(s); |
| 66 | +- // -2 for type, -2 for len |
| 67 | +- for (length -= 4; length; length--) { |
| 68 | +- (void)stream_getc(s); |
| 69 | ++ |
| 70 | ++ /* Validate TLV length */ |
| 71 | ++ if (length < 4) { |
| 72 | ++ zlog_warn("Malformed packet: TLV length too small (%u), skipping to end", length); |
| 73 | ++ stream_forward_getp(s, STREAM_READABLE(s)); |
| 74 | ++ break; |
| 75 | + } |
| 76 | ++ |
| 77 | ++ /* Check for reasonable TLV length */ |
| 78 | ++ if (length > 1024) { |
| 79 | ++ zlog_warn("Malformed packet: TLV length too large (%u), skipping to end", length); |
| 80 | ++ stream_forward_getp(s, STREAM_READABLE(s)); |
| 81 | ++ break; |
| 82 | ++ } |
| 83 | ++ |
| 84 | ++ /* Check if TLV extends beyond packet */ |
| 85 | ++ if (length > STREAM_READABLE(s) + 4) { |
| 86 | ++ zlog_warn("Malformed packet: TLV length (%u) exceeds remaining data (%zu) + 4, skipping to end", |
| 87 | ++ length, STREAM_READABLE(s)); |
| 88 | ++ break; |
| 89 | ++ } |
| 90 | ++ /* Skip current TLV data safely to move on to next TLV */ |
| 91 | ++ if (IS_DEBUG_EIGRP_PACKET(0, RECV)) |
| 92 | ++ zlog_debug("Skipping unknown TLV: type=0x%04x, length=%u", type, length); |
| 93 | ++ stream_forward_getp(s, length - 4); |
| 94 | ++ |
| 95 | ++ |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | +-- |
| 100 | +2.47.3 |
| 101 | + |
0 commit comments