diff options
author | Olivier Dugeon <olivier.dugeon@orange.com> | 2020-04-14 19:49:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-14 19:49:53 +0200 |
commit | 0b4b9672b737c8fb75346523819215ca77d88288 (patch) | |
tree | a09e3e9c4b3a3fb123728e7fe8a9926596402f75 /ospfd/ospf_packet.c | |
parent | Merge pull request #6197 from sworleys/PBR-Atomic (diff) | |
parent | ospfd: router LSA link info missing length check (diff) | |
download | frr-0b4b9672b737c8fb75346523819215ca77d88288.tar.xz frr-0b4b9672b737c8fb75346523819215ca77d88288.zip |
Merge pull request #6218 from qlyoung/fix-ospf-router-lsa-missing-length-check
ospfd: router LSA link info missing length check
Diffstat (limited to 'ospfd/ospf_packet.c')
-rw-r--r-- | ospfd/ospf_packet.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 34e5e2a11..a39d19cc5 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2604,7 +2604,7 @@ static unsigned ospf_router_lsa_links_examin(struct router_lsa_link *link, { unsigned counted_links = 0, thislinklen; - while (linkbytes) { + while (linkbytes >= OSPF_ROUTER_LSA_LINK_SIZE) { thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count; if (thislinklen > linkbytes) { @@ -2642,26 +2642,32 @@ static unsigned ospf_lsa_examin(struct lsa_header *lsah, const uint16_t lsalen, return MSG_NG; } switch (lsah->type) { - case OSPF_ROUTER_LSA: - /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 - * (12+)-byte link blocks */ - if (headeronly) { - ret = (lsalen - OSPF_LSA_HEADER_SIZE - - OSPF_ROUTER_LSA_MIN_SIZE) - % 4 - ? MSG_NG - : MSG_OK; - break; - } + case OSPF_ROUTER_LSA: { + /* + * RFC2328 A.4.2, LSA header + 4 bytes followed by N>=0 + * (12+)-byte link blocks + */ + size_t linkbytes_len = lsalen - OSPF_LSA_HEADER_SIZE + - OSPF_ROUTER_LSA_MIN_SIZE; + + /* + * LSA link blocks are variable length but always multiples of + * 4; basic sanity check + */ + if (linkbytes_len % 4 != 0) + return MSG_NG; + + if (headeronly) + return MSG_OK; + rlsa = (struct router_lsa *)lsah; + ret = ospf_router_lsa_links_examin( (struct router_lsa_link *)rlsa->link, - lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic - header, "flags", - 0, "# links" */ - ntohs(rlsa->links) /* 16 bits */ - ); + linkbytes_len, + ntohs(rlsa->links)); break; + } case OSPF_AS_EXTERNAL_LSA: /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long * blocks */ |