From de20a78a1f8005afea0f8268ac74038a001e808a Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 9 Jan 2026 21:40:38 +0100 Subject: [PATCH] fix(routing): defensive clone of AddrInfo from provider channel (#11120) Belt-and-suspenders defense against data races where routing subsystem (DHT or delegated routing) may reuse backing array. Clones AddrInfo before publishing to QueryEvent to ensure isolated copy. Closes https://github.com/ipfs/kubo/issues/11116 --- core/commands/cmdutils/utils.go | 12 ++++++++++++ core/commands/routing.go | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/core/commands/cmdutils/utils.go b/core/commands/cmdutils/utils.go index c793f516e..30249d016 100644 --- a/core/commands/cmdutils/utils.go +++ b/core/commands/cmdutils/utils.go @@ -2,12 +2,14 @@ package cmdutils import ( "fmt" + "slices" cmds "github.com/ipfs/go-ipfs-cmds" "github.com/ipfs/boxo/path" "github.com/ipfs/go-cid" coreiface "github.com/ipfs/kubo/core/coreiface" + "github.com/libp2p/go-libp2p/core/peer" ) const ( @@ -84,3 +86,13 @@ func PathOrCidPath(str string) (path.Path, error) { // Send back original err. return nil, originalErr } + +// CloneAddrInfo returns a copy of the AddrInfo with a cloned Addrs slice. +// This prevents data races if the sender reuses the backing array. +// See: https://github.com/ipfs/kubo/issues/11116 +func CloneAddrInfo(ai peer.AddrInfo) peer.AddrInfo { + return peer.AddrInfo{ + ID: ai.ID, + Addrs: slices.Clone(ai.Addrs), + } +} diff --git a/core/commands/routing.go b/core/commands/routing.go index a49e5dd32..5e1d5334d 100644 --- a/core/commands/routing.go +++ b/core/commands/routing.go @@ -11,6 +11,7 @@ import ( "github.com/ipfs/kubo/config" cmdenv "github.com/ipfs/kubo/core/commands/cmdenv" + "github.com/ipfs/kubo/core/commands/cmdutils" "github.com/ipfs/kubo/core/node" mh "github.com/multiformats/go-multihash" @@ -89,7 +90,7 @@ var findProvidersRoutingCmd = &cmds.Command{ defer cancel() pchan := n.Routing.FindProvidersAsync(ctx, c, numProviders) for p := range pchan { - np := p + np := cmdutils.CloneAddrInfo(p) routing.PublishQueryEvent(ctx, &routing.QueryEvent{ Type: routing.Provider, Responses: []*peer.AddrInfo{&np},