From ff4ad8709b087b8e1c35ab5008eb34e0af9cd18a Mon Sep 17 00:00:00 2001 From: Mobashshera Rasool Date: Fri, 16 Jul 2021 11:55:56 +0000 Subject: [PATCH 1/3] pimd: Abstracting header verification for igmp Moving the header verification checks inside a function. Signed-off-by: Mobashshera Rasool --- pimd/pim_igmp.c | 45 +++++++++++++++++++++++++++++---------------- pimd/pim_igmp.h | 3 ++- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 73dcdbddb4..36f044b16f 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -469,6 +469,24 @@ static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from, return 0; } +bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len, + int msg_type) +{ + if (len < sizeof(*ip_hdr)) { + zlog_warn("IGMP packet size=%zu shorter than minimum=%zu", len, + sizeof(*ip_hdr)); + return false; + } + + if (igmp_msg_len < PIM_IGMP_MIN_LEN) { + zlog_warn("IGMP message size=%d shorter than minimum=%d", + igmp_msg_len, PIM_IGMP_MIN_LEN); + return false; + } + + return true; +} + int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) { struct ip *ip_hdr; @@ -479,17 +497,8 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) char from_str[INET_ADDRSTRLEN]; char to_str[INET_ADDRSTRLEN]; - if (len < sizeof(*ip_hdr)) { - zlog_warn("IGMP packet size=%zu shorter than minimum=%zu", len, - sizeof(*ip_hdr)); - return -1; - } - ip_hdr = (struct ip *)buf; - pim_inet4_dump("", ip_hdr->ip_src, from_str, sizeof(from_str)); - pim_inet4_dump("", ip_hdr->ip_dst, to_str, sizeof(to_str)); - ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */ if (ip_hlen > len) { @@ -501,15 +510,11 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) igmp_msg = buf + ip_hlen; igmp_msg_len = len - ip_hlen; - - if (igmp_msg_len < PIM_IGMP_MIN_LEN) { - zlog_warn("IGMP message size=%d shorter than minimum=%d", - igmp_msg_len, PIM_IGMP_MIN_LEN); - return -1; - } - msg_type = *igmp_msg; + pim_inet4_dump("", ip_hdr->ip_src, from_str, sizeof(from_str)); + pim_inet4_dump("", ip_hdr->ip_dst, to_str, sizeof(to_str)); + if (PIM_DEBUG_IGMP_PACKETS) { zlog_debug( "Recv IGMP packet from %s to %s on %s: size=%zu ttl=%d msg_type=%d msg_size=%d", @@ -517,6 +522,14 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len) msg_type, igmp_msg_len); } + if (!pim_igmp_verify_header(ip_hdr, len, igmp_msg_len, msg_type)) { + zlog_warn( + "Recv IGMP packet from %s to %s on %s: size=%zu ttl=%u msg_type=%d msg_size=%d", + from_str, to_str, igmp->interface->name, len, + ip_hdr->ip_ttl, msg_type, igmp_msg_len); + return -1; + } + switch (msg_type) { case PIM_IGMP_MEMBERSHIP_QUERY: { int max_resp_code = igmp_msg[1]; diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h index a0681128c0..88324b7937 100644 --- a/pimd/pim_igmp.h +++ b/pimd/pim_igmp.h @@ -116,7 +116,8 @@ void igmp_sock_delete(struct igmp_sock *igmp); void igmp_sock_free(struct igmp_sock *igmp); void igmp_sock_delete_all(struct interface *ifp); int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len); - +bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len, + int msg_type); void pim_igmp_general_query_on(struct igmp_sock *igmp); void pim_igmp_general_query_off(struct igmp_sock *igmp); void pim_igmp_other_querier_timer_on(struct igmp_sock *igmp); From 54d7bf0cc6c487610c6d3fa53c9fa678b2f53d75 Mon Sep 17 00:00:00 2001 From: Mobashshera Rasool Date: Mon, 19 Jul 2021 19:29:09 +0000 Subject: [PATCH 2/3] pimd: Add TTL check for IGMP conformance IGMPv3 packets with invalid TTL should be dropped. Test Case ID: 4.10 TEST_DESCRIPTION Every IGMP message described in this document is sent with an IP Time-to-Live of 1 (Tests that IGMPv3 Membership Report Message conforms to above statement) TEST_REFERENCE NEGATIVE: RFC 3376, IGMP Version 3, s4 p7 Message Formats Issue: #9070 Signed-off-by: Mobashshera Rasool --- pimd/pim_igmp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 36f044b16f..069c515971 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -484,6 +484,16 @@ bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len, return false; } + if ((msg_type != PIM_IGMP_MTRACE_RESPONSE) + && (msg_type != PIM_IGMP_MTRACE_QUERY_REQUEST)) { + if (ip_hdr->ip_ttl != 1) { + zlog_warn( + "Recv IGMP packet with invalid ttl=%u, discarding the packet", + ip_hdr->ip_ttl); + return -1; + } + } + return true; } From e39f74d04a1e61bd75a9519a8484ce5ae7f22b33 Mon Sep 17 00:00:00 2001 From: Mobashshera Rasool Date: Mon, 19 Jul 2021 19:31:56 +0000 Subject: [PATCH 3/3] pimd: Add TOS check for IGMP conformance IGMPv3 packets with invalid TOS should be dropped. Test Case ID: 4.10 TEST_DESCRIPTION Every IGMP message described in this document is sent with IP Precedence of Internetwork Control (e.g., Type of Service 0xc0) (Tests that IGMPv3 Membership Query Message conforms to above statement) TEST_REFERENCE NEGATIVE: RFC 3376, IGMP Version 3, s4 p7 Message Formats Issue: #9071 Signed-off-by: Mobashshera Rasool --- pimd/pim_igmp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 069c515971..477cf991b4 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -494,6 +494,17 @@ bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len, } } + if ((msg_type == PIM_IGMP_V3_MEMBERSHIP_REPORT) + || ((msg_type == PIM_IGMP_MEMBERSHIP_QUERY) + && (igmp_msg_len >= IGMP_V3_SOURCES_OFFSET))) { + /* All IGMPv3 messages must be received with TOS set to 0xC0*/ + if (ip_hdr->ip_tos != IPTOS_PREC_INTERNETCONTROL) { + zlog_warn("Received IGMP Packet with invalid TOS %u", + ip_hdr->ip_tos); + return -1; + } + } + return true; }