The aspa_check() uses as_path_getlen() to estimate the size of a buffer,
which does not work for AS_SET segments, because as_path_getlen() returns
length 1 for them regardless of their length. This may cause buffer
overflow and crash.
As AS_SET segments are not valid for ASPA verification, we can just
handle them explicitly. See https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-aspa-verification#section-6
Co-Authored-By: Alarig <alarig@swordarmor.fr>
Minor changes by committer.
return 0;
}
+int
+as_path_contains_set(const struct adata *path)
+{
+ const byte *pos = path->data;
+ const byte *end = pos + path->length;
+
+ while (pos < end)
+ {
+ uint type = pos[0];
+ uint slen = 2 + BS * pos[1];
+
+ if ((type == AS_PATH_SET) ||
+ (type == AS_PATH_CONFED_SET))
+ return 1;
+
+ pos += slen;
+ }
+
+ return 0;
+}
+
struct adata *
as_path_strip_confed(struct linpool *pool, const struct adata *path)
{
int as_path_32to16(byte *dst, const byte *src, uint len);
int as_path_contains_as4(const struct adata *path);
int as_path_contains_confed(const struct adata *path);
+int as_path_contains_set(const struct adata *path);
struct adata *as_path_strip_confed(struct linpool *pool, const struct adata *op);
struct adata *as_path_prepend2(struct linpool *pool, const struct adata *op, int seq, u32 as);
struct adata *as_path_to_old(struct linpool *pool, const struct adata *path);
if (as_path_contains_confed(path))
return ASPA_INVALID;
- /* Check path length */
+ /* No support for AS_SET */
+ /* See draft-ietf-sidrops-aspa-verification section 6 */
+ if (as_path_contains_set(path))
+ return ASPA_INVALID;
+
+ /* Check path length; we assume just AS_SEQUENCE segments */
uint len = as_path_getlen(path);
if (len == 0)
return ASPA_INVALID;