From 5f3bddc663008a6e55458017fed72406b854a0b7 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 17 Mar 2026 09:43:00 +0000 Subject: [PATCH] hscontrol/policy/v2: fix nil dereferences in alias resolution Fix three nil dereference issues in the policy resolution code: - newResolvedAddresses: preserve partial IP results when errors occur instead of discarding valid IPSets. Callers already handle errors and nil results independently, so returning both allows partial resolution (e.g. groups with phantom users) to work correctly. - resolveTagOwners: guard against nil ResolvedAddresses before calling Prefixes(), since Resolve may return nil when resolution fails. - Asterix.resolve: guard against nil *Policy pointer, which occurs when resolving wildcards without a policy context (e.g. in tests). Updates #2180 --- hscontrol/policy/v2/policy.go | 6 ++++-- hscontrol/policy/v2/types.go | 10 +++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/hscontrol/policy/v2/policy.go b/hscontrol/policy/v2/policy.go index 5852c410..3ef72a16 100644 --- a/hscontrol/policy/v2/policy.go +++ b/hscontrol/policy/v2/policy.go @@ -1198,8 +1198,10 @@ func resolveTagOwners(p *Policy, users types.Users, nodes views.Slice[types.Node case Alias: // If it does not resolve, that means the tag is not associated with any IP addresses. resolved, _ := o.Resolve(p, users, nodes) - for _, pref := range resolved.Prefixes() { - ips.AddPrefix(pref) + if resolved != nil { + for _, pref := range resolved.Prefixes() { + ips.AddPrefix(pref) + } } default: diff --git a/hscontrol/policy/v2/types.go b/hscontrol/policy/v2/types.go index cb20389f..cc194e29 100644 --- a/hscontrol/policy/v2/types.go +++ b/hscontrol/policy/v2/types.go @@ -140,15 +140,11 @@ func newResolved(ipb *netipx.IPSetBuilder) (resolved, error) { } func newResolvedAddresses(ips *netipx.IPSet, err error) (ResolvedAddresses, error) { - if err != nil { + if ips == nil { return nil, err } - if ips == nil { - return nil, nil - } - - return resolved{ips: *ips}, nil + return resolved{ips: *ips}, err } func ipSetToStrings(ips *netipx.IPSet) []string { @@ -301,7 +297,7 @@ func (a Asterix) Resolve(p *Policy, u types.Users, n views.Slice[types.NodeView] } func (a Asterix) resolve(p *Policy, _ types.Users, _ views.Slice[types.NodeView]) (*netipx.IPSet, error) { - if pfxs := p.AutoApprovers.prefixes(); len(pfxs) > 0 { + if p != nil && len(p.AutoApprovers.prefixes()) > 0 { var ipb netipx.IPSetBuilder ipb.AddSet(asterixResolved())