From sybdorsett at proton.me Fri May 1 13:31:08 2026 From: sybdorsett at proton.me (Sybil Isabel Dorsett) Date: Fri, 01 May 2026 13:31:08 +0000 Subject: [PATCH v2] wg-quick: add SocketNamespace for UDP socket netns Message-ID: <20260501133048.3630-1-sybdorsett@proton.me> wg-quick cannot express WireGuard's supported deployment model in which the UDP socket resides in a different network namespace than the interface. This model is documented and used in practice for cases such as keeping routing policy and tunnel endpoints in separate namespaces (e.g. container or policy isolation setups). Achieving this today requires reimplementing substantial parts of wg-quick externally, including interface lifecycle, address assignment, routing, and teardown. Add a SocketNamespace option to select the network namespace in which the WireGuard UDP socket is created, while keeping the interface in the invoking namespace. Create the interface in the target namespace so that sockets are bound there, then move it back to the caller's namespace before executing PreUp hooks. Limit the scope to selecting the socket namespace only, without introducing general network namespace management, persistent state, or changes to default behavior. Document SocketNamespace in the man page and update highlighters. Signed-off-by: Sybil Isabel Dorsett --- v2: - Resend for visibility; no functional changes - Clarify commit message Reference (earlier discussion on mailing list): - https://lists.zx2c4.com/pipermail/wireguard/2020-March/005143.html Implementation notes: - Limit scope to socket namespace only (no general netns management) - Return the interface to the caller namespace before hook execution - Use PID-based netns targeting instead of fixed namespace IDs - Ensure userspace fallback (wireguard-go) runs in SocketNamespace, preserving socket placement - Prevent namespace errors from triggering kernel/userspace fallback paths contrib/highlighter/gui/highlight.cpp | 1 + contrib/highlighter/highlight.c | 1 + contrib/highlighter/highlighter.c | 23 +++++++++++++++++++++++ contrib/highlighter/highlighter.h | 1 + src/man/wg-quick.8 | 5 +++++ src/wg-quick/linux.bash | 15 ++++++++++++--- 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/contrib/highlighter/gui/highlight.cpp b/contrib/highlighter/gui/highlight.cpp index a95857b..7c4e4ac 100644 --- a/contrib/highlighter/gui/highlight.cpp +++ b/contrib/highlighter/gui/highlight.cpp @@ -25,6 +25,7 @@ static QColor colormap[] = { [HighlightDelimiter] = QColor("#7aa6da"), #ifndef MOBILE_WGQUICK_SUBSET [HighlightTable] = QColor("#c397d8"), + [HighlightSocketNamespace] = QColor("#c397d8"), [HighlightFwMark] = QColor("#c397d8"), [HighlightSaveConfig] = QColor("#c397d8"), [HighlightCmd] = QColor("#969896"), diff --git a/contrib/highlighter/highlight.c b/contrib/highlighter/highlight.c index 8dc0d49..a18f039 100644 --- a/contrib/highlighter/highlight.c +++ b/contrib/highlighter/highlight.c @@ -51,6 +51,7 @@ static const char *colormap[] = { [HighlightDelimiter] = TERMINAL_FG_CYAN, #ifndef MOBILE_WGQUICK_SUBSET [HighlightTable] = TERMINAL_FG_BLUE, + [HighlightSocketNamespace] = TERMINAL_FG_BLUE, [HighlightFwMark] = TERMINAL_FG_BLUE, [HighlightSaveConfig] = TERMINAL_FG_BLUE, [HighlightCmd] = TERMINAL_FG_WHITE, diff --git a/contrib/highlighter/highlighter.c b/contrib/highlighter/highlighter.c index 3c34f1c..5264ac9 100644 --- a/contrib/highlighter/highlighter.c +++ b/contrib/highlighter/highlighter.c @@ -223,6 +223,24 @@ static bool is_valid_persistentkeepalive(string_span_t s) #ifndef MOBILE_WGQUICK_SUBSET +static bool is_valid_filename(string_span_t s) +{ + if (s.len > 128 || !s.len) + return false; + if (s.len == 1 && s.s[0] == '.') + return false; + if (s.len == 2 && s.s[0] == '.' && s.s[1] == '.') + return false; + if (s.s[0] == '-') + return false; + for (size_t i = 0; i < s.len; ++i) { + if (!is_alphabet(s.s[i]) && !is_decimal(s.s[i]) && + s.s[i] != '_' && s.s[i] != '-' && s.s[i] != '.') + return false; + } + return true; +} + static bool is_valid_fwmark(string_span_t s) { if (is_same(s, "off")) @@ -345,6 +363,7 @@ enum field { DNS, MTU, #ifndef MOBILE_WGQUICK_SUBSET + SocketNamespace, FwMark, Table, PreUp, PostUp, PreDown, PostDown, @@ -384,6 +403,7 @@ static enum field get_field(string_span_t s) check_enum(Endpoint); check_enum(PersistentKeepalive); #ifndef MOBILE_WGQUICK_SUBSET + check_enum(SocketNamespace); check_enum(FwMark); check_enum(Table); check_enum(PreUp); @@ -526,6 +546,9 @@ static void highlight_value(struct highlight_span_array *ret, const string_span_ case SaveConfig: append_highlight_span(ret, parent.s, s, is_valid_saveconfig(s) ? HighlightSaveConfig : HighlightError); break; + case SocketNamespace: + append_highlight_span(ret, parent.s, s, is_valid_filename(s) ? HighlightSocketNamespace : HighlightError); + break; case FwMark: append_highlight_span(ret, parent.s, s, is_valid_fwmark(s) ? HighlightFwMark : HighlightError); break; diff --git a/contrib/highlighter/highlighter.h b/contrib/highlighter/highlighter.h index ecbce00..d7d6600 100644 --- a/contrib/highlighter/highlighter.h +++ b/contrib/highlighter/highlighter.h @@ -21,6 +21,7 @@ enum highlight_type { HighlightDelimiter, #ifndef MOBILE_WGQUICK_SUBSET HighlightTable, + HighlightSocketNamespace, HighlightFwMark, HighlightSaveConfig, HighlightCmd, diff --git a/src/man/wg-quick.8 b/src/man/wg-quick.8 index bc9e145..1a7c9a6 100644 --- a/src/man/wg-quick.8 +++ b/src/man/wg-quick.8 @@ -102,6 +102,11 @@ the commands are executed in order. SaveConfig \(em if set to `true', the configuration is saved from the current state of the interface upon shutdown. Any changes made to the configuration file before the interface is removed will therefore be overwritten. +.IP \(bu +SocketNamespace \(em the name of an existing network namespace (netns) +in which the interface's UDP sockets are created. If specified, the interface +is first added to that netns, then moved to the invoking process's native netns +before any other interface settings are applied. .P Recommended \fIINTERFACE\fP names include `wg0' or `wgvpn0' or even `wgmgmtlan0'. diff --git a/src/wg-quick/linux.bash b/src/wg-quick/linux.bash index 18e266c..1349d70 100755 --- a/src/wg-quick/linux.bash +++ b/src/wg-quick/linux.bash @@ -13,6 +13,7 @@ export PATH="${SELF%/*}:$PATH" WG_CONFIG="" INTERFACE="" +SOCKET_NAMESPACE="" ADDRESSES=( ) MTU="" DNS=( ) @@ -56,6 +57,7 @@ parse_options() { [[ $key == "[Interface]" ]] && interface_section=1 if [[ $interface_section -eq 1 ]]; then case "$key" in + SocketNamespace) SOCKET_NAMESPACE="$value"; continue ;; Address) ADDRESSES+=( ${value//,/ } ); continue ;; MTU) MTU="$value"; continue ;; DNS) for v in ${value//,/ }; do @@ -88,12 +90,14 @@ auto_su() { add_if() { local ret - if ! cmd ip link add dev "$INTERFACE" type wireguard; then + trap 'cmd "${netns_exec[@]}" ip link delete dev "$INTERFACE"; exit' INT TERM EXIT + if ! cmd "${netns_exec[@]}" ip link add dev "$INTERFACE" type wireguard; then ret=$? [[ -e /sys/module/wireguard ]] || ! command -v "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" >/dev/null && exit $ret echo "[!] Missing WireGuard kernel module. Falling back to slow userspace implementation." >&2 - cmd "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" "$INTERFACE" + cmd "${netns_exec[@]}" "${WG_QUICK_USERSPACE_IMPLEMENTATION:-wireguard-go}" "$INTERFACE" fi + [[ -z "$SOCKET_NAMESPACE" ]] || cmd "${netns_exec[@]}" ip link set "$INTERFACE" netns $$ } del_if() { @@ -256,6 +260,7 @@ save_config() { local old_umask new_config current_config address cmd [[ $(ip -all -brief address show dev "$INTERFACE") =~ ^$INTERFACE\ +\ [A-Z]+\ +(.+)$ ]] || true new_config=$'[Interface]\n' + [[ -z "$SOCKET_NAMESPACE" ]] || new_config+="SocketNamespace = $SOCKET_NAMESPACE"$'\n' for address in ${BASH_REMATCH[1]}; do new_config+="Address = $address"$'\n' done @@ -326,9 +331,13 @@ cmd_usage() { cmd_up() { local i + local netns_exec=() + [[ -z "$SOCKET_NAMESPACE" ]] || netns_exec=(ip netns exec "$SOCKET_NAMESPACE") + "${netns_exec[@]}" true || die "Network namespace '${SOCKET_NAMESPACE:-}' does not exist" [[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" - trap 'del_if; exit' INT TERM EXIT + [[ -z $("${netns_exec[@]}" ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists in network namespace '${SOCKET_NAMESPACE:-}'" add_if + trap 'del_if; exit' INT TERM EXIT execute_hooks "${PRE_UP[@]}" set_config for i in "${ADDRESSES[@]}"; do -- 2.39.5 From Jason at zx2c4.com Sun May 3 19:18:18 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Sun, 3 May 2026 21:18:18 +0200 Subject: [PATCH wireguard] wireguard: prevent ipv6 addrconf via IFF_NO_ADDRCONF flag In-Reply-To: References: <20260208170545.31942-1-valentin@spreckels.dev> Message-ID: On Sat, Mar 21, 2026 at 08:20:53PM +0100, Valentin Spreckels wrote: > Hi Jason, > > On 11/03/2026 23:59, Jason A. Donenfeld wrote: > > Hi Valentin, > > > > On Sun, Feb 08, 2026 at 06:05:45PM +0100, Valentin Spreckels wrote: > >> Use the flag introduced in commit 8a321cf7becc6 ("net: add > >> IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf") > >> instead of mangling the addr_gen_mode to prevent ipv6 addrconf. > > > > Can you give some more context here? Why was IFF_NO_ADDRCONF added when > > the IN6_ADDR_GEN_MODE_NONE method has been working fine? What's the > > difference between these approaches? I don't doubt that your patch is > > correct, but I would like to better understand this. > > Only wireguard configures addr_gen_mode inside the kernel, otherwise it > is only set by userspace; userspace is also able to overwrite the > IFF_NO_ADDRCONF set by wireguard. > > Commit 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to > prevent ipv6 addrconf") introduces the private interface flag > IFF_NO_ADDRCONF, which isn't accessible by userspace. > > Thus use the IFF_NO_ADDRCONF flag in wireguard. > > > Does that answer your questions? If yes, I will submit a v2 with this as > commit message. I applied this here: https://git.zx2c4.com/wireguard-linux/commit/?id=88427bcbe5bd3711de387b1c1f6540ef6fc05a78 Sorry for the delay! Patch looks good as-is, once I looked into the internal mechanism. Jason From Jason at zx2c4.com Mon May 4 11:55:03 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 4 May 2026 13:55:03 +0200 Subject: [PATCH] wg-quick: fix darwin MTU detection In-Reply-To: <20251020142254.16546-2-florian@uekermann.me> References: <20251020142254.16546-2-florian@uekermann.me> Message-ID: Hi Florian, Sorry I didn't see this. I filtered this out because it wasn't formatted correctly (explanation below the break, commit subject not matching other wg-quick commits). Some notes: On Mon, Oct 20, 2025 at 04:22:55PM +0200, Florian Uekermann wrote: > I used macOS 15.4 for testing, but I am not particularly familiar with > the Apple ecosystem. I'm not sure if this never worked, the netstat > shipped by Apple changed at some point and how/which other platforms > (iOS?) may be affected. So please keep that in mind before merging. If you're submitting a patch with your name on it, please do the research to make sure it's correct! Otherwise, what you're submitting is more of a bug report than a patch. > src/wg-quick/darwin.bash | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/src/wg-quick/darwin.bash b/src/wg-quick/darwin.bash > index 1b7fe5e..0467f0e 100755 > --- a/src/wg-quick/darwin.bash > +++ b/src/wg-quick/darwin.bash > @@ -177,7 +177,7 @@ set_mtu() { > cmd ifconfig "$REAL_INTERFACE" mtu "$MTU" > return > fi > - while read -r destination _ _ _ _ netif _; do > + while read -r destination _ _ netif _; do Should this be changed for the other invocations of `netstat -nr -f ...` in the code? It's a bit confusing because in del_route(), it looks like the first invocation (for inet) is aware that it's the 6th parameter, while the second invocation (for inet6) seems to stick with this presumption that it's the 4th. So what's going on here? Consulting the source from Apple, it looks like the 4th param is indeed the right one? https://github.com/apple-oss-distributions/network_cmds/blob/97e27e6244c16d399bfeb254315ddc5828711c56/netstat.tproj/route.c#L328 What circumstances cause this to change? v4 vs v6? Something else? I'd like to get to the bottom of this before applying this patch. When you submit a v2, please include your explanation as part of the commit message. Thanks, Jason From Jason at zx2c4.com Tue May 5 15:05:19 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Tue, 5 May 2026 17:05:19 +0200 Subject: [PATCH wireguard] wireguard: prevent ipv6 addrconf via IFF_NO_ADDRCONF flag In-Reply-To: References: <20260208170545.31942-1-valentin@spreckels.dev> Message-ID: On Sun, May 03, 2026 at 09:18:18PM +0200, Jason A. Donenfeld wrote: > On Sat, Mar 21, 2026 at 08:20:53PM +0100, Valentin Spreckels wrote: > > Hi Jason, > > > > On 11/03/2026 23:59, Jason A. Donenfeld wrote: > > > Hi Valentin, > > > > > > On Sun, Feb 08, 2026 at 06:05:45PM +0100, Valentin Spreckels wrote: > > >> Use the flag introduced in commit 8a321cf7becc6 ("net: add > > >> IFF_NO_ADDRCONF and use it in bonding to prevent ipv6 addrconf") > > >> instead of mangling the addr_gen_mode to prevent ipv6 addrconf. > > > > > > Can you give some more context here? Why was IFF_NO_ADDRCONF added when > > > the IN6_ADDR_GEN_MODE_NONE method has been working fine? What's the > > > difference between these approaches? I don't doubt that your patch is > > > correct, but I would like to better understand this. > > > > Only wireguard configures addr_gen_mode inside the kernel, otherwise it > > is only set by userspace; userspace is also able to overwrite the > > IFF_NO_ADDRCONF set by wireguard. > > > > Commit 8a321cf7becc ("net: add IFF_NO_ADDRCONF and use it in bonding to > > prevent ipv6 addrconf") introduces the private interface flag > > IFF_NO_ADDRCONF, which isn't accessible by userspace. > > > > Thus use the IFF_NO_ADDRCONF flag in wireguard. > > > > > > Does that answer your questions? If yes, I will submit a v2 with this as > > commit message. > > I applied this here: > https://git.zx2c4.com/wireguard-linux/commit/?id=88427bcbe5bd3711de387b1c1f6540ef6fc05a78 > > Sorry for the delay! Patch looks good as-is, once I looked into the > internal mechanism. I'm backing this patch out for now. It seems to break the selftests: [+] NS2: ping6 -c 10 -f -W 1 fd00::1 ping6: connect: Network unreachable Try it yourself with: $ make -C tools/testing/selftests/wireguard/qemu -j$(nproc) I assume it's because of: case NETDEV_UP: case NETDEV_CHANGE: if (idev && idev->cnf.disable_ipv6) break; if (dev->priv_flags & IFF_NO_ADDRCONF) { [...] break; } Feel free to submit a v2 if you think this is fixable or if the tests themselves are wrong. Jason From florian at uekermann.me Tue May 5 16:47:33 2026 From: florian at uekermann.me (Florian Uekermann) Date: Tue, 5 May 2026 18:47:33 +0200 Subject: [PATCH] wg-quick: fix darwin MTU detection In-Reply-To: References: <20251020142254.16546-2-florian@uekermann.me> Message-ID: <8358be3e-d696-454e-a970-2305f23fce2f@uekermann.me> Hi Jason, Thanks for following up. On 04/05/2026 13:55, Jason A. Donenfeld wrote: > If you're submitting a patch with your name on it, please do the > research to make sure it's correct! Otherwise, what you're submitting is > more of a bug report than a patch. Please treat this as a bug report. That's why I added the disclaimer. I tried a number of different things before sending this patch with ack, because I wasn't able to get the bug report through the filter (mailing list, mod-mail) or noticed (IRC, Github) after many failed attempts to report it. Some avenue for drive-by bug reports may be beneficial (maybe Github issues). I had given up on reporting this until your reply. Anyway, happy you saw this now. > Should this be changed for the other invocations of `netstat -nr -f ...` > in the code? It's a bit confusing because in del_route(), it looks like > the first invocation (for inet) is aware that it's the 6th parameter, > while the second invocation (for inet6) seems to stick with this > presumption that it's the 4th. So what's going on here? I also suspect del_route needs to be adjusted too, but I have no idea what's going on here. > I'd like to get to the bottom of this before applying this patch. When > you submit a v2, please include your explanation as part of the commit > message. Sorry, I'm not very familiar with the Apple ecosystem and can't figure out what exactly happened or should be done here with the necessary confidence. Please just take this as a bug report. Best regards, Florian From Jason at zx2c4.com Wed May 6 21:28:53 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Wed, 6 May 2026 23:28:53 +0200 Subject: [PATCH] wg-quick: fix darwin MTU detection In-Reply-To: <8358be3e-d696-454e-a970-2305f23fce2f@uekermann.me> References: <20251020142254.16546-2-florian@uekermann.me> <8358be3e-d696-454e-a970-2305f23fce2f@uekermann.me> Message-ID: Hi Florian, Could you test this? https://git.zx2c4.com/wireguard-tools/commit/?id=a998407747005ea7e4e0258d96f105c97241e1d3 Thanks, Jason From Jason at zx2c4.com Thu May 7 13:01:03 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Thu, 7 May 2026 15:01:03 +0200 Subject: Sunsetting support for old Windows versions In-Reply-To: References: Message-ID: On Mon, Mar 23, 2026 at 6:09?PM Jason A. Donenfeld wrote: > I must admit, however, that I am a bit sad about this. After coding up > [1] this dialog box for the installer, I felt a few pangs of sadness > when testing it for the first time on Windows 7 and seeing the tragic > result: https://data.zx2c4.com/bye-bye-wg-win7.png . But it was a > familiar feeling. For, long ago, I'd already watched the beauty of > Windows fall to pieces. To me, Windows 2000 is the most beautiful of In order to reduce user confusion, this dialog box for old Windows installations is now augmented with this email thread opening: https://data.zx2c4.com/windows7-update-sunset-flow.gif . This especially helps with the update flow on old Windows, where dialog boxes aren't shown. Hopefully this reduces the amount of confused emails I've been receiving, while also not lulling old Windows users into a false sense of security by disabling all update notifications. Jason From florian at uekermann.me Fri May 8 13:42:03 2026 From: florian at uekermann.me (Florian Uekermann) Date: Fri, 8 May 2026 15:42:03 +0200 Subject: [PATCH] wg-quick: fix darwin MTU detection In-Reply-To: References: <20251020142254.16546-2-florian@uekermann.me> <8358be3e-d696-454e-a970-2305f23fce2f@uekermann.me> Message-ID: <7792e4d4-c66f-4981-8f2b-f59731b50bd0@uekermann.me> Hi Jason, On 06/05/2026 23:28, Jason A. Donenfeld wrote: > Could you test this? > https://git.zx2c4.com/wireguard-tools/commit/?id=a998407747005ea7e4e0258d96f105c97241e1d3 Yes, it seems to work. I tested this commit and the previous one after connecting to another VPN (to lower MTU of the default interface to 1280) and got a MTUs of 1420 and 1200 respectively. Thanks! Best regards, Florian From mjsabby at gmail.com Sun May 10 19:58:10 2026 From: mjsabby at gmail.com (Mukul Sabharwal) Date: Sun, 10 May 2026 19:58:10 +0000 Subject: [PATCH wireguard-go] conn: allow StdNetBind to bind to specific host addresses Message-ID: <20260510195810.192447-1-mjsabby@gmail.com> Currently StdNetBind opens its IPv4 and IPv6 sockets on the unspecified address (0.0.0.0 and [::]). Embedders that want the WireGuard listener restricted to a specific local address ? for example an Android application that wants its inbound peers to reach it only over Wi-Fi and never over the cellular interface, or a host with multiple interfaces where listening on a single one is preferable for routing or security reasons ? currently have to reimplement Bind from scratch just to substitute a different bind address, losing the recvmmsg / sendmmsg / GSO optimizations along the way. Add a NewStdNetBindWithBindHost(host4, host6 string) constructor that records optional per-family bind hosts on the StdNetBind. Open() passes them through to listenNet, which now uses net.JoinHostPort instead of the hardcoded ":port" wildcard. Empty strings preserve the existing any-address behavior, so NewStdNetBind() is unchanged for existing callers. Tests verify that an explicit loopback host pins both v4 and v6 listeners to loopback, and that the default constructor still binds to the unspecified address. Signed-off-by: Mukul Sabharwal --- conn/bind_std.go | 35 ++++++++++++++++++++++++++++---- conn/bind_std_test.go | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/conn/bind_std.go b/conn/bind_std.go index f5c8816..9291b4b 100644 --- a/conn/bind_std.go +++ b/conn/bind_std.go @@ -46,10 +46,37 @@ type StdNetBind struct { blackhole4 bool blackhole6 bool + + // Optional bind hosts for the IPv4 and IPv6 listeners. An empty + // string preserves the historical behavior of binding to the + // unspecified address (0.0.0.0 / [::]). These are read in Open() + // under mu and not mutated thereafter. + bindHost4 string + bindHost6 string } func NewStdNetBind() Bind { + return newStdNetBind("", "") +} + +// NewStdNetBindWithBindHost returns a StdNetBind whose IPv4 / IPv6 listeners +// bind to the supplied hosts instead of the unspecified address. An empty +// string for either argument preserves the default any-address behavior for +// that family. This is useful on hosts with multiple addresses where the +// caller wants the WireGuard listener pinned to one of them ? e.g. an +// Android app that wants its inbound peers to reach it only over Wi-Fi +// and never over the cellular interface. +// +// The hosts must parse as literal IP addresses (no DNS lookups are +// performed). They are not validated until Open() is called. +func NewStdNetBindWithBindHost(host4, host6 string) Bind { + return newStdNetBind(host4, host6) +} + +func newStdNetBind(host4, host6 string) Bind { return &StdNetBind{ + bindHost4: host4, + bindHost6: host6, udpAddrPool: sync.Pool{ New: func() any { return &net.UDPAddr{ @@ -119,8 +146,8 @@ func (e *StdNetEndpoint) DstToString() string { return e.AddrPort.String() } -func listenNet(network string, port int) (*net.UDPConn, int, error) { - conn, err := listenConfig().ListenPacket(context.Background(), network, ":"+strconv.Itoa(port)) +func listenNet(network, host string, port int) (*net.UDPConn, int, error) { + conn, err := listenConfig().ListenPacket(context.Background(), network, net.JoinHostPort(host, strconv.Itoa(port))) if err != nil { return nil, 0, err } @@ -156,13 +183,13 @@ again: var v4pc *ipv4.PacketConn var v6pc *ipv6.PacketConn - v4conn, port, err = listenNet("udp4", port) + v4conn, port, err = listenNet("udp4", s.bindHost4, port) if err != nil && !errors.Is(err, syscall.EAFNOSUPPORT) { return nil, 0, err } // Listen on the same port as we're using for ipv4. - v6conn, port, err = listenNet("udp6", port) + v6conn, port, err = listenNet("udp6", s.bindHost6, port) if uport == 0 && errors.Is(err, syscall.EADDRINUSE) && tries < 100 { v4conn.Close() tries++ diff --git a/conn/bind_std_test.go b/conn/bind_std_test.go index 34a3c9a..e5d6650 100644 --- a/conn/bind_std_test.go +++ b/conn/bind_std_test.go @@ -27,6 +27,52 @@ func TestStdNetBindReceiveFuncAfterClose(t *testing.T) { } } +func TestStdNetBindWithBindHost(t *testing.T) { + bind := NewStdNetBindWithBindHost("127.0.0.1", "::1").(*StdNetBind) + if _, _, err := bind.Open(0); err != nil { + t.Fatal(err) + } + defer bind.Close() + if bind.ipv4 == nil { + t.Fatal("ipv4 listener not opened") + } + la4, ok := bind.ipv4.LocalAddr().(*net.UDPAddr) + if !ok { + t.Fatalf("ipv4 LocalAddr is not *net.UDPAddr: %T", bind.ipv4.LocalAddr()) + } + if !la4.IP.IsLoopback() { + t.Errorf("ipv4 listener bound to %v, want loopback", la4.IP) + } + if bind.ipv6 != nil { + la6, ok := bind.ipv6.LocalAddr().(*net.UDPAddr) + if !ok { + t.Fatalf("ipv6 LocalAddr is not *net.UDPAddr: %T", bind.ipv6.LocalAddr()) + } + if !la6.IP.IsLoopback() { + t.Errorf("ipv6 listener bound to %v, want loopback", la6.IP) + } + } +} + +func TestStdNetBindDefaultBindHost(t *testing.T) { + // Empty host strings must preserve the historical wildcard behavior. + bind := NewStdNetBind().(*StdNetBind) + if _, _, err := bind.Open(0); err != nil { + t.Fatal(err) + } + defer bind.Close() + if bind.ipv4 == nil { + t.Fatal("ipv4 listener not opened") + } + la4, ok := bind.ipv4.LocalAddr().(*net.UDPAddr) + if !ok { + t.Fatalf("ipv4 LocalAddr is not *net.UDPAddr: %T", bind.ipv4.LocalAddr()) + } + if !la4.IP.IsUnspecified() { + t.Errorf("ipv4 listener bound to %v, want unspecified", la4.IP) + } +} + func mockSetGSOSize(control *[]byte, gsoSize uint16) { *control = (*control)[:cap(*control)] binary.LittleEndian.PutUint16(*control, gsoSize) -- 2.53.0 From geert at linux-m68k.org Mon May 11 06:42:13 2026 From: geert at linux-m68k.org (Geert Uytterhoeven) Date: Mon, 11 May 2026 08:42:13 +0200 Subject: crypto/ahash.c:1073:1: warning: the frame size of 1040 bytes is larger than 1024 bytes In-Reply-To: <202605100125.l4JVHppO-lkp@intel.com> References: <202605100125.l4JVHppO-lkp@intel.com> Message-ID: On Sat, 9 May 2026 at 19:07, kernel test robot wrote: > FYI, the error/warning still remains. > > tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master > head: ec89572766744e844df24c27d31c97b4c00f4e07 > commit: 9d9b193ed73a65ec47cf1fd39925b09da8216461 crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390) > date: 9 months ago > config: mips-eyeq5_defconfig (https://download.01.org/0day-ci/archive/20260510/202605100125.l4JVHppO-lkp at intel.com/config) > compiler: mips64-linux-gcc (GCC) 15.2.0 > reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260510/202605100125.l4JVHppO-lkp at intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version of > the same patch/commit), kindly add following tags > | Fixes: 9d9b193ed73a ("crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390)") > | Reported-by: kernel test robot > | Closes: https://lore.kernel.org/oe-kbuild-all/202605100125.l4JVHppO-lkp at intel.com/ > > All warnings (new ones prefixed by >>): > > crypto/ahash.c: In function 'crypto_hash_digest': > >> crypto/ahash.c:1073:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=] > 1073 | } > | ^ This is one of the few defconfigs that still use CONFIG_FRAME_WARN=1024. The default value for 32-bit systems was lifted from 1024 to 1280 in commit 32115734c0ed8b46 ("Increase the default 32-bit build frame size warning limit to 1280 bytes") in v6.18, so perhaps the downgrade to 1024 should be dropped from the following defconfigs: $ git grep CONFIG_FRAME_WARN=1024 arch/mips/configs/eyeq5_defconfig:CONFIG_FRAME_WARN=1024 arch/mips/configs/eyeq6_defconfig:CONFIG_FRAME_WARN=1024 arch/mips/configs/eyeq6lplus_defconfig:CONFIG_FRAME_WARN=1024 arch/mips/configs/lemote2f_defconfig:CONFIG_FRAME_WARN=1024 arch/mips/configs/loongson2k_defconfig:CONFIG_FRAME_WARN=1024 arch/powerpc/configs/fsl-emb-nonhw.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/arm.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/armeb.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/i686.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/m68k.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/mips.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/mipsel.config:CONFIG_FRAME_WARN=1024 tools/testing/selftests/wireguard/qemu/arch/powerpc.config:CONFIG_FRAME_WARN=1024 I am not sure about the wireguard selftests: they might use the lower value deliberately for testing? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds From Jason at zx2c4.com Tue May 12 07:08:25 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Tue, 12 May 2026 09:08:25 +0200 Subject: Unable to use wireguard 0.6 / 1.0 / 1.0.1 on Windows 24H2 In-Reply-To: References: Message-ID: Hi Justin, I'm working on this now. I think I have a decent idea of what's happening (odd windows bug), but could you email me (privately) all of the logs in \windows\inf\, including the historical backup ones, the offline ones, the upgrade ones, the setup ones, etc, so I can try to figure out the whole flow of the bug? Thanks, Jason From konstantineb at pm.me Tue May 12 14:50:53 2026 From: konstantineb at pm.me (konstantineb at pm.me) Date: Tue, 12 May 2026 14:50:53 +0000 Subject: [PATCH] Added space to allowedNameFormat Message-ID: <20260512145040.1671-1-konstantineb@pm.me> From: Konstantine Commit message: fix(windows): support adapter names containing spaces WireGuardNT permits NIC names with spaces (e.g., WireGuardCreateAdapter(L"Data Center", ...)), but the Windows implementation previously rejected them. This update removes that limitation and enables full compatibility. Signed-off-by: Konstantine --- conf/name.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/name.go b/conf/name.go index c34db900..3f5c680e 100644 --- a/conf/name.go +++ b/conf/name.go @@ -24,7 +24,7 @@ const ( specialChars = "/\\<>:\"|?*\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x00" ) -var allowedNameFormat = regexp.MustCompile("^[a-zA-Z0-9_=+.-]{1,32}$") +var allowedNameFormat = regexp.MustCompile("^[a-zA-Z0-9_=+. -]{1,32}$") func isReserved(name string) bool { if len(name) == 0 { -- 2.50.1.windows.1 From me at pavel.sh Wed May 13 16:32:35 2026 From: me at pavel.sh (me at pavel.sh) Date: Wed, 13 May 2026 19:32:35 +0300 Subject: [PATCH] feat: add Import from Clipboard and Paste/Type config options Message-ID: Changes: - AddTunnelsSheet: two new buttons + REQUEST_CLIPBOARD / REQUEST_TEXT - TunnelListFragment: handles both new request methods; showSnackbar ? promoted to internal so PasteConfigDialogFragment can call it - PasteConfigDialogFragment: new dialog fragment with auto-fill and ? inline validation - dialog_paste_config.xml: monospace multi-line TextInputEditText - add_tunnels_bottom_sheet.xml: two new Material buttons wired up - strings.xml: all new user-visible strings added --- ?.../android/fragment/AddTunnelsSheet.kt ? ? ? | ?18 ++++ ?.../fragment/PasteConfigDialogFragment.kt ? ? | 102 ++++++++++++++++++ ?.../android/fragment/TunnelListFragment.kt ? ?| ?25 ++++- ?.../res/layout/add_tunnels_bottom_sheet.xml ? | ?60 +++++++++-- ?.../main/res/layout/dialog_paste_config.xml ? | ?35 ++++++ ?ui/src/main/res/values/strings.xml ? ? ? ? ? ?| ? 8 ++ ?6 files changed, 241 insertions(+), 7 deletions(-) ?create mode 100644 ui/src/main/java/com/wireguard/android/fragment/PasteConfigDialogFragment.kt ?create mode 100644 ui/src/main/res/layout/dialog_paste_config.xml diff --git a/ui/src/main/java/com/wireguard/android/fragment/AddTunnelsSheet.kt b/ui/src/main/java/com/wireguard/android/fragment/AddTunnelsSheet.kt index 161709c3..c0e10afd 100644 --- a/ui/src/main/java/com/wireguard/android/fragment/AddTunnelsSheet.kt +++ b/ui/src/main/java/com/wireguard/android/fragment/AddTunnelsSheet.kt @@ -68,6 +68,14 @@ class AddTunnelsSheet : BottomSheetDialogFragment() { ? ? ? ? ? ? ? ? ? ? ?dismiss() ? ? ? ? ? ? ? ? ? ? ?onRequestScanQRCode() ? ? ? ? ? ? ? ? ?} + ? ? ? ? ? ? ? ?dialog.findViewById(R.id.create_from_clipboard)?.setOnClickListener { + ? ? ? ? ? ? ? ? ? ?dismiss() + ? ? ? ? ? ? ? ? ? ?onRequestImportFromClipboard() + ? ? ? ? ? ? ? ?} + ? ? ? ? ? ? ? ?dialog.findViewById(R.id.create_from_text)?.setOnClickListener { + ? ? ? ? ? ? ? ? ? ?dismiss() + ? ? ? ? ? ? ? ? ? ?onRequestImportFromText() + ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ?} ? ? ? ? ?}) ? ? ? ? ?val gradientDrawable = GradientDrawable().apply { @@ -93,11 +101,21 @@ class AddTunnelsSheet : BottomSheetDialogFragment() { ? ? ? ? ?setFragmentResult(REQUEST_KEY_NEW_TUNNEL, Bundle().apply { putString(REQUEST_METHOD, REQUEST_SCAN) }) ? ? ?} ? + ? ?private fun onRequestImportFromClipboard() { + ? ? ? ?setFragmentResult(REQUEST_KEY_NEW_TUNNEL, Bundle().apply { putString(REQUEST_METHOD, REQUEST_CLIPBOARD) }) + ? ?} + + ? ?private fun onRequestImportFromText() { + ? ? ? ?setFragmentResult(REQUEST_KEY_NEW_TUNNEL, Bundle().apply { putString(REQUEST_METHOD, REQUEST_TEXT) }) + ? ?} + ? ? ?companion object { ? ? ? ? ?const val REQUEST_KEY_NEW_TUNNEL = "request_new_tunnel" ? ? ? ? ?const val REQUEST_METHOD = "request_method" ? ? ? ? ?const val REQUEST_CREATE = "request_create" ? ? ? ? ?const val REQUEST_IMPORT = "request_import" ? ? ? ? ?const val REQUEST_SCAN = "request_scan" + ? ? ? ?const val REQUEST_CLIPBOARD = "request_clipboard" + ? ? ? ?const val REQUEST_TEXT = "request_text" ? ? ?} ?} diff --git a/ui/src/main/java/com/wireguard/android/fragment/PasteConfigDialogFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/PasteConfigDialogFragment.kt new file mode 100644 index 00000000..f6e86236 --- /dev/null +++ b/ui/src/main/java/com/wireguard/android/fragment/PasteConfigDialogFragment.kt @@ -0,0 +1,102 @@ +/* + * Copyright ? 2017-2025 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package com.wireguard.android.fragment + +import android.app.Dialog +import android.content.ClipboardManager +import android.content.Context +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.widget.Button +import androidx.appcompat.app.AlertDialog +import androidx.fragment.app.DialogFragment +import androidx.lifecycle.lifecycleScope +import com.google.android.material.textfield.TextInputEditText +import com.google.android.material.textfield.TextInputLayout +import com.wireguard.android.R +import com.wireguard.android.util.TunnelImporter +import kotlinx.coroutines.launch + +/** + * Dialog that lets the user paste or manually type a WireGuard config INI block. + * Fields ([Interface] / [Peer] sections) are auto-detected from the input text. + * On "Import", the config is validated and handed to [TunnelImporter]. + */ +class PasteConfigDialogFragment : DialogFragment() { + + ? ?override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + ? ? ? ?val inflater = LayoutInflater.from(requireContext()) + ? ? ? ?val view = inflater.inflate(R.layout.dialog_paste_config, null) + + ? ? ? ?val textInputLayout = view.findViewById(R.id.config_text_input_layout) + ? ? ? ?val editText = view.findViewById(R.id.config_edit_text) + + ? ? ? ?// Pre-fill from clipboard if it looks like a WireGuard config + ? ? ? ?val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + ? ? ? ?val clipText = clipboard.primaryClip?.getItemAt(0)?.coerceToText(requireContext())?.toString() + ? ? ? ?if (!clipText.isNullOrBlank() && looksLikeWireGuardConfig(clipText)) { + ? ? ? ? ? ?editText.setText(clipText) + ? ? ? ?} + + ? ? ? ?val dialog = AlertDialog.Builder(requireContext()) + ? ? ? ? ? ?.setTitle(R.string.paste_config_dialog_title) + ? ? ? ? ? ?.setView(view) + ? ? ? ? ? ?.setPositiveButton(R.string.paste_config_import, null) // set below to prevent auto-dismiss on error + ? ? ? ? ? ?.setNegativeButton(android.R.string.cancel, null) + ? ? ? ? ? ?.create() + + ? ? ? ?dialog.setOnShowListener { + ? ? ? ? ? ?val importButton: Button = dialog.getButton(AlertDialog.BUTTON_POSITIVE) + + ? ? ? ? ? ?// Validate on every keystroke ? highlight error inline + ? ? ? ? ? ?editText.addTextChangedListener(object : TextWatcher { + ? ? ? ? ? ? ? ?override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit + ? ? ? ? ? ? ? ?override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit + ? ? ? ? ? ? ? ?override fun afterTextChanged(s: Editable?) { + ? ? ? ? ? ? ? ? ? ?textInputLayout.error = null + ? ? ? ? ? ? ? ? ? ?importButton.isEnabled = !s.isNullOrBlank() + ? ? ? ? ? ? ? ?} + ? ? ? ? ? ?}) + ? ? ? ? ? ?importButton.isEnabled = !editText.text.isNullOrBlank() + + ? ? ? ? ? ?importButton.setOnClickListener { + ? ? ? ? ? ? ? ?val configText = editText.text?.toString().orEmpty().trim() + ? ? ? ? ? ? ? ?if (configText.isEmpty()) { + ? ? ? ? ? ? ? ? ? ?textInputLayout.error = getString(R.string.paste_config_empty_error) + ? ? ? ? ? ? ? ? ? ?return at setOnClickListener + ? ? ? ? ? ? ? ?} + ? ? ? ? ? ? ? ?lifecycleScope.launch { + ? ? ? ? ? ? ? ? ? ?TunnelImporter.importTunnel(parentFragmentManager, configText) { message -> + ? ? ? ? ? ? ? ? ? ? ? ?// Show result via the parent fragment's snackbar mechanism + ? ? ? ? ? ? ? ? ? ? ? ?(parentFragment as? TunnelListFragment)?.let { + ? ? ? ? ? ? ? ? ? ? ? ? ? ?it.showSnackbar(message) + ? ? ? ? ? ? ? ? ? ? ? ?} + ? ? ? ? ? ? ? ? ? ?} + ? ? ? ? ? ? ? ?} + ? ? ? ? ? ? ? ?dismiss() + ? ? ? ? ? ?} + ? ? ? ?} + + ? ? ? ?return dialog + ? ?} + + ? ?companion object { + ? ? ? ?/** + ? ? ? ? * Heuristic: a string contains at least one [Interface] or [Peer] section header + ? ? ? ? * and at least one key = value pair typical of WireGuard configs. + ? ? ? ? */ + ? ? ? ?fun looksLikeWireGuardConfig(text: String): Boolean { + ? ? ? ? ? ?val hasSection = text.contains("[Interface]", ignoreCase = true) || + ? ? ? ? ? ? ? ?text.contains("[Peer]", ignoreCase = true) + ? ? ? ? ? ?val hasKeyValue = text.contains("PrivateKey", ignoreCase = true) || + ? ? ? ? ? ? ? ?text.contains("PublicKey", ignoreCase = true) || + ? ? ? ? ? ? ? ?text.contains("Address", ignoreCase = true) || + ? ? ? ? ? ? ? ?text.contains("Endpoint", ignoreCase = true) + ? ? ? ? ? ?return hasSection && hasKeyValue + ? ? ? ?} + ? ?} +} diff --git a/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt index 119b6afe..6ade6279 100644 --- a/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt +++ b/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt @@ -4,6 +4,8 @@ ? */ ?package com.wireguard.android.fragment ? +import android.content.ClipboardManager +import android.content.Context ?import android.content.Intent ?import android.content.res.Resources ?import android.os.Bundle @@ -122,6 +124,15 @@ class TunnelListFragment : BaseFragment() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.setPrompt(getString(R.string.qr_code_hint)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?) ? ? ? ? ? ? ? ? ? ? ? ? ?} + + ? ? ? ? ? ? ? ? ? ? ? ?AddTunnelsSheet.REQUEST_CLIPBOARD -> { + ? ? ? ? ? ? ? ? ? ? ? ? ? ?onRequestImportFromClipboard() + ? ? ? ? ? ? ? ? ? ? ? ?} + + ? ? ? ? ? ? ? ? ? ? ? ?AddTunnelsSheet.REQUEST_TEXT -> { + ? ? ? ? ? ? ? ? ? ? ? ? ? ?PasteConfigDialogFragment() + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.show(childFragmentManager, "PASTE_CONFIG") + ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ?bottomSheet.showNow(childFragmentManager, "BOTTOM_SHEET") @@ -154,6 +165,18 @@ class TunnelListFragment : BaseFragment() { ? ? ? ? ?} ? ? ?} ? + ? ?private fun onRequestImportFromClipboard() { + ? ? ? ?val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + ? ? ? ?val text = clipboard.primaryClip?.getItemAt(0)?.coerceToText(requireContext())?.toString() + ? ? ? ?if (text.isNullOrBlank()) { + ? ? ? ? ? ?showSnackbar(getString(R.string.clipboard_empty_error)) + ? ? ? ? ? ?return + ? ? ? ?} + ? ? ? ?lifecycleScope.launch { + ? ? ? ? ? ?TunnelImporter.importTunnel(parentFragmentManager, text) { showSnackbar(it) } + ? ? ? ?} + ? ?} + ? ? ?private fun onTunnelDeletionFinished(count: Int, throwable: Throwable?) { ? ? ? ? ?val message: String ? ? ? ? ?val ctx = activity ?: Application.get() @@ -194,7 +217,7 @@ class TunnelListFragment : BaseFragment() { ? ? ? ? ?} ? ? ?} ? - ? ?private fun showSnackbar(message: CharSequence) { + ? ?internal fun showSnackbar(message: CharSequence) { ? ? ? ? ?val binding = binding ? ? ? ? ?if (binding != null) ? ? ? ? ? ? ?Snackbar.make(binding.mainContainer, message, Snackbar.LENGTH_LONG) diff --git a/ui/src/main/res/layout/add_tunnels_bottom_sheet.xml b/ui/src/main/res/layout/add_tunnels_bottom_sheet.xml index 0ad1ef23..c2224f83 100644 --- a/ui/src/main/res/layout/add_tunnels_bottom_sheet.xml +++ b/ui/src/main/res/layout/add_tunnels_bottom_sheet.xml @@ -42,22 +42,22 @@ ? ? ? ? ?android:layout_marginEnd="@dimen/normal_margin" ? ? ? ? ?android:layout_marginRight="@dimen/normal_margin" ? ? ? ? ?android:nextFocusUp="@id/create_from_file" - ? ? ? ?android:nextFocusDown="@id/create_empty" - ? ? ? ?android:nextFocusForward="@id/create_empty" + ? ? ? ?android:nextFocusDown="@id/create_from_clipboard" + ? ? ? ?android:nextFocusForward="@id/create_from_clipboard" ? ? ? ? ?android:text="@string/create_from_qr_code" ? ? ? ? ?android:textAlignment="viewStart" ? ? ? ? ?android:textColor="?attr/colorOnSurface" ? ? ? ? ?app:icon="@drawable/ic_action_scan_qr_code" ? ? ? ? ?app:iconPadding="@dimen/bottom_sheet_icon_padding" ? ? ? ? ?app:iconTint="?attr/colorSecondary" - ? ? ? ?app:layout_constraintBottom_toBottomOf="@+id/create_empty" + ? ? ? ?app:layout_constraintBottom_toTopOf="@+id/create_from_clipboard" ? ? ? ? ?app:layout_constraintEnd_toEndOf="parent" ? ? ? ? ?app:layout_constraintStart_toStartOf="parent" ? ? ? ? ?app:layout_constraintTop_toBottomOf="@+id/create_from_file" ? ? ? ? ?app:rippleColor="?attr/colorSecondary" /> ? ? ? ? + + ? ? + + ? ? ? ? diff --git a/ui/src/main/res/layout/dialog_paste_config.xml b/ui/src/main/res/layout/dialog_paste_config.xml new file mode 100644 index 00000000..75ae5133 --- /dev/null +++ b/ui/src/main/res/layout/dialog_paste_config.xml @@ -0,0 +1,35 @@ + + + + ? ? + + ? ? ? ? + + ? ? + + diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 32e797e6..6b07c79b 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -97,8 +97,16 @@ ? ? ?Cannot create local binary directory ? ? ?Cannot create file in downloads directory ? ? ?Create from scratch + ? ?Import from clipboard ? ? ?Import from file or archive ? ? ?Scan from QR code + ? ?Paste or type config + ? ?Import tunnel configuration + ? ?Paste or type your WireGuard config here? + ? ?Import + ? ?Configuration text cannot be empty + ? ?Clipboard does not contain any text + ? ?Tunnel imported from clipboard ? ? ?Cannot create output directory ? ? ?Cannot create local temporary directory ? ? ?Create Tunnel --? 2.43.0 From chleroy at kernel.org Tue May 19 14:54:31 2026 From: chleroy at kernel.org (Christophe Leroy (CS GROUP)) Date: Tue, 19 May 2026 16:54:31 +0200 Subject: crypto/ahash.c:1073:1: warning: the frame size of 1040 bytes is larger than 1024 bytes In-Reply-To: References: <202605100125.l4JVHppO-lkp@intel.com> Message-ID: Le 11/05/2026 ? 08:42, Geert Uytterhoeven a ?crit?: > On Sat, 9 May 2026 at 19:07, kernel test robot wrote: >> FYI, the error/warning still remains. >> >> tree: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.kernel.org%2Fpub%2Fscm%2Flinux%2Fkernel%2Fgit%2Ftorvalds%2Flinux.git&data=05%7C02%7Cchristophe.leroy2%40cs-soprasteria.com%7Cb57c2e1952ea48b306d508deaf28809f%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639140785686768547%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=MBIlFF0TKur9ZxxdvLflUjFXN8BiEIWx%2FW2eO2rQteM%3D&reserved=0 master >> head: ec89572766744e844df24c27d31c97b4c00f4e07 >> commit: 9d9b193ed73a65ec47cf1fd39925b09da8216461 crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390) >> date: 9 months ago >> config: mips-eyeq5_defconfig (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdownload.01.org%2F0day-ci%2Farchive%2F20260510%2F202605100125.l4JVHppO-lkp%40intel.com%2Fconfig&data=05%7C02%7Cchristophe.leroy2%40cs-soprasteria.com%7Cb57c2e1952ea48b306d508deaf28809f%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639140785686802803%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=9mLXlRz5JrVhRQ0Ft4c3tQJGrDtlSSmYmd7vZ4pneYc%3D&reserved=0) >> compiler: mips64-linux-gcc (GCC) 15.2.0 >> reproduce (this is a W=1 build): (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdownload.01.org%2F0day-ci%2Farchive%2F20260510%2F202605100125.l4JVHppO-lkp%40intel.com%2Freproduce&data=05%7C02%7Cchristophe.leroy2%40cs-soprasteria.com%7Cb57c2e1952ea48b306d508deaf28809f%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639140785686823501%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=NNAWk0DHq2gD1%2FToE%2FXk75Mz3sKpppwVkpkDG6amzD0%3D&reserved=0) >> >> If you fix the issue in a separate patch/commit (i.e. not just a new version of >> the same patch/commit), kindly add following tags >> | Fixes: 9d9b193ed73a ("crypto: hash - Increase HASH_MAX_DESCSIZE for hmac(sha3-224-s390)") >> | Reported-by: kernel test robot >> | Closes: https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore.kernel.org%2Foe-kbuild-all%2F202605100125.l4JVHppO-lkp%40intel.com%2F&data=05%7C02%7Cchristophe.leroy2%40cs-soprasteria.com%7Cb57c2e1952ea48b306d508deaf28809f%7C8b87af7d86474dc78df45f69a2011bb5%7C0%7C0%7C639140785686842796%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=2M0BnhyxISt3rrzxPXkX4p%2Ba1bIVz%2FhjwSNokIVueuE%3D&reserved=0 >> >> All warnings (new ones prefixed by >>): >> >> crypto/ahash.c: In function 'crypto_hash_digest': >>>> crypto/ahash.c:1073:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=] >> 1073 | } >> | ^ > > This is one of the few defconfigs that still use CONFIG_FRAME_WARN=1024. > The default value for 32-bit systems was lifted from 1024 to 1280 in > commit 32115734c0ed8b46 ("Increase the default 32-bit build frame size > warning limit to 1280 bytes") in v6.18, so perhaps the downgrade to > 1024 should be dropped from the following defconfigs: > > $ git grep CONFIG_FRAME_WARN=1024 > arch/mips/configs/eyeq5_defconfig:CONFIG_FRAME_WARN=1024 > arch/mips/configs/eyeq6_defconfig:CONFIG_FRAME_WARN=1024 > arch/mips/configs/eyeq6lplus_defconfig:CONFIG_FRAME_WARN=1024 > arch/mips/configs/lemote2f_defconfig:CONFIG_FRAME_WARN=1024 > arch/mips/configs/loongson2k_defconfig:CONFIG_FRAME_WARN=1024 > arch/powerpc/configs/fsl-emb-nonhw.config:CONFIG_FRAME_WARN=1024 I agree for that one, lets drop the downgrade, don't know why it was added at the first place as it was the default, most likely someone didn't use make savedefconfig So feel from to drop that in a treewide cleanup with my Acked-by: Christophe Leroy (CS GROUP) > tools/testing/selftests/wireguard/qemu/arch/arm.config:CONFIG_FRAME_WARN=1024 > tools/testing/selftests/wireguard/qemu/arch/armeb.config:CONFIG_FRAME_WARN=1024 > tools/testing/selftests/wireguard/qemu/arch/i686.config:CONFIG_FRAME_WARN=1024 > tools/testing/selftests/wireguard/qemu/arch/m68k.config:CONFIG_FRAME_WARN=1024 > tools/testing/selftests/wireguard/qemu/arch/mips.config:CONFIG_FRAME_WARN=1024 > tools/testing/selftests/wireguard/qemu/arch/mipsel.config:CONFIG_FRAME_WARN=1024 > tools/testing/selftests/wireguard/qemu/arch/powerpc.config:CONFIG_FRAME_WARN=1024 > > I am not sure about the wireguard selftests: they might use the lower > value deliberately for testing? > > Gr{oetje,eeting}s, > > Geert > From doug.hs at proton.me Wed May 20 20:27:26 2026 From: doug.hs at proton.me (Douglas Silva) Date: Wed, 20 May 2026 20:27:26 +0000 Subject: Add instructions to verify android APK to wireguard.com Message-ID: The instructions were posted on the mailing list [1] in 2023, but it's still not available on the site. Assuming they're still relevant, I think it's a good idea to put them on the installation page [2]. Even a link to that mailing list message would help. [1] https://lists.zx2c4.com/pipermail/wireguard/2023-May/008057.html [2] https://www.wireguard.com/install/#android-play-store-direct-apk-file From peter at lekensteyn.nl Sun May 31 22:55:19 2026 From: peter at lekensteyn.nl (Peter Wu) Date: Mon, 1 Jun 2026 00:55:19 +0200 Subject: [PATCH 0/2] extract-handshakes: add BTF approach and fix compatibility Message-ID: <20260531225521.576473-1-peter@lekensteyn.nl> While trying to decrypt WireGuard traffic in Wireshark, I noticed the extract-handshakes utility broke since upstreaming in Linux v5.6 (2019). Attached is a patch to fix the main issue, and another one to remove a dependency on the WireGuard kernel module sources by relying on BTF. Tested on Arch Linux (7.0.10-arch1-1) and Ubuntu 24.04 (6.8.0-41-generic), both have BTF support. Peter Wu (2): extract-handshakes: fix compatibility with upstream WireGuard module extract-handshakes: add a more user-friendly BTF approach contrib/extract-handshakes/README | 7 +- .../extract-handshakes/extract-handshakes.sh | 25 ++++--- contrib/extract-handshakes/make-offsets.sh | 70 +++++++++++++++++++ 3 files changed, 93 insertions(+), 9 deletions(-) create mode 100755 contrib/extract-handshakes/make-offsets.sh -- 2.54.0 From peter at lekensteyn.nl Sun May 31 22:55:21 2026 From: peter at lekensteyn.nl (Peter Wu) Date: Mon, 1 Jun 2026 00:55:21 +0200 Subject: [PATCH 2/2] extract-handshakes: add a more user-friendly BTF approach In-Reply-To: <20260531225521.576473-1-peter@lekensteyn.nl> References: <20260531225521.576473-1-peter@lekensteyn.nl> Message-ID: <20260531225521.576473-3-peter@lekensteyn.nl> The previous implementation requires a copy of WireGuard kernel module module sources matching the current kernel and a writeable directory. Add an alternative implementation that reads the module offsets at runtime using BTF (BPF Type Format). The previous module-based implementation is maintained in case BTF is unavailable, like hardened systems with structure layout randomization. A fprobetrace-based approach was also considered as that would avoid the need to manually extract BTF offsets. It is currently not feasible however since the wg_index_hashtable_insert entry parameter cannot be typecast to the larger structure it was embedded in. Signed-off-by: Peter Wu --- contrib/extract-handshakes/README | 7 +- .../extract-handshakes/extract-handshakes.sh | 8 ++- contrib/extract-handshakes/make-offsets.sh | 70 +++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100755 contrib/extract-handshakes/make-offsets.sh diff --git a/contrib/extract-handshakes/README b/contrib/extract-handshakes/README index 1d030fa..568d142 100644 --- a/contrib/extract-handshakes/README +++ b/contrib/extract-handshakes/README @@ -6,7 +6,12 @@ to them being sent, via kprobes. It exports the bare minimum to be able to then decrypt all packets in the handshake and in the subsequent transport data session. -Build: +These probes depend on knowledge of kernel structure offsets. Ideally +from BTF (BPF Type Format), available with CONFIG_DEBUG_INFO_BTF=y +and Linux 5.2+. On systems where this is not available, an alternative +approach is possible when WireGuard module sources are available. + +Build (only if BTF is unavailable): $ make diff --git a/contrib/extract-handshakes/extract-handshakes.sh b/contrib/extract-handshakes/extract-handshakes.sh index 57d397e..284749f 100755 --- a/contrib/extract-handshakes/extract-handshakes.sh +++ b/contrib/extract-handshakes/extract-handshakes.sh @@ -2,13 +2,17 @@ # SPDX-License-Identifier: GPL-2.0 # # Copyright (C) 2015-2026 Jason A. Donenfeld . All Rights Reserved. -# Copyright (C) 2017-2018 Peter Wu . All Rights Reserved. +# Copyright (C) 2017-2026 Peter Wu . All Rights Reserved. set -e ME_DIR="${BASH_SOURCE[0]}" ME_DIR="${ME_DIR%/*}" -source "$ME_DIR/offsets.include" || { echo "Did you forget to run make?" >&2; exit 1; } +if [ -e "$ME_DIR/offsets.include" ]; then + source "$ME_DIR/offsets.include" +else + source "$ME_DIR/make-offsets.sh" +fi case "$(uname -m)" in x86_64) ARGUMENT_REGISTER="%si" ;; diff --git a/contrib/extract-handshakes/make-offsets.sh b/contrib/extract-handshakes/make-offsets.sh new file mode 100755 index 0000000..ed7e6b4 --- /dev/null +++ b/contrib/extract-handshakes/make-offsets.sh @@ -0,0 +1,70 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2026 Peter Wu . All Rights Reserved. + +set -eu -o pipefail + +if ! [ -e /sys/kernel/btf/vmlinux ]; then + echo "kernel BTF is missing, requires Linux v5.2+ with CONFIG_DEBUG_INFO_BTF=y" >&2 + exit 1 +fi + +if ! [ -e /sys/kernel/btf/wireguard ]; then + echo "BTF not available for wireguard, ensure kernel module is loaded." >&2 + exit 1 +fi + +for tool in bpftool jq; do + if ! type "$tool" &>/dev/null; then + echo "Extracting offsets using BTF requires tool: $tool" >&2 + exit 1 + fi +done + +declare -A struct_offsets +while read -r struct field offset; do + struct_offsets["$struct.$field"]="$offset" +done < <( + bpftool -j btf dump file /sys/kernel/btf/wireguard | + jq -cr '.types[]|select(.kind=="STRUCT" and + (.name=="noise_handshake" or .name=="noise_static_identity") + ) as $t|.members[]|[$t.name, .name, .bits_offset/8]|@tsv' +) + +struct_offset() { + local struct="$1" field="$2" offset + offset="${struct_offsets[$struct.$field]:-}" + if [ -z "$offset" ]; then + echo "Failed to find offset for struct $struct $field" >&2 + exit 1 + fi + echo "$offset" +} + +declare -A OFFSETS +OFFSETS[LOCAL_STATIC_PRIVATE_KEY]=$(struct_offset noise_static_identity static_private),$(struct_offset noise_handshake static_identity) +OFFSETS[LOCAL_EPHEMERAL_PRIVATE_KEY]=$(struct_offset noise_handshake ephemeral_private) +OFFSETS[REMOTE_STATIC_PUBLIC_KEY]=$(struct_offset noise_handshake remote_static) +OFFSETS[PRESHARED_KEY]=$(struct_offset noise_handshake preshared_key) + +if [ -e /sys/kernel/cpu_byteorder ]; then + # Since Linux 6.2 (February 2023) + read -r ENDIAN < /sys/kernel/cpu_byteorder +else + [[ "$(lscpu)" == *Byte\ Order:*Big* ]] && ENDIAN=big || ENDIAN=little +fi + +# Pretty-print values if not sourced. +if ! (return 0 2>/dev/null); then + # Pretty-print version of 'declare -p OFFSETS' + cat < References: <20260531225521.576473-1-peter@lekensteyn.nl> Message-ID: <20260531225521.576473-2-peter@lekensteyn.nl> Fix probe target, it got prefixed with wg_ in WireGuard 0.0.20181006 to prepare for upstream Linux inclusion. Fix the trace directory, since Linux v6.17 the old location has been disabled by default. Signed-off-by: Peter Wu --- .../extract-handshakes/extract-handshakes.sh | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/contrib/extract-handshakes/extract-handshakes.sh b/contrib/extract-handshakes/extract-handshakes.sh index 135a0d3..57d397e 100755 --- a/contrib/extract-handshakes/extract-handshakes.sh +++ b/contrib/extract-handshakes/extract-handshakes.sh @@ -34,17 +34,22 @@ for key in "${!OFFSETS[@]}"; do done done +# Use the new tracefs dir, since Linux v4.1. The old debugfs tracing directory +# is gone since Linux v6.17 without CONFIG_TRACEFS_AUTOMOUNT_DEPRECATED=y. +tracefs=/sys/kernel/tracing +[ -e "$tracefs" ] || tracefs=/sys/kernel/debug/tracing + turn_off() { set +e - [[ -f /sys/kernel/debug/tracing/events/wireguard/idxadd/enable ]] || exit - echo 0 > /sys/kernel/debug/tracing/events/wireguard/idxadd/enable - echo "-:wireguard/idxadd" >> /sys/kernel/debug/tracing/kprobe_events + [[ -f "$tracefs/events/wireguard/idxadd/enable" ]] || exit + echo 0 > "$tracefs/events/wireguard/idxadd/enable" + echo "-:wireguard/idxadd" >> "$tracefs/kprobe_events" exit } trap turn_off INT TERM EXIT -echo "p:wireguard/idxadd index_hashtable_insert ${ARGS[*]}" >> /sys/kernel/debug/tracing/kprobe_events -echo 1 > /sys/kernel/debug/tracing/events/wireguard/idxadd/enable +echo "p:wireguard/idxadd wg_index_hashtable_insert ${ARGS[*]}" >> "$tracefs/kprobe_events" +echo 1 > "$tracefs/events/wireguard/idxadd/enable" unpack_u64() { local i expanded="$1" @@ -77,4 +82,4 @@ while read -r line; do done echo " $key = $(printf "$bytes" | base64)" done -done < /sys/kernel/debug/tracing/trace_pipe +done < "$tracefs/trace_pipe" -- 2.54.0