tailscale/tailscale
NetworkManager IPv4 DNS addresses encoded with native endianness instead of network byte order
Summary
Context: The NetworkManager DNS integration code encodes IPv4 addresses as uint32 values for NetworkManager's DBus API.
Bug: The code uses
binary.NativeEndianinstead ofbinary.BigEndianto convert IPv4 addresses to uint32.Actual vs. expected: On little-endian systems (x86/AMD64), IPv4 addresses are byte-swapped, causing NetworkManager to receive incorrect DNS server addresses instead of network byte order (big-endian) values as specified in its API documentation.
Impact: DNS queries are sent to incorrect IP addresses, causing resolution failures for users with custom DNS configurations on NetworkManager-managed Linux systems.
Code with bug
File: net/dns/nm.go
NetworkManager's DBus API documentation at developer.gnome.org/NetworkManager/stable/settings-ipv4.html explicitly states that IPv4 addresses must be "in network byte order" (big-endian).
Example
On little-endian systems (x86/AMD64), the byte-swapping produces incorrect addresses:
Input IP | Bytes | Current (NativeEndian) | Expected (BigEndian) | NetworkManager Interprets As |
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The bug has remained undetected because the most commonly used Tailscale DNS server IP (100.100.100.100) is a palindrome that produces the same encoding regardless of byte order. Additionally, NetworkManager mode is less common than other DNS management modes like systemd-resolved.
Recommended fix
Change binary.NativeEndian to binary.BigEndian:
This aligns with NetworkManager's API requirements and the consistent pattern used throughout the codebase for network protocol encoding (e.g., net/packet/ip4.go).