summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnkur Tyagi <ankur.tyagi85@gmail.com>2026-05-13 17:04:45 +1200
committerAnuj Mittal <anuj.mittal@oss.qualcomm.com>2026-05-21 08:57:45 +0530
commitfdd887bc2979ae4d1666d1fb5750c60201622ef2 (patch)
treecaca3b9457a6666b4bbc1f2928f944ccdef26b43
parent764a8f2154aa26b3716c12ace1119115d15768a9 (diff)
downloadmeta-openembedded-fdd887bc2979ae4d1666d1fb5750c60201622ef2.tar.gz
frr: patch CVE-2026-28532
Details: https://nvd.nist.gov/vuln/detail/CVE-2026-28532 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
-rw-r--r--meta-networking/recipes-protocols/frr/frr/CVE-2026-28532.patch309
-rw-r--r--meta-networking/recipes-protocols/frr/frr_9.1.3.bb1
2 files changed, 310 insertions, 0 deletions
diff --git a/meta-networking/recipes-protocols/frr/frr/CVE-2026-28532.patch b/meta-networking/recipes-protocols/frr/frr/CVE-2026-28532.patch
new file mode 100644
index 0000000000..39f5f569de
--- /dev/null
+++ b/meta-networking/recipes-protocols/frr/frr/CVE-2026-28532.patch
@@ -0,0 +1,309 @@
1From ea6982fe2ae7db40b0ea0ec42c283eb3b3178798 Mon Sep 17 00:00:00 2001
2From: Jafar Al-Gharaibeh <jafar@atcorp.com>
3Date: Wed, 4 Mar 2026 12:38:46 -0600
4Subject: [PATCH] ospfd: harden TE/SR TLV iteration against malformed lengths
5
6Use 32-bit counters and per-iteration TLV size bounds checks
7in OSPF TE/SR TLV parsers so malformed opaque LSAs cannot wrap
8loop accounting and advance pointers beyond the LSA buffer.
9
10- Change loop accumulators from 16-bit to 32-bit (uint32_t) to
11 prevent wraparound
12- Rework TLV iteration so pointer advancement is controlled in-loop
13- Add per-iteration guard before advancing:
14 - `tlv_size <= (len - sum)` (or `length - sum`)
15- On malformed size, parser now logs and exits/breaks the loop
16 safely instead of stepping past buffer limits
17
18Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
19(cherry picked from commit d3e8aedb87671f38db59b0df908e25e1d4af027d)
20
21CVE: CVE-2026-28532
22Upstream-Status: Backport [https://github.com/FRRouting/frr/commit/d3e8aedb87671f38db59b0df908e25e1d4af027d]
23Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
24---
25 ospfd/ospf_sr.c | 50 ++++++++++++++++++++++++++++++--------
26 ospfd/ospf_te.c | 64 +++++++++++++++++++++++++++++++++++++++----------
27 2 files changed, 91 insertions(+), 23 deletions(-)
28
29diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c
30index e26fe6f53a..11ca362a1b 100644
31--- a/ospfd/ospf_sr.c
32+++ b/ospfd/ospf_sr.c
33@@ -985,7 +985,8 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh, size_t size)
34 struct ext_subtlv_rmt_itf_addr *rmt_itf;
35
36 struct tlv_header *sub_tlvh;
37- uint16_t length = 0, sum = 0, i = 0;
38+ uint32_t length = 0, sum = 0;
39+ uint16_t i = 0;
40
41 /* Check TLV size */
42 if ((ntohs(tlvh->length) > size)
43@@ -1000,7 +1001,15 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh, size_t size)
44 length = ntohs(tlvh->length) - EXT_TLV_LINK_SIZE;
45 sub_tlvh = (struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE
46 + EXT_TLV_LINK_SIZE);
47- for (; sum < length && sub_tlvh; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
48+ for (; sum < length && sub_tlvh;) {
49+ uint32_t tlv_size = TLV_SIZE(sub_tlvh);
50+
51+ if (tlv_size > length - sum) {
52+ zlog_warn("Malformed Extended Link sub-TLV size %u (remaining %u)",
53+ tlv_size, length - sum);
54+ break;
55+ }
56+
57 switch (ntohs(sub_tlvh->type)) {
58 case EXT_SUBTLV_ADJ_SID:
59 adj_sid = (struct ext_subtlv_adj_sid *)sub_tlvh;
60@@ -1041,7 +1050,9 @@ static struct sr_link *get_ext_link_sid(struct tlv_header *tlvh, size_t size)
61 default:
62 break;
63 }
64- sum += TLV_SIZE(sub_tlvh);
65+ sum += tlv_size;
66+ if (sum < length)
67+ sub_tlvh = TLV_HDR_NEXT(sub_tlvh);
68 }
69
70 IPV4_ADDR_COPY(&srl->itf_addr, &link->link_data);
71@@ -1062,7 +1073,7 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh,
72 struct ext_subtlv_prefix_sid *psid;
73
74 struct tlv_header *sub_tlvh;
75- uint16_t length = 0, sum = 0;
76+ uint32_t length = 0, sum = 0;
77
78 /* Check TLV size */
79 if ((ntohs(tlvh->length) > size)
80@@ -1077,7 +1088,15 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh,
81 length = ntohs(tlvh->length) - EXT_TLV_PREFIX_SIZE;
82 sub_tlvh = (struct tlv_header *)((char *)(tlvh) + TLV_HDR_SIZE
83 + EXT_TLV_PREFIX_SIZE);
84- for (; sum < length && sub_tlvh; sub_tlvh = TLV_HDR_NEXT(sub_tlvh)) {
85+ for (; sum < length && sub_tlvh;) {
86+ uint32_t tlv_size = TLV_SIZE(sub_tlvh);
87+
88+ if (tlv_size > length - sum) {
89+ zlog_warn("Malformed Extended Prefix sub-TLV size %u (remaining %u)",
90+ tlv_size, length - sum);
91+ break;
92+ }
93+
94 switch (ntohs(sub_tlvh->type)) {
95 case EXT_SUBTLV_PREFIX_SID:
96 psid = (struct ext_subtlv_prefix_sid *)sub_tlvh;
97@@ -1102,7 +1121,9 @@ static struct sr_prefix *get_ext_prefix_sid(struct tlv_header *tlvh,
98 default:
99 break;
100 }
101- sum += TLV_SIZE(sub_tlvh);
102+ sum += tlv_size;
103+ if (sum < length)
104+ sub_tlvh = TLV_HDR_NEXT(sub_tlvh);
105 }
106
107 osr_debug(" |- Found SID %u for prefix %pFX", srp->sid,
108@@ -1364,7 +1385,7 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
109 struct ri_sr_tlv_sid_label_range *ri_srlb = NULL;
110 struct ri_sr_tlv_sr_algorithm *algo = NULL;
111 struct sr_block srgb;
112- uint16_t length = 0, sum = 0;
113+ uint32_t length = 0, sum = 0;
114 uint8_t msd = 0;
115
116 osr_debug("SR (%s): Process Router Information LSA 4.0.0.%u from %pI4",
117@@ -1392,8 +1413,15 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
118 srgb.range_size = 0;
119 srgb.lower_bound = 0;
120
121- for (tlvh = TLV_HDR_TOP(lsah); (sum < length) && (tlvh != NULL);
122- tlvh = TLV_HDR_NEXT(tlvh)) {
123+ for (tlvh = TLV_HDR_TOP(lsah); (sum < length) && (tlvh != NULL);) {
124+ uint32_t tlv_size = TLV_SIZE(tlvh);
125+
126+ if (tlv_size > length - sum) {
127+ zlog_warn("Malformed RI TLV size %u (remaining %u)", tlv_size,
128+ length - sum);
129+ break;
130+ }
131+
132 switch (ntohs(tlvh->type)) {
133 case RI_SR_TLV_SR_ALGORITHM:
134 algo = (struct ri_sr_tlv_sr_algorithm *)tlvh;
135@@ -1410,7 +1438,9 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa)
136 default:
137 break;
138 }
139- sum += TLV_SIZE(tlvh);
140+ sum += tlv_size;
141+ if (sum < length)
142+ tlvh = TLV_HDR_NEXT(tlvh);
143 }
144
145 /* Check if Segment Routing Capabilities has been found */
146diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
147index 1bddf97bde..8d01e4fd1d 100644
148--- a/ospfd/ospf_te.c
149+++ b/ospfd/ospf_te.c
150@@ -2121,7 +2121,7 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)
151 struct ls_attributes *old, attr = {};
152 struct tlv_header *tlvh;
153 void *value;
154- uint16_t len, sum;
155+ uint32_t len, sum;
156 uint8_t lsa_id;
157
158 /* Initialize Attribute */
159@@ -2151,11 +2151,19 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)
160
161 sum = sizeof(struct tlv_header);
162 /* Browse sub-TLV and fulfill Link State Attributes */
163- for (tlvh = TLV_DATA(tlvh); sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
164+ tlvh = TLV_DATA(tlvh);
165+ while (sum < len) {
166+ uint32_t tlv_size = TLV_SIZE(tlvh);
167 uint32_t val32, tab32[2];
168 float valf, tabf[8];
169 struct in_addr addr;
170
171+ if (tlv_size > len - sum) {
172+ zlog_warn("Malformed TE sub-TLV size %u (remaining %u)", tlv_size,
173+ len - sum);
174+ break;
175+ }
176+
177 value = TLV_DATA(tlvh);
178 switch (ntohs(tlvh->type)) {
179 case TE_LINK_SUBTLV_LCLIF_IPADDR:
180@@ -2250,7 +2258,9 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa)
181 default:
182 break;
183 }
184- sum += TLV_SIZE(tlvh);
185+ sum += tlv_size;
186+ if (sum < len)
187+ tlvh = TLV_HDR_NEXT(tlvh);
188 }
189
190 /* Get corresponding Edge from Link State Data Base */
191@@ -2350,7 +2360,7 @@ static int ospf_te_delete_te(struct ls_ted *ted, struct ospf_lsa *lsa)
192 struct tlv_header *tlvh;
193 struct in_addr addr;
194 struct ls_edge_key key = {.family = AF_UNSPEC};
195- uint16_t len, sum;
196+ uint32_t len, sum;
197 uint8_t lsa_id;
198
199 /* Initialize TLV browsing */
200@@ -2362,14 +2372,25 @@ static int ospf_te_delete_te(struct ls_ted *ted, struct ospf_lsa *lsa)
201 sum = sizeof(struct tlv_header);
202
203 /* Browse sub-TLV to find Link ID */
204- for (tlvh = TLV_DATA(tlvh); sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
205+ tlvh = TLV_DATA(tlvh);
206+ while (sum < len) {
207+ uint32_t tlv_size = TLV_SIZE(tlvh);
208+
209+ if (tlv_size > len - sum) {
210+ zlog_warn("Malformed TE sub-TLV size %u (remaining %u)", tlv_size,
211+ len - sum);
212+ break;
213+ }
214+
215 if (ntohs(tlvh->type) == TE_LINK_SUBTLV_LCLIF_IPADDR) {
216 memcpy(&addr, TLV_DATA(tlvh), TE_LINK_SUBTLV_DEF_SIZE);
217 key.family = AF_INET;
218 IPV4_ADDR_COPY(&key.k.addr, &addr);
219 break;
220 }
221- sum += TLV_SIZE(tlvh);
222+ sum += tlv_size;
223+ if (sum < len)
224+ tlvh = TLV_HDR_NEXT(tlvh);
225 }
226 if (key.family == AF_UNSPEC)
227 return 0;
228@@ -2444,7 +2465,7 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa)
229 struct ls_node *node;
230 struct lsa_header *lsah = lsa->data;
231 struct tlv_header *tlvh;
232- uint16_t len = 0, sum = 0;
233+ uint32_t len = 0, sum = 0;
234
235 /* Get vertex / Node from LSA Advertised Router ID */
236 vertex = get_vertex(ted, lsa);
237@@ -2455,13 +2476,18 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa)
238
239 /* Initialize TLV browsing */
240 len = lsa->size - OSPF_LSA_HEADER_SIZE;
241- for (tlvh = TLV_HDR_TOP(lsah); sum < len && tlvh;
242- tlvh = TLV_HDR_NEXT(tlvh)) {
243+ for (tlvh = TLV_HDR_TOP(lsah); sum < len && tlvh;) {
244+ uint32_t tlv_size = TLV_SIZE(tlvh);
245 struct ri_sr_tlv_sr_algorithm *algo;
246 struct ri_sr_tlv_sid_label_range *range;
247 struct ri_sr_tlv_node_msd *msd;
248 uint32_t size, lower;
249
250+ if (tlv_size > len - sum) {
251+ zlog_warn("Malformed RI TLV size %u (remaining %u)", tlv_size, len - sum);
252+ break;
253+ }
254+
255 switch (ntohs(tlvh->type)) {
256 case RI_SR_TLV_SR_ALGORITHM:
257 if (TLV_BODY_SIZE(tlvh) < 1 ||
258@@ -2546,7 +2572,9 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa)
259 default:
260 break;
261 }
262- sum += TLV_SIZE(tlvh);
263+ sum += tlv_size;
264+ if (sum < len)
265+ tlvh = TLV_HDR_NEXT(tlvh);
266 }
267
268 /* Vertex has been created or updated: export it */
269@@ -2758,7 +2786,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
270 struct ext_tlv_link *ext;
271 struct ls_edge *edge;
272 struct ls_attributes *atr;
273- uint16_t len = 0, sum = 0, i;
274+ uint32_t len = 0, sum = 0;
275+ uint16_t i;
276 uint32_t label;
277
278 /* Get corresponding Edge from Link State Data Base */
279@@ -2792,11 +2821,18 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
280 len -= EXT_TLV_LINK_SIZE;
281 tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
282 + EXT_TLV_LINK_SIZE);
283- for (; sum < len; tlvh = TLV_HDR_NEXT(tlvh)) {
284+ for (; sum < len;) {
285+ uint32_t tlv_size = TLV_SIZE(tlvh);
286 struct ext_subtlv_adj_sid *adj;
287 struct ext_subtlv_lan_adj_sid *ladj;
288 struct ext_subtlv_rmt_itf_addr *rmt;
289
290+ if (tlv_size > len - sum) {
291+ zlog_warn("Malformed Extended Link sub-TLV size %u (remaining %u)",
292+ tlv_size, len - sum);
293+ break;
294+ }
295+
296 switch (ntohs(tlvh->type)) {
297 case EXT_SUBTLV_ADJ_SID:
298 if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_ADJ_SID_SIZE)
299@@ -2875,7 +2911,9 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa)
300 default:
301 break;
302 }
303- sum += TLV_SIZE(tlvh);
304+ sum += tlv_size;
305+ if (sum < len)
306+ tlvh = TLV_HDR_NEXT(tlvh);
307 }
308
309 /* Export Link State Edge if needed */
diff --git a/meta-networking/recipes-protocols/frr/frr_9.1.3.bb b/meta-networking/recipes-protocols/frr/frr_9.1.3.bb
index 0287a6fb69..20a224b7d7 100644
--- a/meta-networking/recipes-protocols/frr/frr_9.1.3.bb
+++ b/meta-networking/recipes-protocols/frr/frr_9.1.3.bb
@@ -18,6 +18,7 @@ SRC_URI = "git://github.com/FRRouting/frr.git;protocol=https;branch=stable/9.1 \
18 file://CVE-2025-61099-61100-61101-61102-61103-61104-61105-61106-61107_2.patch \ 18 file://CVE-2025-61099-61100-61101-61102-61103-61104-61105-61106-61107_2.patch \
19 file://CVE-2025-61099-61100-61101-61102-61103-61104-61105-61106-61107_3.patch \ 19 file://CVE-2025-61099-61100-61101-61102-61103-61104-61105-61106-61107_3.patch \
20 file://CVE-2025-61099-61100-61101-61102-61103-61104-61105-61106-61107_4.patch \ 20 file://CVE-2025-61099-61100-61101-61102-61103-61104-61105-61106-61107_4.patch \
21 file://CVE-2026-28532.patch \
21 " 22 "
22 23
23SRCREV = "ad1766d17be022587fe05ebe1a7bf10e1b7dce19" 24SRCREV = "ad1766d17be022587fe05ebe1a7bf10e1b7dce19"