summaryrefslogtreecommitdiffstats
path: root/ospf6d
diff options
context:
space:
mode:
authorMartin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>2021-01-29 16:40:04 +0100
committerMartin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>2021-01-29 19:38:17 +0100
commit100f2989b351d337a28742a69e82e4b4b5e16ba0 (patch)
tree1d35a9927eb82b60e109cde29c4b8887bb605ad2 /ospf6d
parentMerge pull request #7953 from mjstapp/fix_more_ntoa (diff)
downloadfrr-100f2989b351d337a28742a69e82e4b4b5e16ba0.tar.xz
frr-100f2989b351d337a28742a69e82e4b4b5e16ba0.zip
ospf6d: Fix LSA formatting out-of-bounds access
Check whether full struct ospf6_router_lsdesc/ospf6_prefix is accessible before accessing its contents. Previously, we only checked for the first byte in ospf6_router_lsa_get_nbr_id() or not even that (due to an additional off-by-one error) in ospf6_link_lsa_get_prefix_str() and ospf6_intra_prefix_lsa_get_prefix_str(). Also check *before* accessing the first prefix instead of starting the checks only at the 2nd prefix. The previous code could cause out-of-bounds accesses with valid LSAs in case of ospf6_link_lsa_get_prefix_str() and ospf6_intra_prefix_lsa_get_prefix_str() and with specially crafted LSAs (bad length field) in case of ospf6_router_lsa_get_nbr_id(). Signed-off-by: Martin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_intra.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index 01e4b31c4..a8a469136 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -76,7 +76,8 @@ static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf,
*)(start
+ pos * (sizeof(struct
ospf6_router_lsdesc)));
- if ((char *)lsdesc < end) {
+ if ((char *)lsdesc + sizeof(struct ospf6_router_lsdesc)
+ <= end) {
if (buf && (buflen > INET_ADDRSTRLEN * 2)) {
inet_ntop(AF_INET,
&lsdesc->neighbor_interface_id, buf1,
@@ -650,7 +651,7 @@ static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf,
end = (char *)lsa->header + ntohs(lsa->header->length);
current = start;
- do {
+ while (current + sizeof(struct ospf6_prefix) <= end) {
prefix = (struct ospf6_prefix *)current;
if (prefix->prefix_length == 0
|| current + OSPF6_PREFIX_SIZE(prefix) > end) {
@@ -668,7 +669,7 @@ static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf,
inet_ntop(AF_INET6, &in6, buf, buflen);
return (buf);
}
- } while (current <= end);
+ }
}
return NULL;
}
@@ -879,7 +880,7 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
end = (char *)lsa->header + ntohs(lsa->header->length);
current = start;
- do {
+ while (current + sizeof(struct ospf6_prefix) <= end) {
prefix = (struct ospf6_prefix *)current;
if (prefix->prefix_length == 0
|| current + OSPF6_PREFIX_SIZE(prefix) > end) {
@@ -899,7 +900,7 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
prefix->prefix_length);
return (buf);
}
- } while (current <= end);
+ }
}
return (buf);
}