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;