summaryrefslogtreecommitdiff
path: root/pimd/pim_igmp.c
diff options
context:
space:
mode:
authorMobashshera Rasool <mrasool@vmware.com>2021-07-26 06:35:31 -0700
committerMobashshera Rasool <mrasool@vmware.com>2021-07-27 02:12:30 -0700
commit88ea79ad94389a920811bdfffe115082bcd021ea (patch)
tree65572a76976191df90da6603fd402d9524d4809a /pimd/pim_igmp.c
parent53d7080980bb4e3bf6ef053673ebc560c5412103 (diff)
pimd: Validate the fields before accessing it
This commit is to correct the order in which the fields are accessed while verifying it. First the fields should be verified, and if it is valid then access it. Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
Diffstat (limited to 'pimd/pim_igmp.c')
-rw-r--r--pimd/pim_igmp.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 3325b6ee34..426112d4d6 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -473,15 +473,33 @@ 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)
+bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, size_t *hlen)
{
+ char *igmp_msg;
+ int igmp_msg_len;
+ int msg_type;
+ size_t ip_hlen; /* ip header length in bytes */
+
if (len < sizeof(*ip_hdr)) {
zlog_warn("IGMP packet size=%zu shorter than minimum=%zu", len,
sizeof(*ip_hdr));
return false;
}
+ ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
+ *hlen = ip_hlen;
+
+ if (ip_hlen > len) {
+ zlog_warn(
+ "IGMP packet header claims size %zu, but we only have %zu bytes",
+ ip_hlen, len);
+ return false;
+ }
+
+ igmp_msg = (char *)ip_hdr + ip_hlen;
+ igmp_msg_len = len - ip_hlen;
+ msg_type = *igmp_msg;
+
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);
@@ -514,7 +532,7 @@ bool pim_igmp_verify_header(struct ip *ip_hdr, size_t len, int igmp_msg_len,
int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
{
- struct ip *ip_hdr;
+ struct ip *ip_hdr = (struct ip *)buf;
size_t ip_hlen; /* ip header length in bytes */
char *igmp_msg;
int igmp_msg_len;
@@ -522,16 +540,8 @@ int pim_igmp_packet(struct igmp_sock *igmp, char *buf, size_t len)
char from_str[INET_ADDRSTRLEN];
char to_str[INET_ADDRSTRLEN];
- ip_hdr = (struct ip *)buf;
-
- ip_hlen = ip_hdr->ip_hl << 2; /* ip_hl gives length in 4-byte words */
-
- if (ip_hlen > len) {
- zlog_warn(
- "IGMP packet header claims size %zu, but we only have %zu bytes",
- ip_hlen, len);
+ if (!pim_igmp_verify_header(ip_hdr, len, &ip_hlen))
return -1;
- }
igmp_msg = buf + ip_hlen;
igmp_msg_len = len - ip_hlen;
@@ -547,14 +557,6 @@ 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];