Download raw body.
bgpd: other attributes vs the bucket allocator
On Thu, Apr 30, 2026 at 09:22:56PM +0200, Claudio Jeker wrote:
> This is a fun one. The new bucket allocator used for attrs jumps from
> 240 to 256 entries. The problem is that l is a uint8_t and so 256
> becomes 0. The reallocarray shrinks the array and you can imagine the
> rest.
>
> In attr_optadd() check the value returned by bin_of_attrs() and limit it
> to UCHAR_MAX to prevent the overflow. Also switch the iterator variable
> from uint8_t to int (I did this everywhere because it is more natural).
>
> Does this make sense?
I think it does but I find it very difficult to see through all the magic.
Just to make sure: do I understand correctly that the
fatalx("attr_optadd: attribute overflow");
wasn't reachable before and that the fact that it is reachable now is
making things work as intended?
> --
> :wq Claudio
>
> Index: mrt.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/mrt.c,v
> diff -u -p -r1.134 mrt.c
> --- mrt.c 17 Feb 2026 14:06:44 -0000 1.134
> +++ mrt.c 30 Apr 2026 18:35:08 -0000
> @@ -222,9 +222,9 @@ mrt_attr_dump(struct ibuf *buf, struct r
> struct attr *oa;
> u_char *pdata;
> uint32_t tmp;
> - int neednewpath = 0;
> + int l, neednewpath = 0;
> uint16_t plen, afi;
> - uint8_t l, safi;
> + uint8_t safi;
>
> /* origin */
> if (attr_writebuf(buf, ATTR_WELL_KNOWN, ATTR_ORIGIN,
> Index: rde.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> diff -u -p -r1.694 rde.c
> --- rde.c 27 Apr 2026 15:52:20 -0000 1.694
> +++ rde.c 30 Apr 2026 19:00:49 -0000
> @@ -2924,7 +2924,7 @@ rde_dump_rib_as(struct prefix *p, struct
> struct rde_peer *peer;
> monotime_t staletime;
> size_t aslen;
> - uint8_t l;
> + int l;
>
> nexthop = prefix_nexthop(p);
> peer = prefix_peer(p);
> @@ -3042,7 +3042,7 @@ rde_dump_adjout_as(struct rde_peer *peer
> struct rde_aspath *asp;
> struct nexthop *nexthop;
> size_t aslen;
> - uint8_t l;
> + int l;
>
> nexthop = attrs->nexthop;
> asp = attrs->aspath;
> Index: rde_attr.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_attr.c,v
> diff -u -p -r1.141 rde_attr.c
> --- rde_attr.c 17 Mar 2026 09:29:29 -0000 1.141
> +++ rde_attr.c 30 Apr 2026 19:08:36 -0000
> @@ -95,7 +95,7 @@ int
> attr_optadd(struct rde_aspath *asp, uint8_t flags, uint8_t type,
> void *data, uint16_t len)
> {
> - uint8_t l;
> + int l;
> struct attr *a, *t;
> struct attr **p;
> uint64_t h;
> @@ -137,6 +137,8 @@ attr_optadd(struct rde_aspath *asp, uint
> fatalx("attr_optadd: attribute overflow");
>
> l = bin_of_attrs(asp->others_len + 1);
> + if (l > UCHAR_MAX)
> + l = UCHAR_MAX;
> if ((p = reallocarray(asp->others, l, sizeof(struct attr *))) == NULL)
> fatal("%s", __func__);
> memset(&p[asp->others_len], 0, (l - asp->others_len) * sizeof(*p));
> @@ -150,7 +152,7 @@ attr_optadd(struct rde_aspath *asp, uint
> struct attr *
> attr_optget(const struct rde_aspath *asp, uint8_t type)
> {
> - uint8_t l;
> + int l;
>
> for (l = 0; l < asp->others_len; l++) {
> if (asp->others[l] == NULL)
> @@ -166,7 +168,7 @@ attr_optget(const struct rde_aspath *asp
> void
> attr_copy(struct rde_aspath *t, const struct rde_aspath *s)
> {
> - uint8_t l;
> + int l;
>
> if (t->others != NULL)
> attr_freeall(t);
> @@ -206,7 +208,7 @@ attr_eq(const struct attr *oa, const str
> int
> attr_equal(const struct rde_aspath *a, const struct rde_aspath *b)
> {
> - uint8_t l;
> + int l;
>
> if (a->others_len != b->others_len)
> return (0);
> @@ -219,7 +221,7 @@ attr_equal(const struct rde_aspath *a, c
> void
> attr_free(struct rde_aspath *asp, struct attr *attr)
> {
> - uint8_t l;
> + int l;
>
> for (l = 0; l < asp->others_len; l++)
> if (asp->others[l] == attr) {
> @@ -236,7 +238,7 @@ attr_free(struct rde_aspath *asp, struct
> void
> attr_freeall(struct rde_aspath *asp)
> {
> - uint8_t l;
> + int l;
>
> for (l = 0; l < asp->others_len; l++)
> attr_put(asp->others[l]);
> Index: rde_update.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
> diff -u -p -r1.193 rde_update.c
> --- rde_update.c 11 Feb 2026 10:24:57 -0000 1.193
> +++ rde_update.c 30 Apr 2026 18:36:05 -0000
> @@ -591,9 +591,9 @@ up_generate_attr(struct ibuf *buf, struc
> struct attr *oa = NULL, *newaggr = NULL;
> u_char *pdata;
> uint32_t tmp32;
> - int flags, neednewpath = 0, rv;
> + int flags, neednewpath = 0, rv, oalen = 0;
> uint16_t plen;
> - uint8_t oalen = 0, type;
> + uint8_t type;
>
> if (asp->others_len > 0)
> oa = asp->others[oalen++];
>
bgpd: other attributes vs the bucket allocator