@@ -171,6 +171,12 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
171171 int psize ;
172172 uint8_t prefix_offset = 0 ;
173173
174+ /* Need at least 1 byte for prefixlen. */
175+ if (max_len < 1 ) {
176+ * error = -1 ;
177+ return 0 ;
178+ }
179+
174180 * error = 0 ;
175181 memset (& prefix_local , 0 , sizeof (prefix_local ));
176182 /* read the prefix length */
@@ -179,6 +185,12 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
179185 offset ++ ;
180186 prefix_local .family = afi2family (afi );
181187 if (prefix_local .family == AF_INET6 ) {
188+ /* Need one more byte for IPv6 offset. */
189+ if (offset >= max_len ) {
190+ * error = -1 ;
191+ return offset ;
192+ }
193+
182194 prefix_offset = nlri_ptr [offset ];
183195 if (ipv6_offset )
184196 * ipv6_offset = prefix_offset ;
@@ -254,13 +266,32 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
254266 struct bgp_pbr_match_val * mval = (struct bgp_pbr_match_val * )result ;
255267
256268 * error = 0 ;
269+
270+ /* do/while executes at least once, so guard first deref */
271+ if (max_len < 1 ) {
272+ * error = -1 ;
273+ return 0 ;
274+ }
275+
257276 do {
258277 if (loop > BGP_PBR_MATCH_VAL_MAX )
259278 * error = -2 ;
279+
280+ if (offset >= max_len ) {
281+ * error = -1 ;
282+ break ;
283+ }
284+
260285 hex2bin (& nlri_ptr [offset ], op );
261286 offset ++ ;
262287 len = 2 * op [2 ]+ op [3 ];
263288 value_size = 1 << len ;
289+
290+ if (offset > max_len || (uint32_t )value_size > (max_len - offset )) {
291+ * error = -1 ;
292+ break ;
293+ }
294+
264295 value = hexstr2num (& nlri_ptr [offset ], value_size );
265296 /* can not be < and > at the same time */
266297 if (op [5 ] == 1 && op [6 ] == 1 )
@@ -358,18 +389,32 @@ int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
358389 int len_written ;
359390
360391 * error = 0 ;
392+
393+ /* do/while executes at least once, so guard first deref */
394+ if (max_len < 1 ) {
395+ * error = -1 ;
396+ return 0 ;
397+ }
398+
361399 do {
362400 if (loop > BGP_PBR_MATCH_VAL_MAX ) {
363401 * error = -2 ;
364402 return offset ;
365403 }
404+
366405 hex2bin (& nlri_ptr [offset ], op );
367406 /* if first element, AND bit can not be set */
368407 if (op [1 ] == 1 && loop == 0 )
369408 * error = -1 ;
370409 offset ++ ;
371410 len = 2 * op [2 ] + op [3 ];
372411 value_size = 1 << len ;
412+
413+ if (offset > max_len || (uint32_t )value_size > (max_len - offset )) {
414+ * error = -1 ;
415+ break ;
416+ }
417+
373418 value = hexstr2num (& nlri_ptr [offset ], value_size );
374419 switch (type ) {
375420 case BGP_FLOWSPEC_RETURN_STRING :
0 commit comments