mirror of
https://github.com/slackhq/nebula.git
synced 2026-11-15 17:06:52 +01:00
Enumerate Android interfaces without anet
anet's only reason to need -ldflags=-checklinkname=0 is a pair of //go:linkname pulls that refresh the IPv6 zone caches inside net and x/net after it enumerates interfaces. localAddrs never resolves a zone and drops link-local addresses anyway, so nebula was paying for that flag, and disabling the linker's check for the whole binary, for nothing it used. Replace the dependency with the part of anet that matters: an RTM_GETADDR dump on a netlink socket that is never bound, and SIOCGIFNAME to name each index. Both are permitted to Android apps, and it is the same path Bionic's getifaddrs takes for app UIDs. It is built only for android; every other platform, Linux included, keeps net.Interfaces. One dump yields every interface with its addresses, so reshape the seam to a single enumerator returning localInterface values with a deferred Addrs. Android hands back what it already has; every other platform still only asks for the addresses of interfaces the allow list accepts. Take the bind-free path unconditionally on android. The sepolicy is keyed to the app's target SDK rather than the OS release, detecting either needs cgo, and the path is valid on every release. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B15ivF2aJUtLFdqJ4iz6zs
This commit is contained in:
1 parent
8589b76e1f
commit
fcc6008a78
7 files changed
+250
-49
No files matched your search
+25
-14
@@ -425,11 +425,24 @@ func TestCollectLocalAddrs(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
enumerate := func() ([]net.Interface, error) { return ifaces, nil }
|
||||
addrsFor := func(i *net.Interface) ([]net.Addr, error) { return addrs[i.Name], nil }
|
||||
// enumerate wraps ifaces with the given address lookup.
|
||||
enumerate := func(addrsFor func(name string) ([]net.Addr, error)) func() ([]localInterface, error) {
|
||||
return func() ([]localInterface, error) {
|
||||
out := make([]localInterface, 0, len(ifaces))
|
||||
for _, i := range ifaces {
|
||||
name := i.Name
|
||||
out = append(out, localInterface{
|
||||
Name: name,
|
||||
Addrs: func() ([]net.Addr, error) { return addrsFor(name) },
|
||||
})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
addrsFor := func(name string) ([]net.Addr, error) { return addrs[name], nil }
|
||||
|
||||
// Loopback and link local are dropped, everything else on every interface is kept.
|
||||
out, err := collectLocalAddrs(test.NewLogger(), nil, enumerate, addrsFor)
|
||||
out, err := collectLocalAddrs(test.NewLogger(), nil, enumerate(addrsFor))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []netip.Addr{
|
||||
netip.MustParseAddr("10.0.0.5"),
|
||||
@@ -446,11 +459,11 @@ func TestCollectLocalAddrs(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
asked := make(map[string]struct{})
|
||||
countingAddrsFor := func(i *net.Interface) ([]net.Addr, error) {
|
||||
asked[i.Name] = struct{}{}
|
||||
return addrs[i.Name], nil
|
||||
countingAddrsFor := func(name string) ([]net.Addr, error) {
|
||||
asked[name] = struct{}{}
|
||||
return addrs[name], nil
|
||||
}
|
||||
out, err = collectLocalAddrs(test.NewLogger(), al, enumerate, countingAddrsFor)
|
||||
out, err = collectLocalAddrs(test.NewLogger(), al, enumerate(countingAddrsFor))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []netip.Addr{
|
||||
netip.MustParseAddr("10.0.0.5"),
|
||||
@@ -462,8 +475,7 @@ func TestCollectLocalAddrs(t *testing.T) {
|
||||
out, err = collectLocalAddrs(
|
||||
test.NewLogger(),
|
||||
nil,
|
||||
func() ([]net.Interface, error) { return nil, errors.New("netlinkrib: permission denied") },
|
||||
addrsFor,
|
||||
func() ([]localInterface, error) { return nil, errors.New("netlinkrib: permission denied") },
|
||||
)
|
||||
assert.Nil(t, out)
|
||||
require.EqualError(t, err, "failed to enumerate local interfaces: netlinkrib: permission denied")
|
||||
@@ -472,13 +484,12 @@ func TestCollectLocalAddrs(t *testing.T) {
|
||||
out, err = collectLocalAddrs(
|
||||
test.NewLogger(),
|
||||
nil,
|
||||
enumerate,
|
||||
func(i *net.Interface) ([]net.Addr, error) {
|
||||
if i.Name == "eth0" {
|
||||
enumerate(func(name string) ([]net.Addr, error) {
|
||||
if name == "eth0" {
|
||||
return nil, errors.New("nope")
|
||||
}
|
||||
return addrs[i.Name], nil
|
||||
},
|
||||
return addrs[name], nil
|
||||
}),
|
||||
)
|
||||
assert.Equal(t, []netip.Addr{netip.MustParseAddr("172.17.0.1")}, out)
|
||||
require.EqualError(t, err, "failed to get addresses for eth0: nope")
|
||||
|
||||
Reference in new issue
Block a user