From 761fe19e5f5ee60622d9bc00900989111884dd02 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 15 Sep 2020 10:00:23 -0700 Subject: [PATCH] control/controlclient: don't accept /32 routes without --accept-routes Fixes tailscale/corp#500 Signed-off-by: Brad Fitzpatrick --- control/controlclient/netmap.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/control/controlclient/netmap.go b/control/controlclient/netmap.go index 2f7f39a5b..819560ab1 100644 --- a/control/controlclient/netmap.go +++ b/control/controlclient/netmap.go @@ -273,7 +273,7 @@ func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Confi logf("wgcfg: %v skipping default route", peer.Key.ShortString()) continue } - } else if allowedIP.Mask < 32 { + } else if cidrIsSubnet(peer, allowedIP) { if (flags & AllowSubnetRoutes) == 0 { logf("wgcfg: %v skipping subnet route", peer.Key.ShortString()) continue @@ -286,6 +286,29 @@ func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Confi return cfg, nil } +// cidrIsSubnet reports whether cidr is a non-default-route subnet +// exported by node that is not one of its own self addresses. +func cidrIsSubnet(node *tailcfg.Node, cidr wgcfg.CIDR) bool { + if cidr.Mask == 0 { + return false + } + if cidr.Mask < 32 { + // Fast path for IPv4, to avoid loop below. + // + // TODO: if cidr.IP is an IPv6 address, we could do "< 128" + // to avoid the range over node.Addresses. Or we could + // just remove this fast path and unconditionally do the range + // loop. + return true + } + for _, selfCIDR := range node.Addresses { + if cidr == selfCIDR { + return false + } + } + return true +} + func appendEndpoint(peer *wgcfg.Peer, epStr string) error { if epStr == "" { return nil