Hello Jason, > That looks to me like a security vulnerability. User namespace sets > listen-port to < 1024, and then moves it into the target namespace, > and bam, controls subverted. Luckily this is not the case. The kernel code called by Wireguard to create a socket already checks that the executing program has the correct capabilities in the transit namespace. In the case you described, the call will fail if the program does not have CAP_NET_BIND_SERVICE in the transit namespace. To be clear: Moving the socket involves creating a new one in the target namespace and closing the old one. V1 of this series did, however, have a security vulnerability. It did not check if the program could create a socket in the transit namespace. While creating a socket in your current network namespace requires no capabilities, creating a socket in another network namespace requires CAP_SYS_ADMIN in that namespace: * Linux provides no syscalls to create a socket in a network namespace except for your current namespace. * Therefore you first have to enter this namespace to create the socket. * Entering a network namespace requires CAP_SYS_ADMIN in that namespace. I've talked about this in more detail here: [1]. In V2 I have therefore added the following capability check: To change the listen-port or the transit-netns, the caller must have CAP_NET_ADMIN in the transit namespace. At the same time, I've introduced a way to skip this capability check: If the caller can prove that he could implement Wireguard in userspace in the desired transit namespace, then he is allowed to open the socket without CAP_NET_ADMIN. The caller proves this by passing UDP sockets from the transit namespace into the kernel. And indeed, if Wireguard refused her, then she could simply bind these sockets to the desired port and run a userspace implementation of Wireguard. Julian [1] https://lists.zx2c4.com/pipermail/wireguard/2018-September/003342.html PS: I've attached my key.