From: Christian Franke Date: Fri, 10 May 2019 11:24:38 +0000 (+0200) Subject: isisd: Don't set subtlv structure if we didn't unpack any subtlvs X-Git-Tag: base_7.2~369^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=bf555bf035a0cbed9520886b42681ed4f2f37f7e;p=matthieu%2Ffrr.git isisd: Don't set subtlv structure if we didn't unpack any subtlvs This ensures deserialized and serialized TLV representation is consistent. --- diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index f72540b811..ae149a0428 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -405,7 +405,7 @@ static int pack_subtlvs(struct isis_subtlvs *subtlvs, struct stream *s) static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len, struct stream *stream, struct sbuf *log, void *dest, - int indent); + int indent, bool *unpacked_known_tlvs); /* Functions related to TLVs 1 Area Addresses */ @@ -796,7 +796,7 @@ static int unpack_item_extended_reach(uint16_t mtid, uint8_t len, size_t subtlv_start = stream_get_getp(s); if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_NE_REACH, subtlv_len, s, - log, NULL, indent + 4)) { + log, NULL, indent + 4, NULL)) { goto out; } @@ -1391,10 +1391,16 @@ static int unpack_item_extended_ip_reach(uint16_t mtid, uint8_t len, } rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH); + bool unpacked_known_tlvs = false; + if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IP_REACH, subtlv_len, s, - log, rv->subtlvs, indent + 4)) { + log, rv->subtlvs, indent + 4, &unpacked_known_tlvs)) { goto out; } + if (!unpacked_known_tlvs) { + isis_free_subtlvs(rv->subtlvs); + rv->subtlvs = NULL; + } } append_item(items, (struct isis_item *)rv); @@ -1870,10 +1876,16 @@ static int unpack_item_ipv6_reach(uint16_t mtid, uint8_t len, struct stream *s, } rv->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH); + bool unpacked_known_tlvs = false; + if (unpack_tlvs(ISIS_CONTEXT_SUBTLV_IPV6_REACH, subtlv_len, s, - log, rv->subtlvs, indent + 4)) { + log, rv->subtlvs, indent + 4, &unpacked_known_tlvs)) { goto out; } + if (!unpacked_known_tlvs) { + isis_free_subtlvs(rv->subtlvs); + rv->subtlvs = NULL; + } } append_item(items, (struct isis_item *)rv); @@ -2971,7 +2983,7 @@ static int unpack_tlv_unknown(enum isis_tlv_context context, uint8_t tlv_type, static int unpack_tlv(enum isis_tlv_context context, size_t avail_len, struct stream *stream, struct sbuf *log, void *dest, - int indent) + int indent, bool *unpacked_known_tlvs) { uint8_t tlv_type, tlv_len; const struct tlv_ops *ops; @@ -3002,6 +3014,8 @@ static int unpack_tlv(enum isis_tlv_context context, size_t avail_len, ops = tlv_table[context][tlv_type]; if (ops && ops->unpack) { + if (unpacked_known_tlvs) + *unpacked_known_tlvs = true; return ops->unpack(context, tlv_type, tlv_len, stream, log, dest, indent + 2); } @@ -3012,7 +3026,7 @@ static int unpack_tlv(enum isis_tlv_context context, size_t avail_len, static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len, struct stream *stream, struct sbuf *log, void *dest, - int indent) + int indent, bool *unpacked_known_tlvs) { int rv; size_t tlv_start, tlv_pos; @@ -3025,7 +3039,7 @@ static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len, while (tlv_pos < avail_len) { rv = unpack_tlv(context, avail_len - tlv_pos, stream, log, dest, - indent + 2); + indent + 2, unpacked_known_tlvs); if (rv) return rv; @@ -3057,7 +3071,7 @@ int isis_unpack_tlvs(size_t avail_len, struct stream *stream, result = isis_alloc_tlvs(); rv = unpack_tlvs(ISIS_CONTEXT_LSP, avail_len, stream, &logbuf, result, - indent); + indent, NULL); *log = sbuf_buf(&logbuf); *dest = result; diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz index 4a89bda84e..6f8bc2218e 100644 Binary files a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz and b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz differ