Development discussion of WireGuard
 help / color / mirror / Atom feed
From: Julian Orth <ju.orth@gmail.com>
To: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: WireGuard mailing list <wireguard@lists.zx2c4.com>
Subject: Re: Setting the transit namespace at runtime
Date: Mon, 10 Sep 2018 09:16:11 +0200	[thread overview]
Message-ID: <ea71ea95-b0ab-2b88-72b5-90089e216c2a@gmail.com> (raw)
In-Reply-To: <CAHmME9qYX8AEtOWo-u2E90mnKy+HeT-cb8KH8b9q3GUsmjxzDg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1979 bytes --]

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.

[-- Attachment #2: id_wireguard.pub --]
[-- Type: application/vnd.ms-publisher, Size: 99 bytes --]

      reply	other threads:[~2018-09-10  7:15 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-03 16:16 Julian Orth
2018-09-06 20:42 ` Julian Orth
2018-09-07  1:29   ` Jason A. Donenfeld
2018-09-07  1:26 ` Jason A. Donenfeld
2018-09-07 19:06   ` Julian Orth
2018-09-09 22:27     ` Jason A. Donenfeld
2018-09-10  7:16       ` Julian Orth [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ea71ea95-b0ab-2b88-72b5-90089e216c2a@gmail.com \
    --to=ju.orth@gmail.com \
    --cc=Jason@zx2c4.com \
    --cc=wireguard@lists.zx2c4.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).