Commit d43752ce2a for frr
commit d43752ce2a21748cd6b761cd05fa2bb5204c64a6
Author: Philippe Guibert <philippe.guibert@6wind.com>
Date: Thu Oct 15 13:20:07 2026 +0200
bgpd: fix stack overflow in show bgp labelpool inuse
When bgpd runs with AddressSanitizer and labels are allocated from the
label pool, for instance with 'label vpn export auto' in a VRF, the
'show bgp labelpool inuse' command makes bgpd crash:
ERROR: AddressSanitizer: stack-buffer-overflow ... WRITE of size 8
The command is run by the topotest support bundle, so a failing test
makes bgpd crash on the routers where labels are in use, and all the
following test steps fail.
show_bgp_labelpool_inuse() walks the lp->inuse skiplist, whose keys
are the labels stored as pointers. It passes the address of an
mpls_label_t (4 bytes) as the key pointer of skiplist_next(), which
writes a void * (8 bytes) there. Also, the next iterations call
skiplist_next() on lp->ledger instead of lp->inuse; this has no effect
because skiplist_next() follows the cursor, but it is misleading.
Fix this by reading the key into a void * and converting it to the
label, and by walking lp->inuse in the loop increment too.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index 1afd5066b5..fa2460e03b 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -1009,6 +1009,7 @@ DEFUN(show_bgp_labelpool_inuse, show_bgp_labelpool_inuse_cmd,
mpls_label_t label;
struct lp_lcb *lcb;
void *cursor = NULL;
+ void *key;
const struct prefix *p;
int rc, count;
@@ -1035,10 +1036,9 @@ DEFUN(show_bgp_labelpool_inuse, show_bgp_labelpool_inuse_cmd,
vty_out(vty, "Prefix Label\n");
vty_out(vty, "---------------------------\n");
}
- for (rc = skiplist_next(lp->inuse, (void **)&label, (void **)&dest,
- &cursor);
- !rc; rc = skiplist_next(lp->ledger, (void **)&label,
- (void **)&dest, &cursor)) {
+ for (rc = skiplist_next(lp->inuse, &key, (void **)&dest, &cursor); !rc;
+ rc = skiplist_next(lp->inuse, &key, (void **)&dest, &cursor)) {
+ label = (uintptr_t)key;
if (skiplist_search(lp->ledger, dest, (void **)&lcb))
continue;