From dbfd865b05d6c4e9395a39bb24f5eaf0b850451c Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 24 Aug 2017 19:15:20 -0400 Subject: [PATCH] eigrpd: Cleanup various SA Issues 1) Handle key value not found on interface 2) Handle various NULL pointer possibilities 3) Fix possible integer overflow 4) Fix memory leak 5) Check return codes on sscanf Signed-off-by: Donald Sharp --- eigrpd/eigrp_dump.c | 6 ++++-- eigrpd/eigrp_hello.c | 6 +++++- eigrpd/eigrp_interface.c | 9 ++++----- eigrpd/eigrp_packet.c | 29 ++++++++++++++++++----------- eigrpd/eigrp_topology.c | 2 +- eigrpd/eigrp_update.c | 3 +++ 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 74515c98cb..98c72668fc 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -295,11 +295,13 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) vty_out(vty, "%s, ", prefix2str(tn->destination, buffer, PREFIX_STRLEN)); - vty_out(vty, "%u successors, ", successors->count); + vty_out(vty, "%u successors, ", + (successors) ? successors->count : 0); vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance, tn->serno); - list_delete(successors); + if (successors) + list_delete(successors); } void show_ip_eigrp_neighbor_entry(struct vty *vty, struct eigrp *eigrp, diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index ef10ebf54c..49647c6b85 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -412,11 +412,15 @@ void eigrp_sw_version_initialize(void) { char ver_string[] = VERSION; char *dash = strstr(ver_string, "-"); + int ret; if (dash) dash[0] = '\0'; - sscanf(ver_string, "%d.%d", &FRR_MAJOR, &FRR_MINOR); + ret = sscanf(ver_string, "%d.%d", &FRR_MAJOR, &FRR_MINOR); + if (ret != 2) + zlog_err("Did not Properly parse %s, please fix VERSION string", + VERSION); } /** diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index ae9ec293ce..59b1724f85 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -249,15 +249,14 @@ int eigrp_if_up(struct eigrp_interface *ei) struct eigrp_metrics metric; struct eigrp_interface *ei2; struct listnode *node, *nnode; - struct eigrp *eigrp = eigrp_lookup(); + struct eigrp *eigrp; if (ei == NULL) return 0; - if (eigrp != NULL) - eigrp_adjust_sndbuflen(eigrp, ei->ifp->mtu); - else - zlog_warn("%s: eigrp_lookup () returned NULL", __func__); + eigrp = ei->eigrp; + eigrp_adjust_sndbuflen(eigrp, ei->ifp->mtu); + eigrp_if_stream_set(ei); /* Set multicast memberships appropriately for new state. */ diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 68e7cdcbbe..8a7d4d9587 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -193,6 +193,12 @@ int eigrp_check_md5_digest(struct stream *s, if (keychain) key = key_lookup_for_send(keychain); + if (!key) { + zlog_warn("Interface %s: Expected key value not found in config", + nbr->ei->ifp->name); + return 0; + } + memset(&ctx, 0, sizeof(ctx)); MD5Init(&ctx); @@ -229,8 +235,7 @@ int eigrp_check_md5_digest(struct stream *s, } /* save neighbor's crypt_seqnum */ - if (nbr) - nbr->crypt_seqnum = authTLV->key_sequence; + nbr->crypt_seqnum = authTLV->key_sequence; return 1; } @@ -240,10 +245,11 @@ int eigrp_make_sha256_digest(struct eigrp_interface *ei, struct stream *s, { struct key *key = NULL; struct keychain *keychain; - char *source_ip; + char source_ip[PREFIX_STRLEN]; unsigned char digest[EIGRP_AUTH_TYPE_SHA256_LEN]; unsigned char buffer[1 + PLAINTEXT_LENGTH + 45 + 1] = {0}; + HMAC_SHA256_CTX ctx; void *ibuf; size_t backup_get, backup_end; @@ -263,11 +269,13 @@ int eigrp_make_sha256_digest(struct eigrp_interface *ei, struct stream *s, if (keychain) key = key_lookup_for_send(keychain); - // saved_len[index] = strnzcpyn(saved_key[index], key, - // PLAINTEXT_LENGTH + 1); + if (!key) { + zlog_warn("Interface %s: Expected key value not found in config", + ei->ifp->name); + return 0; + } - source_ip = calloc(16, sizeof(char)); - inet_ntop(AF_INET, &ei->address->u.prefix4, source_ip, 16); + inet_ntop(AF_INET, &ei->address->u.prefix4, source_ip, PREFIX_STRLEN); memset(&ctx, 0, sizeof(ctx)); buffer[0] = '\n'; @@ -287,7 +295,6 @@ int eigrp_make_sha256_digest(struct eigrp_interface *ei, struct stream *s, stream_set_endp(s, backup_end); eigrp_authTLV_SHA256_free(auth_TLV); - free(source_ip); return EIGRP_AUTH_TYPE_SHA256_LEN; } @@ -613,10 +620,10 @@ int eigrp_read(struct thread *thread) opcode = eigrph->opcode; if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) { - char src[100], dst[100]; + char src[PREFIX_STRLEN], dst[PREFIX_STRLEN]; - strcpy(src, inet_ntoa(iph->ip_src)); - strcpy(dst, inet_ntoa(iph->ip_dst)); + strncpy(src, inet_ntoa(iph->ip_src), PREFIX_STRLEN); + strncpy(dst, inet_ntoa(iph->ip_dst), PREFIX_STRLEN); zlog_debug("Received [%s][%d/%d] length [%u] via [%s] src [%s] dst [%s]", lookup_msg(eigrp_packet_type_str, opcode, NULL), ntohl(eigrph->sequence), ntohl(eigrph->ack), length, diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 64e65b694c..8390bfc66e 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -444,7 +444,7 @@ void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest) for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) { if (((uint64_t)entry->distance - <= (uint64_t)(dest->distance * eigrp->variance)) + <= (uint64_t)dest->distance * (uint64_t)eigrp->variance) && entry->distance != EIGRP_MAX_METRIC) // is successor { entry->flags |= EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index d6a1134124..430068496b 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -443,6 +443,9 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, eigrp_query_send_all(eigrp); eigrp_update_send_all(eigrp, ei); + + if (nbr_prefixes) + list_delete(nbr_prefixes); } /*send EIGRP Update packet*/ -- 2.39.5