diff options
| author | Louis Scalbert <louis.scalbert@6wind.com> | 2024-09-12 09:31:49 +0200 | 
|---|---|---|
| committer | Mergify <37929162+mergify[bot]@users.noreply.github.com> | 2024-09-17 12:35:18 +0000 | 
| commit | 06e5366187bfd174f116c4d65890475d022e0b65 (patch) | |
| tree | 6fdf01158e0554e288ac345cccb6b261adb6fee8 /isisd | |
| parent | 212e152f57ced2420b5420ce6091898e43458e0d (diff) | |
isisd: fix rcap tlv double-free crash
A double-free crash happens when a subTLV of the "Router Capability"
TLV is not readable and a previous "Router Capability" TLV was read.
rcap was supposed to be freed later by isis_free_tlvs() ->
free_tlv_router_cap(). In 78774bbcd5 ("isisd: add isis flex-algo lsp
advertisement"), this was not the case because rcap was not saved to
tlvs->router_cap when the function returned early because of a subTLV
length issue.
Always set tlvs->router_cap to free the memory.
Note that this patch has the consequence that in case of subTLV error,
the previously read "Router Capability" subTLVs are kept in memory.
Fixes: 49efc80d34 ("isisd: Ensure rcap is freed in error case")
Fixes: 78774bbcd5 ("isisd: add isis flex-algo lsp advertisement")
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
(cherry picked from commit d61758140d33972c10ecbb72d0a3e528049dd8d6)
Diffstat (limited to 'isisd')
| -rw-r--r-- | isisd/isis_tlvs.c | 17 | 
1 files changed, 8 insertions, 9 deletions
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 85664e4f20..b26d63da78 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -5386,16 +5386,17 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,  		return 0;  	} -	if (tlvs->router_cap) -		/* Multiple Router Capability found */ -		rcap = tlvs->router_cap; -	else { -		/* Allocate router cap structure and initialize SR Algorithms */ -		rcap = XCALLOC(MTYPE_ISIS_TLV, sizeof(struct isis_router_cap)); +	if (!tlvs->router_cap) { +		/* First Router Capability TLV. +		 * Allocate router cap structure and initialize SR Algorithms */ +		tlvs->router_cap = XCALLOC(MTYPE_ISIS_TLV, +					   sizeof(struct isis_router_cap));  		for (int i = 0; i < SR_ALGORITHM_COUNT; i++) -			rcap->algo[i] = SR_ALGORITHM_UNSET; +			tlvs->router_cap->algo[i] = SR_ALGORITHM_UNSET;  	} +	rcap = tlvs->router_cap; +  	/* Get Router ID and Flags */  	rcap->router_id.s_addr = stream_get_ipv4(s);  	rcap->flags = stream_getc(s); @@ -5417,7 +5418,6 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,  				log, indent,  				"WARNING: Router Capability subTLV length too large compared to expected size\n");  			stream_forward_getp(s, STREAM_READABLE(s)); -			XFREE(MTYPE_ISIS_TLV, rcap);  			return 0;  		} @@ -5728,7 +5728,6 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context,  		}  		subtlv_len = subtlv_len - length - 2;  	} -	tlvs->router_cap = rcap;  	return 0;  }  | 
