bgpd: add some flowspec sanity returns

If an error is detected in an NLRI, immediately return
an error, when there is a risk of buffer overflow.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2023-04-28 21:56:19 +02:00
parent 34a8441fe8
commit 9ba97a35a6

View File

@ -185,16 +185,23 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
offset++; offset++;
} }
/* Prefix length check. */ /* Prefix length check. */
if (prefix_local.prefixlen > prefix_blen(&prefix_local) * 8) if (prefix_local.prefixlen > prefix_blen(&prefix_local) * 8) {
*error = -1; *error = -1;
return offset;
}
/* When packet overflow occur return immediately. */ /* When packet overflow occur return immediately. */
if (psize + offset > max_len) if (psize + offset > max_len) {
*error = -1; *error = -1;
return offset;
}
/* Defensive coding, double-check /* Defensive coding, double-check
* the psize fits in a struct prefix * the psize fits in a struct prefix
*/ */
if (psize > (ssize_t)sizeof(prefix_local.u)) if (psize > (ssize_t)sizeof(prefix_local.u)) {
*error = -1; *error = -1;
return offset;
}
memcpy(&prefix_local.u.prefix, &nlri_ptr[offset], psize); memcpy(&prefix_local.u.prefix, &nlri_ptr[offset], psize);
offset += psize; offset += psize;
switch (type) { switch (type) {
@ -352,8 +359,10 @@ int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
*error = 0; *error = 0;
do { do {
if (loop > BGP_PBR_MATCH_VAL_MAX) if (loop > BGP_PBR_MATCH_VAL_MAX) {
*error = -2; *error = -2;
return offset;
}
hex2bin(&nlri_ptr[offset], op); hex2bin(&nlri_ptr[offset], op);
/* if first element, AND bit can not be set */ /* if first element, AND bit can not be set */
if (op[1] == 1 && loop == 0) if (op[1] == 1 && loop == 0)