]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: fix unaligned accesses 11597/head
authorDavid Lamparter <equinox@opensourcerouting.org>
Tue, 12 Jul 2022 10:47:46 +0000 (12:47 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Tue, 12 Jul 2022 10:48:04 +0000 (12:48 +0200)
These are in packed structs at weird offsets (e.g. 2 bytes), and as such
need a memcpy to get them into proper alignment.

It'd be even better if the pimd code used proper de/serialization, but
let's get this improved one step at a time.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
pimd/pim_bsm.c
pimd/pim_cmd.c

index 1a13f79e71ba86874d40c04800fcf1ad75374d1f..1f7dd2f3f92be2e13c46d7ae75c696eca9af98e9 100644 (file)
@@ -1280,6 +1280,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
        struct bsm_frag *bsfrag;
        struct pim_instance *pim;
        uint16_t frag_tag;
+       pim_addr bsr_addr;
        bool empty_bsm = false;
 
        /* BSM Packet acceptance validation */
@@ -1330,6 +1331,8 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
        }
        pim->global_scope.hashMasklen = bshdr->hm_len;
        frag_tag = ntohs(bshdr->frag_tag);
+       /* NB: bshdr->bsr_addr.addr is packed/unaligned => memcpy */
+       memcpy(&bsr_addr, &bshdr->bsr_addr.addr, sizeof(bsr_addr));
 
        /* Identify empty BSM */
        if ((buf_size - PIM_BSM_HDR_LEN - PIM_MSG_HEADER_LEN) < PIM_BSM_GRP_LEN)
@@ -1351,7 +1354,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
        }
 
        /* Drop if bsr is not preferred bsr */
-       if (!is_preferred_bsr(pim, bshdr->bsr_addr.addr, bshdr->bsr_prio)) {
+       if (!is_preferred_bsr(pim, bsr_addr, bshdr->bsr_prio)) {
                if (PIM_DEBUG_BSM)
                        zlog_debug("%s : Received a non-preferred BSM",
                                   __func__);
@@ -1368,8 +1371,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
                        if (PIM_DEBUG_BSM)
                                zlog_debug(
                                        "%s : nofwd_bsm received on %pPAs when accpt_nofwd_bsm false",
-                                       __func__,
-                                       (pim_addr *)&bshdr->bsr_addr.addr);
+                                       __func__, &bsr_addr);
                        pim->bsm_dropped++;
                        pim_ifp->pim_ifstat_ucast_bsm_cfg_miss++;
                        return -1;
@@ -1381,13 +1383,12 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
                 * match RPF towards the BSR's IP address, or they have
                 * no-forward set
                 */
-               if (!no_fwd && !pim_nht_bsr_rpf_check(pim, bshdr->bsr_addr.addr,
-                                                     ifp, sg->src)) {
+               if (!no_fwd &&
+                   !pim_nht_bsr_rpf_check(pim, bsr_addr, ifp, sg->src)) {
                        if (PIM_DEBUG_BSM)
                                zlog_debug(
                                        "BSM check: RPF to BSR %pPAs is not %pPA%%%s",
-                                       (pim_addr *)&bshdr->bsr_addr.addr,
-                                       &sg->src, ifp->name);
+                                       &bsr_addr, &sg->src, ifp->name);
                        pim->bsm_dropped++;
                        return -1;
                }
@@ -1446,7 +1447,7 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
        }
 
        /* update the scope information from bsm */
-       pim_bsm_update(pim, bshdr->bsr_addr.addr, bshdr->bsr_prio);
+       pim_bsm_update(pim, bsr_addr, bshdr->bsr_prio);
 
        if (!no_fwd) {
                pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
index 813ef4ca3745588db17028497150ab6796ab3c84..843b24efde87a407925c6c5c1c687b15074c23e2 100644 (file)
@@ -864,6 +864,7 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
                struct bsmmsg_rpinfo *bsm_rpinfo;
                struct prefix grp;
                struct bsm_hdr *hdr;
+               pim_addr bsr_addr;
                uint32_t offset = 0;
                uint8_t *buf;
                uint32_t len = 0;
@@ -877,15 +878,16 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
                len -= PIM_MSG_HEADER_LEN;
 
                hdr = (struct bsm_hdr *)buf;
+               /* NB: bshdr->bsr_addr.addr is packed/unaligned => memcpy */
+               memcpy(&bsr_addr, &hdr->bsr_addr.addr, sizeof(bsr_addr));
 
                /* BSM starts with bsr header */
                buf += sizeof(struct bsm_hdr);
                len -= sizeof(struct bsm_hdr);
 
                if (uj) {
-                       json_object_string_addf(
-                               json, "BSR address", "%pPA",
-                               (pim_addr *)&hdr->bsr_addr.addr);
+                       json_object_string_addf(json, "BSR address", "%pPA",
+                                               &bsr_addr);
                        json_object_int_add(json, "BSR priority",
                                            hdr->bsr_prio);
                        json_object_int_add(json, "Hashmask Length",
@@ -897,9 +899,9 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
                        vty_out(vty, "------------------\n");
                        vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
                                "BSR-Priority", "Hashmask-len", "Fragment-Tag");
-                       vty_out(vty, "%-15pPA %-15d %-15d %-15d\n",
-                               (pim_addr *)&hdr->bsr_addr.addr, hdr->bsr_prio,
-                               hdr->hm_len, ntohs(hdr->frag_tag));
+                       vty_out(vty, "%-15pPA %-15d %-15d %-15d\n", &bsr_addr,
+                               hdr->bsr_prio, hdr->hm_len,
+                               ntohs(hdr->frag_tag));
                }
 
                vty_out(vty, "\n");
@@ -957,7 +959,12 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
                                        "RpAddress     HoldTime     Priority\n");
 
                        while (frag_rp_cnt--) {
+                               pim_addr rp_addr;
+
                                bsm_rpinfo = (struct bsmmsg_rpinfo *)buf;
+                               /* unaligned, again */
+                               memcpy(&rp_addr, &bsm_rpinfo->rpaddr,
+                                      sizeof(rp_addr));
 
                                buf += sizeof(struct bsmmsg_rpinfo);
                                offset += sizeof(struct bsmmsg_rpinfo);
@@ -966,8 +973,7 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
                                        json_row = json_object_new_object();
                                        json_object_string_addf(
                                                json_row, "Rp Address", "%pPA",
-                                               (pim_addr *)&bsm_rpinfo->rpaddr
-                                                       .addr);
+                                               &rp_addr);
                                        json_object_int_add(
                                                json_row, "Rp HoldTime",
                                                ntohs(bsm_rpinfo->rp_holdtime));
@@ -976,12 +982,10 @@ static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
                                                            bsm_rpinfo->rp_pri);
                                        json_object_object_addf(
                                                json_group, json_row, "%pPA",
-                                               (pim_addr *)&bsm_rpinfo->rpaddr
-                                                       .addr);
+                                               &rp_addr);
                                } else {
                                        vty_out(vty, "%-15pPA %-12d %d\n",
-                                               (pim_addr *)&bsm_rpinfo->rpaddr
-                                                       .addr,
+                                               &rp_addr,
                                                ntohs(bsm_rpinfo->rp_holdtime),
                                                bsm_rpinfo->rp_pri);
                                }