1
0
mirror of https://github.com/openbsd/src.git synced 2026-06-18 07:13:36 +02:00

Introduce a maximum size for a single flowspec NLRI of 4000 bytes.

Enforce this in both in the parser but also in the RDE.
In the RDE flowspec_valid() will error out if the lenght is too long
but also pt_get_flow() and pt_add_flow() will error out.
The fixed buffer in pt_get_flow() is now sized appropriately instead
of using a arbitrary size.

OK tb@
This commit is contained in:
claudio
2026-05-18 18:36:25 +00:00
parent 5db7a46e29
commit 314bc62c53
4 changed files with 28 additions and 8 deletions
+2 -1
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: bgpd.h,v 1.542 2026/05/12 09:12:49 claudio Exp $ */
/* $OpenBSD: bgpd.h,v 1.543 2026/05/18 18:36:25 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -594,6 +594,7 @@ struct flowspec {
uint8_t data[1];
};
#define FLOWSPEC_SIZE (offsetof(struct flowspec, data))
#define FLOWSPEC_SIZE_MAX 4000
struct flowspec_config {
RB_ENTRY(flowspec_config) entry;
+5 -1
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: flowspec.c,v 1.5 2023/10/23 13:07:44 claudio Exp $ */
/* $OpenBSD: flowspec.c,v 1.6 2026/05/18 18:36:25 claudio Exp $ */
/*
* Copyright (c) 2023 Claudio Jeker <claudio@openbsd.org>
@@ -177,6 +177,10 @@ flowspec_valid(const uint8_t *buf, int len, int is_v6)
if (len == 0)
return -1;
/* flowspec rule is too large */
if (len > FLOWSPEC_SIZE_MAX)
return -1;
while (len > 0) {
l = flowspec_next_component(buf, len, is_v6, &type);
if (l == -1)
+11 -4
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.497 2026/05/18 15:49:22 claudio Exp $ */
/* $OpenBSD: parse.y,v 1.498 2026/05/18 18:36:25 claudio Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1201,7 +1201,6 @@ flowspec : FLOWSPEC af {
f = flow_to_flowspec(curflow);
if (f == NULL) {
yyerror("out of memory");
free($5);
flow_free(curflow);
curflow = NULL;
@@ -5692,6 +5691,7 @@ flow_to_flowspec(struct flowspec_context *ctx)
aid = AID_FLOWSPECv6;
break;
default:
yyerror("unknown AID %d", ctx->aid);
return NULL;
}
@@ -5699,9 +5699,16 @@ flow_to_flowspec(struct flowspec_context *ctx)
if (ctx->components[i] != NULL)
len += ctx->complen[i] + 1;
f = flowspec_alloc(aid, len);
if (f == NULL)
if (len > FLOWSPEC_SIZE_MAX) {
yyerror("flowspec too long %d > %d", len, FLOWSPEC_SIZE_MAX);
return NULL;
}
f = flowspec_alloc(aid, len);
if (f == NULL) {
yyerror("out of memory");
return NULL;
}
len = 0;
for (i = FLOWSPEC_TYPE_MIN; i < FLOWSPEC_TYPE_MAX; i++)
+10 -2
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: rde_prefix.c,v 1.61 2026/05/13 15:12:14 claudio Exp $ */
/* $OpenBSD: rde_prefix.c,v 1.62 2026/05/18 18:36:25 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -405,11 +405,16 @@ pt_get_flow(struct flowspec *f)
struct pt_entry *needle;
union {
struct pt_entry_flow flow;
uint8_t buf[4096];
uint8_t buf[FLOWSPEC_SIZE_MAX + PT_FLOW_SIZE];
} x;
needle = (struct pt_entry *)&x.flow;
if (f->len > FLOWSPEC_SIZE_MAX) {
log_warnx("%s: flowspec too long", __func__);
return NULL;
}
memset(needle, 0, PT_FLOW_SIZE);
needle->aid = f->aid;
needle->len = f->len + PT_FLOW_SIZE;
@@ -424,6 +429,9 @@ pt_add_flow(struct flowspec *f)
struct pt_entry *p;
int len = f->len + PT_FLOW_SIZE;
if (f->len > FLOWSPEC_SIZE_MAX)
fatalx("%s: flowspec too long", __func__);
p = malloc(len);
if (p == NULL)
fatal(__func__);