]> git.proxmox.com Git - mirror_frr.git/commitdiff
pimd: Various buffer overflow reads and crashes
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 Nov 2019 00:36:19 +0000 (19:36 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 Nov 2019 13:31:27 +0000 (08:31 -0500)
A variety of buffer overflow reads and crashes
that could occur if you fed bad info into pim.

1) When type is setup incorrectly we were printing the first 8 bytes
of the pim_parse_addr_source, but the min encoding length is
4 bytes.  As such we will read beyond end of buffer.

2) The RP(pim, grp) macro can return a NULL value
Do not automatically assume that we can deref
the data.

3) BSM parsing was not properly sanitizing data input from wire
and we could enter into situations where we would read beyond
the end of the buffer.  Prevent this from happening, we are
probably left in a bad way.

4) The received bit length cannot be greater than 32 bits,
refuse to allow it to happen.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_join.c
pimd/pim_rp.c
pimd/pim_tlv.c

index cbacaf3ea872733b4c749c3875e2230cf6c68bb2..3cf82c0820555761a011b5a5f753590ce4c742fe 100644 (file)
@@ -83,6 +83,11 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
            && (source_flags & PIM_WILDCARD_BIT_MASK)) {
                struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
 
+               if (!rp) {
+                       zlog_warn("%s: Lookup of RP failed for %pSG4",
+                                 __PRETTY_FUNCTION__, sg);
+                       return;
+               }
                /*
                 * If the RP sent in the message is not
                 * our RP for the group, drop the message
@@ -139,6 +144,12 @@ static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
            && (source_flags & PIM_WILDCARD_BIT_MASK)) {
                struct pim_rpf *rp = RP(pim_ifp->pim, sg->grp);
 
+               if (!rp) {
+                       if (PIM_DEBUG_PIM_TRACE)
+                               zlog_debug("%s: RP for %pSG4 completely failed lookup",
+                                          __PRETTY_FUNCTION__, sg);
+                       return;
+               }
                // Ignoring Prune *,G's at the moment.
                if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr)
                        return;
index 14643743ad8fc4fd28f7c38f0beabc7b81244d17..14b70d4ba79d3a49fadb669a2b0e71742f1da933 100644 (file)
@@ -1002,8 +1002,8 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, struct in_addr *up,
 
        rp_info = pim_rp_find_match_group(pim, &g);
 
-       if ((pim_rpf_addr_is_inaddr_none(&rp_info->rp))
-           && (source.s_addr == INADDR_ANY)) {
+       if (!rp_info || ((pim_rpf_addr_is_inaddr_none(&rp_info->rp))
+                        && (source.s_addr == INADDR_ANY))) {
                if (PIM_DEBUG_PIM_NHT_RP)
                        zlog_debug("%s: Received a (*,G) with no RP configured",
                                   __PRETTY_FUNCTION__);
index d93a360448edb06fec21146fd20dcecefbe76158..09851c4a916f109899f74910d662b66fcf129cf1 100644 (file)
@@ -603,9 +603,9 @@ int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
 
        if (type) {
                zlog_warn(
-                       "%s: unknown source address encoding type=%d: %02x%02x%02x%02x%02x%02x%02x%02x",
+                       "%s: unknown source address encoding type=%d: %02x%02x%02x%02x",
                        __PRETTY_FUNCTION__, type, buf[0], buf[1], buf[2],
-                       buf[3], buf[4], buf[5], buf[6], buf[7]);
+                       buf[3]);
                return -2;
        }
 
@@ -644,9 +644,9 @@ int pim_parse_addr_source(struct prefix_sg *sg, uint8_t *flags,
                break;
        default: {
                zlog_warn(
-                       "%s: unknown source address encoding family=%d: %02x%02x%02x%02x%02x%02x%02x%02x",
+                       "%s: unknown source address encoding family=%d: %02x%02x%02x%02x",
                        __PRETTY_FUNCTION__, family, buf[0], buf[1], buf[2],
-                       buf[3], buf[4], buf[5], buf[6], buf[7]);
+                       buf[3]);
                return -5;
        }
        }