@@ -1048,13 +1048,17 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
1048
1048
return len ;
1049
1049
}
1050
1050
1051
- static int ipv6_ecommunity_lb_str (char * buf , size_t bufsz , const uint8_t * pnt )
1051
+ static int ipv6_ecommunity_lb_str (char * buf , size_t bufsz , const uint8_t * pnt ,
1052
+ size_t length )
1052
1053
{
1053
1054
int len = 0 ;
1054
- as_t as ;
1055
- uint64_t bw ;
1055
+ as_t as = 0 ;
1056
+ uint64_t bw = 0 ;
1056
1057
char bps_buf [20 ] = { 0 };
1057
1058
1059
+ if (length < IPV6_ECOMMUNITY_SIZE )
1060
+ goto done ;
1061
+
1058
1062
pnt += 2 ; /* Reserved */
1059
1063
pnt = ptr_get_be64 (pnt , & bw );
1060
1064
(void )ptr_get_be32 (pnt , & as );
@@ -1071,6 +1075,7 @@ static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt)
1071
1075
else
1072
1076
snprintfrr (bps_buf , sizeof (bps_buf ), "%" PRIu64 " bps" , bw * 8 );
1073
1077
1078
+ done :
1074
1079
len = snprintfrr (buf , bufsz , "LB:%u:%" PRIu64 " (%s)" , as , bw , bps_buf );
1075
1080
return len ;
1076
1081
}
@@ -1143,7 +1148,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1143
1148
char encbuf [128 ];
1144
1149
1145
1150
for (i = 0 ; i < ecom -> size ; i ++ ) {
1146
- int unk_ecom = 0 ;
1151
+ bool unk_ecom = false ;
1147
1152
memset (encbuf , 0x00 , sizeof (encbuf ));
1148
1153
1149
1154
/* Space between each value. */
@@ -1153,6 +1158,18 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1153
1158
/* Retrieve value field */
1154
1159
pnt = ecom -> val + (i * ecom -> unit_size );
1155
1160
1161
+ uint8_t * data = pnt ;
1162
+ uint8_t * end = data + ecom -> unit_size ;
1163
+ size_t len = end - data ;
1164
+
1165
+ /* Sanity check for extended communities lenght, to avoid
1166
+ * overrun when dealing with bits, e.g. ptr_get_be64().
1167
+ */
1168
+ if (len < ecom -> unit_size ) {
1169
+ unk_ecom = true;
1170
+ goto unknown ;
1171
+ }
1172
+
1156
1173
/* High-order octet is the type */
1157
1174
type = * pnt ++ ;
1158
1175
@@ -1180,14 +1197,14 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1180
1197
type == ECOMMUNITY_ENCODE_AS4 ) {
1181
1198
ipv6_ecommunity_lb_str (encbuf ,
1182
1199
sizeof (encbuf ),
1183
- pnt );
1200
+ pnt , len );
1184
1201
} else if (sub_type == ECOMMUNITY_NODE_TARGET &&
1185
1202
type == ECOMMUNITY_ENCODE_IP ) {
1186
1203
ecommunity_node_target_str (
1187
1204
encbuf , sizeof (encbuf ), pnt ,
1188
1205
format );
1189
1206
} else
1190
- unk_ecom = 1 ;
1207
+ unk_ecom = true ;
1191
1208
} else {
1192
1209
ecommunity_rt_soo_str (encbuf , sizeof (encbuf ),
1193
1210
pnt , type , sub_type ,
@@ -1210,7 +1227,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1210
1227
ecommunity_color_str (encbuf , sizeof (encbuf ),
1211
1228
pnt );
1212
1229
} else {
1213
- unk_ecom = 1 ;
1230
+ unk_ecom = true ;
1214
1231
}
1215
1232
} else if (type == ECOMMUNITY_ENCODE_EVPN ) {
1216
1233
if (filter == ECOMMUNITY_ROUTE_TARGET )
@@ -1303,14 +1320,14 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1303
1320
"DF: (alg: %u, pref: %u)" , alg ,
1304
1321
pref );
1305
1322
} else
1306
- unk_ecom = 1 ;
1323
+ unk_ecom = true ;
1307
1324
} else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH ) {
1308
1325
sub_type = * pnt ++ ;
1309
1326
if (sub_type == ECOMMUNITY_REDIRECT_IP_NH ) {
1310
1327
snprintf (encbuf , sizeof (encbuf ),
1311
1328
"FS:redirect IP 0x%x" , * (pnt + 5 ));
1312
1329
} else
1313
- unk_ecom = 1 ;
1330
+ unk_ecom = true ;
1314
1331
} else if (type == ECOMMUNITY_ENCODE_TRANS_EXP ||
1315
1332
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 ||
1316
1333
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_3 ) {
@@ -1357,7 +1374,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1357
1374
snprintf (encbuf , sizeof (encbuf ),
1358
1375
"FS:redirect VRF %s" , buf );
1359
1376
} else if (type != ECOMMUNITY_ENCODE_TRANS_EXP )
1360
- unk_ecom = 1 ;
1377
+ unk_ecom = true ;
1361
1378
else if (sub_type == ECOMMUNITY_TRAFFIC_ACTION ) {
1362
1379
char action [64 ];
1363
1380
@@ -1390,36 +1407,37 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
1390
1407
snprintf (encbuf , sizeof (encbuf ),
1391
1408
"FS:marking %u" , * (pnt + 5 ));
1392
1409
} else
1393
- unk_ecom = 1 ;
1410
+ unk_ecom = true ;
1394
1411
} else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS ) {
1395
1412
sub_type = * pnt ++ ;
1396
1413
if (sub_type == ECOMMUNITY_LINK_BANDWIDTH )
1397
1414
ecommunity_lb_str (encbuf , sizeof (encbuf ), pnt ,
1398
1415
ecom -> disable_ieee_floating );
1399
1416
else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH )
1400
1417
ipv6_ecommunity_lb_str (encbuf , sizeof (encbuf ),
1401
- pnt );
1418
+ pnt , len );
1402
1419
else
1403
- unk_ecom = 1 ;
1420
+ unk_ecom = true ;
1404
1421
} else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS ) {
1405
1422
sub_type = * pnt ++ ;
1406
1423
if (sub_type == ECOMMUNITY_NODE_TARGET )
1407
1424
ecommunity_node_target_str (
1408
1425
encbuf , sizeof (encbuf ), pnt , format );
1409
1426
else
1410
- unk_ecom = 1 ;
1427
+ unk_ecom = true ;
1411
1428
} else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS ) {
1412
1429
sub_type = * pnt ++ ;
1413
1430
if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE )
1414
1431
ecommunity_origin_validation_state_str (
1415
1432
encbuf , sizeof (encbuf ), pnt );
1416
1433
else
1417
- unk_ecom = 1 ;
1434
+ unk_ecom = true ;
1418
1435
} else {
1419
1436
sub_type = * pnt ++ ;
1420
- unk_ecom = 1 ;
1437
+ unk_ecom = true ;
1421
1438
}
1422
1439
1440
+ unknown :
1423
1441
if (unk_ecom )
1424
1442
snprintf (encbuf , sizeof (encbuf ), "UNK:%d, %d" , type ,
1425
1443
sub_type );
0 commit comments