diff options
| author | Olivier Dugeon <olivier.dugeon@orange.com> | 2024-04-16 16:42:06 +0200 | 
|---|---|---|
| committer | Olivier Dugeon <olivier.dugeon@orange.com> | 2024-05-23 10:47:34 +0200 | 
| commit | 8c177d69e32b91b45bda5fc5da6511fa03dc11ca (patch) | |
| tree | 4f4afa07089d1dad30ceb5d09ff3fa7226e08fd5 /ospfd | |
| parent | 5557a289acdaeec8cc63ffc97b5c2abf6dee7b3a (diff) | |
ospfd: protect call to get_edge() in ospf_te.c
During fuzzing, Iggy Frankovic discovered that get_edge() function in ospf_te.c
could return null pointer, in particular when the link_id or advertised router
IP addresses are fuzzed. As the null pointer returned by get_edge() function is
not handlei by calling functions, this could cause ospfd crash.
This patch introduces new verification of returned pointer by get_edge()
function and stop the processing in case of null pointer. In addition, link ID
and advertiser router ID are validated before calling ls_find_edge_by_key() to
avoid the creation of a new edge with an invalid key.
CVE-2024-34088
Co-authored-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/ospf_te.c | 19 | 
1 files changed, 16 insertions, 3 deletions
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index e68f9444f5..d57990e1a1 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -1670,6 +1670,11 @@ static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_node_id adv,  	struct ls_edge *edge;  	struct ls_attributes *attr; +	/* Check that Link ID and Node ID are valid */ +	if (IPV4_NET0(link_id.s_addr) || IPV4_NET0(adv.id.ip.addr.s_addr) || +	    adv.origin != OSPFv2) +		return NULL; +  	/* Search Edge that corresponds to the Link ID */  	key.family = AF_INET;  	IPV4_ADDR_COPY(&key.k.addr, &link_id); @@ -1743,6 +1748,10 @@ static void ospf_te_update_link(struct ls_ted *ted, struct ls_vertex *vertex,  	/* Get Corresponding Edge from Link State Data Base */  	edge = get_edge(ted, vertex->node->adv, link_data); +	if (!edge) { +		ote_debug("  |- Found no edge from Link Data. Abort!"); +		return; +	}  	attr = edge->attributes;  	/* re-attached edge to vertex if needed */ @@ -2246,11 +2255,11 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)  	}  	/* Get corresponding Edge from Link State Data Base */ -	if (IPV4_NET0(attr.standard.local.s_addr) && !attr.standard.local_id) { -		ote_debug("  |- Found no TE Link local address/ID. Abort!"); +	edge = get_edge(ted, attr.adv, attr.standard.local); +	if (!edge) { +		ote_debug("  |- Found no edge from Link local add./ID. Abort!");  		return -1;  	} -	edge = get_edge(ted, attr.adv, attr.standard.local);  	old = edge->attributes;  	ote_debug("  |- Process Traffic Engineering LSA %pI4 for Edge %pI4", @@ -2759,6 +2768,10 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)  	lnid.id.ip.area_id = lsa->area->area_id;  	ext = (struct ext_tlv_link *)TLV_HDR_TOP(lsa->data);  	edge = get_edge(ted, lnid, ext->link_data); +	if (!edge) { +		ote_debug("  |- Found no edge from Extended Link Data. Abort!"); +		return -1; +	}  	atr = edge->attributes;  	ote_debug("  |- Process Extended Link LSA %pI4 for edge %pI4",  | 
