diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-09-24 20:40:08 -0400 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-09-25 09:26:24 -0400 |
| commit | 0f9f74baeb97f437d7acf7feda0f400d50943c4c (patch) | |
| tree | de20395258870f3baa322acce995f8fbab74687d /ospf6d/ospf6_message.c | |
| parent | b53c5f1ab47d05a85b254e88f12be4ac5c71d42a (diff) | |
ospf6d: Prevent use after free
the for (ALL_LSDB...) macro was iterating over lsa,
when lsa had just been freed in these functions.
Remove the macro and make the adjustments saving lsa_next
before the free.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'ospf6d/ospf6_message.c')
| -rw-r--r-- | ospf6d/ospf6_message.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 4acb5e3b2e..da42a24252 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1866,7 +1866,8 @@ int ospf6_dbdesc_send(struct thread *thread) int ospf6_dbdesc_send_newone(struct thread *thread) { struct ospf6_neighbor *on; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsa_next; + const struct route_node *iterend; unsigned int size = 0; on = (struct ospf6_neighbor *)THREAD_ARG(thread); @@ -1876,7 +1877,10 @@ int ospf6_dbdesc_send_newone(struct thread *thread) structure) so that ospf6_send_dbdesc () can send those LSAs */ size = sizeof(struct ospf6_lsa_header) + sizeof(struct ospf6_dbdesc); - for (ALL_LSDB(on->summary_list, lsa)) { + + for (iterend = ospf6_lsdb_head(on->summary_list, 0, 0, 0, &lsa); lsa; + lsa = lsa_next) { + lsa_next = ospf6_lsdb_next(iterend, lsa); if (size + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { ospf6_lsdb_lsa_unlock(lsa); @@ -2019,7 +2023,8 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) struct ospf6_lsupdate *lsupdate; uint8_t *p; int lsa_cnt; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsa_next; + const struct route_node *iterend; on = (struct ospf6_neighbor *)THREAD_ARG(thread); on->thread_send_lsupdate = (struct thread *)NULL; @@ -2044,7 +2049,9 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) /* lsupdate_list lists those LSA which doesn't need to be retransmitted. remove those from the list */ - for (ALL_LSDB(on->lsupdate_list, lsa)) { + for (iterend = ospf6_lsdb_head(on->lsupdate_list, 0, 0, 0, &lsa); lsa; + lsa = lsa_next) { + lsa_next = ospf6_lsdb_next(iterend, lsa); /* MTU check */ if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header)) > ospf6_packet_max(on->ospf6_if)) { @@ -2074,7 +2081,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) p += OSPF6_LSA_SIZE(lsa->header); lsa_cnt++; - assert(lsa->lock == 2); + assert(lsa->lock == 1); ospf6_lsdb_remove(lsa, on->lsupdate_list); } @@ -2202,7 +2209,8 @@ int ospf6_lsupdate_send_interface(struct thread *thread) struct ospf6_lsupdate *lsupdate; uint8_t *p; int lsa_cnt; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsa_next; + const struct route_node *iterend; oi = (struct ospf6_interface *)THREAD_ARG(thread); oi->thread_send_lsupdate = (struct thread *)NULL; @@ -2228,7 +2236,9 @@ int ospf6_lsupdate_send_interface(struct thread *thread) p = (uint8_t *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); lsa_cnt = 0; - for (ALL_LSDB(oi->lsupdate_list, lsa)) { + for (iterend = ospf6_lsdb_head(oi->lsupdate_list, 0, 0, 0, &lsa); lsa; + lsa = lsa_next) { + lsa_next = ospf6_lsdb_next(iterend, lsa); /* MTU check */ if ((p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE(lsa->header))) > ospf6_packet_max(oi)) { @@ -2263,7 +2273,7 @@ int ospf6_lsupdate_send_interface(struct thread *thread) p += OSPF6_LSA_SIZE(lsa->header); lsa_cnt++; - assert(lsa->lock == 2); + assert(lsa->lock == 1); ospf6_lsdb_remove(lsa, oi->lsupdate_list); } @@ -2289,7 +2299,8 @@ int ospf6_lsack_send_neighbor(struct thread *thread) struct ospf6_neighbor *on; struct ospf6_header *oh; uint8_t *p; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsa_next; + const struct route_node *iterend; int lsa_cnt = 0; on = (struct ospf6_neighbor *)THREAD_ARG(thread); @@ -2312,7 +2323,9 @@ int ospf6_lsack_send_neighbor(struct thread *thread) p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header)); - for (ALL_LSDB(on->lsack_list, lsa)) { + for (iterend = ospf6_lsdb_head(on->lsack_list, 0, 0, 0, &lsa); lsa; + lsa = lsa_next) { + lsa_next = ospf6_lsdb_next(iterend, lsa); /* MTU check */ if (p - sendbuf + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if)) { @@ -2340,7 +2353,7 @@ int ospf6_lsack_send_neighbor(struct thread *thread) memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); p += sizeof(struct ospf6_lsa_header); - assert(lsa->lock == 2); + assert(lsa->lock == 1); ospf6_lsdb_remove(lsa, on->lsack_list); lsa_cnt++; } @@ -2367,7 +2380,8 @@ int ospf6_lsack_send_interface(struct thread *thread) struct ospf6_interface *oi; struct ospf6_header *oh; uint8_t *p; - struct ospf6_lsa *lsa; + struct ospf6_lsa *lsa, *lsa_next; + const struct route_node *iterend; int lsa_cnt = 0; oi = (struct ospf6_interface *)THREAD_ARG(thread); @@ -2391,7 +2405,9 @@ int ospf6_lsack_send_interface(struct thread *thread) p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header)); - for (ALL_LSDB(oi->lsack_list, lsa)) { + for (iterend = ospf6_lsdb_head(oi->lsack_list, 0, 0, 0, &lsa); lsa; + lsa = lsa_next) { + lsa_next = ospf6_lsdb_next(iterend, lsa); /* MTU check */ if (p - sendbuf + sizeof(struct ospf6_lsa_header) > ospf6_packet_max(oi)) { @@ -2409,7 +2425,7 @@ int ospf6_lsack_send_interface(struct thread *thread) memcpy(p, lsa->header, sizeof(struct ospf6_lsa_header)); p += sizeof(struct ospf6_lsa_header); - assert(lsa->lock == 2); + assert(lsa->lock == 1); ospf6_lsdb_remove(lsa, oi->lsack_list); lsa_cnt++; } |
