mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-13 14:29:49 -04:00
Android denies app UIDs both NETLINK_ROUTE (golang/go#40569, #2293) and /proc/net, so net.Interfaces always fails and netmon.New errors out before a standalone binary can do anything. The Android app solves this from Java via netmon.RegisterInterfaceGetter, but raw binaries run under Termux or a rooted shell have no Java to lean on. This is the second half of #21129, following the androiddns feature. I added a netmon fallback hook, consulted only when no interface getter was registered and net.Interfaces failed, and a new androidbin feature (ts_omit_androidbin) that implements it: report a single synthetic interface whose v4 and v6 addresses come from asking the kernel to route an outbound UDP socket, which sends no packets and is permitted in the app sandbox. That's enough for magicsock to discover local endpoints. The fallback also requires runtime evidence of Android (GOOS=android, or /dev/__properties__ existing for GOOS=linux binaries running under an Android kernel), so it's inert on regular Linux. The androidbin feature also blank imports androiddns, and fixes a third gap I found while testing: GOOS=linux binaries on Android have an empty CA root pool, because Go's unix root loader doesn't know Android's /system/etc/security/cacerts (the GOOS=android loader does), so all TLS verification fails. On Android it points SSL_CERT_DIR there unless the user already set it, as Termux's ca-certificates package does. The feature is on by default in tailscaled builds on Linux and Android via condregister, and deliberately not linked into tsnet by default; tsnet apps and other programs opt in with a blank import of tailscale.com/feature/androidbin. I verified on an Android 13 emulator with SELinux enforcing, running GOOS=linux static binaries under the app UID (run-as), where net.Interfaces fails with the exact netlinkrib permission denial from the issue: netmon.New succeeds with the synthetic interface, and a tailcat binary importing this feature does DNS via dnsproxyd, fetches its DERP map over TLS using the Android cert store, completes STUN, selects a DERP region, and prints its address. Updates #21129 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: If7dbcbb825ecd24bcf6d9d64b1e334dd00700d51
14 lines
563 B
Go
14 lines
563 B
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
// Code generated by gen.go; DO NOT EDIT.
|
|
|
|
//go:build !ts_omit_androidbin
|
|
|
|
package buildfeatures
|
|
|
|
// HasAndroidBin is whether the binary was built with support for modular feature "Support for running raw (non-GUI app) binaries on Android: netmon interface discovery under the app sandbox".
|
|
// Specifically, it's whether the binary was NOT built with the "ts_omit_androidbin" build tag.
|
|
// It's a const so it can be used for dead code elimination.
|
|
const HasAndroidBin = true
|