From 545182717db94753877657331e526bb9dcfb71ec Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 28 May 2026 05:42:14 +0000 Subject: [PATCH] In rde_attr_missing() make sure the nexthop attribute is present if there is any nlri data. In rde_as4byte_fixup() only run if ATTR_ASPATH is present. Depending the nexthop attribute on MP_REACH is not correct since and UPDATE can in theory carry both MP_REACH nlri and old school IPv4 nlri. rde_as4byte_fixup() should only fixup paths that have - ATTR_AS4_AGGREGATOR or ATTR_AS4_PATH present - ATTR_ASPATH must be present as well - no parse error (F_ATTR_PARSE_ERR) The rde_as4byte_fixup() is entered all the time even for path that only contain an ATTR_MP_UNREACH (which then could also include an ATTR_AS4_PATH but no ATTR_ASPATH). Reported by 7Asecurity OK tb@ --- usr.sbin/bgpd/rde.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 7049d5ffea3..92fa39bc10a 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.703 2026/05/21 15:20:27 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.704 2026/05/28 05:42:14 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -57,7 +57,7 @@ void rde_update_withdraw(struct rde_peer *, uint32_t, int rde_attr_parse(struct ibuf *, struct rde_peer *, struct filterstate *, struct ibuf *, struct ibuf *); int rde_attr_add(struct filterstate *, struct ibuf *); -uint8_t rde_attr_missing(struct rde_aspath *, int, uint16_t); +uint8_t rde_attr_missing(struct rde_aspath *, int, size_t); int rde_get_mp_nexthop(struct ibuf *, uint8_t, struct rde_peer *, struct filterstate *); void rde_as4byte_fixup(struct rde_peer *, struct rde_aspath *); @@ -2514,7 +2514,7 @@ rde_attr_add(struct filterstate *state, struct ibuf *buf) } uint8_t -rde_attr_missing(struct rde_aspath *a, int ebgp, uint16_t nlrilen) +rde_attr_missing(struct rde_aspath *a, int ebgp, size_t nlrilen) { /* ATTR_MP_UNREACH_NLRI may be sent alone */ if (nlrilen == 0 && a->flags & F_ATTR_MP_UNREACH && @@ -2525,8 +2525,7 @@ rde_attr_missing(struct rde_aspath *a, int ebgp, uint16_t nlrilen) return (ATTR_ORIGIN); if ((a->flags & F_ATTR_ASPATH) == 0) return (ATTR_ASPATH); - if ((a->flags & F_ATTR_MP_REACH) == 0 && - (a->flags & F_ATTR_NEXTHOP) == 0) + if (nlrilen != 0 && (a->flags & F_ATTR_NEXTHOP) == 0) return (ATTR_NEXTHOP); if (!ebgp) if ((a->flags & F_ATTR_LOCALPREF) == 0) @@ -2751,11 +2750,14 @@ rde_as4byte_fixup(struct rde_peer *peer, struct rde_aspath *a) uint32_t as; /* - * if either ATTR_AS4_AGGREGATOR or ATTR_AS4_PATH is present - * try to fixup the attributes. - * Do not fixup if F_ATTR_PARSE_ERR is set. + * Only fix up paths for which all these conditions hold: + * - ATTR_AS4_AGGREGATOR or ATTR_AS4_PATH is present + * - ATTR_ASPATH is present as well + * - no parse error (F_ATTR_PARSE_ERR) */ - if (!(a->flags & F_ATTR_AS4BYTE_NEW) || a->flags & F_ATTR_PARSE_ERR) + if ((a->flags & F_ATTR_AS4BYTE_NEW) == 0 || + (a->flags & F_ATTR_ASPATH) == 0 || + a->flags & F_ATTR_PARSE_ERR) return; /* first get the attributes */