mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-30 04:59:51 +00:00
isisd: don't process invalid prefixes from TLVs
it's possible to feed invalid prefixes (1.2.3.4/40 or dead::beef/200) on IS-IS. if this is not checked, it will later cause an assert in processing. let's simply abort processing the TLV if the prefix is invalid. * isisd/isis_tlv.c: check prefix lengths for validity Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
948b6bef7f
commit
f02a09925d
@ -117,7 +117,7 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
|
|||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
u_char virtual;
|
u_char virtual;
|
||||||
int value_len, retval = ISIS_OK;
|
int value_len, retval = ISIS_OK;
|
||||||
u_char *start = stream, *pnt = stream;
|
u_char *start = stream, *pnt = stream, *endpnt;
|
||||||
|
|
||||||
*found = 0;
|
*found = 0;
|
||||||
memset (tlvs, 0, sizeof (struct tlvs));
|
memset (tlvs, 0, sizeof (struct tlvs));
|
||||||
@ -584,11 +584,20 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
|
|||||||
zlog_debug ("ISIS-TLV (%s): IPv4 extended Reachability length %d",
|
zlog_debug ("ISIS-TLV (%s): IPv4 extended Reachability length %d",
|
||||||
areatag, length);
|
areatag, length);
|
||||||
#endif /* EXTREME_TLV_DEBUG */
|
#endif /* EXTREME_TLV_DEBUG */
|
||||||
|
endpnt = pnt + length;
|
||||||
if (*expected & TLVFLAG_TE_IPV4_REACHABILITY)
|
if (*expected & TLVFLAG_TE_IPV4_REACHABILITY)
|
||||||
{
|
{
|
||||||
while (length > value_len)
|
while (length > value_len)
|
||||||
{
|
{
|
||||||
te_ipv4_reach = (struct te_ipv4_reachability *) pnt;
|
te_ipv4_reach = (struct te_ipv4_reachability *) pnt;
|
||||||
|
if ((te_ipv4_reach->control & 0x3F) > IPV4_MAX_BITLEN)
|
||||||
|
{
|
||||||
|
zlog_warn ("ISIS-TLV (%s): invalid IPv4 extended reach"
|
||||||
|
"ability prefix length %d", areatag,
|
||||||
|
te_ipv4_reach->control & 0x3F);
|
||||||
|
retval = ISIS_WARNING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!tlvs->te_ipv4_reachs)
|
if (!tlvs->te_ipv4_reachs)
|
||||||
tlvs->te_ipv4_reachs = list_new ();
|
tlvs->te_ipv4_reachs = list_new ();
|
||||||
listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach);
|
listnode_add (tlvs->te_ipv4_reachs, te_ipv4_reach);
|
||||||
@ -600,10 +609,8 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
|
|||||||
((((te_ipv4_reach->control & 0x3F) - 1) >> 3) + 1) : 0);
|
((((te_ipv4_reach->control & 0x3F) - 1) >> 3) + 1) : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
pnt = endpnt;
|
||||||
pnt += length;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
@ -648,11 +655,22 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
|
|||||||
* +---------------------------------------------------------------+
|
* +---------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
*found |= TLVFLAG_IPV6_REACHABILITY;
|
*found |= TLVFLAG_IPV6_REACHABILITY;
|
||||||
|
endpnt = pnt + length;
|
||||||
|
|
||||||
if (*expected & TLVFLAG_IPV6_REACHABILITY)
|
if (*expected & TLVFLAG_IPV6_REACHABILITY)
|
||||||
{
|
{
|
||||||
while (length > value_len)
|
while (length > value_len)
|
||||||
{
|
{
|
||||||
ipv6_reach = (struct ipv6_reachability *) pnt;
|
ipv6_reach = (struct ipv6_reachability *) pnt;
|
||||||
|
if (ipv6_reach->prefix_len > IPV6_MAX_BITLEN)
|
||||||
|
{
|
||||||
|
zlog_warn ("ISIS-TLV (%s): invalid IPv6 extended reach"
|
||||||
|
"ability prefix length %d", areatag,
|
||||||
|
ipv6_reach->prefix_len);
|
||||||
|
retval = ISIS_WARNING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
prefix_octets = ((ipv6_reach->prefix_len + 7) / 8);
|
prefix_octets = ((ipv6_reach->prefix_len + 7) / 8);
|
||||||
value_len += prefix_octets + 6;
|
value_len += prefix_octets + 6;
|
||||||
pnt += prefix_octets + 6;
|
pnt += prefix_octets + 6;
|
||||||
@ -662,10 +680,8 @@ parse_tlvs (char *areatag, u_char * stream, int size, u_int32_t * expected,
|
|||||||
listnode_add (tlvs->ipv6_reachs, ipv6_reach);
|
listnode_add (tlvs->ipv6_reachs, ipv6_reach);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
pnt = endpnt;
|
||||||
pnt += length;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user