lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 1 Jan 2019 15:58:54 +0100
From:   Ralf Jung <post@...fj.de>
To:     netdev@...r.kernel.org
Cc:     David Ahern <dsahern@...il.com>,
        Ondrej Zajicek <santiago@...reenet.org>, jan.matejka@....cz
Subject: Cannot bind to IPv6 address in VRF

Hi all,

I am experiencing trouble with using Bird over IPv6 inside a VRF, and reduced
this down to a problem with IPv6 `bind`.

I have a VRF called "vrf_freifunk", with some GRE tunnel devices in it:

> 3: vrf_freifunk: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP group default qlen 1000
>     link/ether 6e:6d:9f:5d:f3:f2 brd ff:ff:ff:ff:ff:ff
> 12: tun-up-a_ak@...E: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1280 qdisc noqueue master vrf_freifunk state UNKNOWN group default qlen 1000
>     link/gre 82.165.162.239 peer 185.66.195.0
>     inet 100.64.3.21/31 scope global tun-up-a_ak
>        valid_lft forever preferred_lft forever
>     inet6 2a03:2260:0:194::2/64 scope global 
>        valid_lft forever preferred_lft forever
>     inet6 fe80::200:5efe:52a5:a2ef/64 scope link 
>        valid_lft forever preferred_lft forever

Now I am running the following python script to reproduce the problem:

> #!/usr/bin/python3                                                                                                                                                                                                 
> import socket
> 
> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
> s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b"vrf_freifunk")
> s.bind(("100.64.3.21", 188))
> 
> s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP)
> s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
> s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b"vrf_freifunk")
> s.bind(("2a03:2260:0:194::2", 188))

The IPv4 block completes successfully, but doing the same with IPv6 in the
second block fails saying:

> Traceback (most recent call last):
>   File "./test.py", line 11, in <module>
>     s.bind(("2a03:2260:0:194::2", 188))
> OSError: [Errno 99] Cannot assign requested address

If instead, in the last line, I use the IPv6 address of eth0 (which is not
inside this VRF), the `bind` call succeeds.  On the other hand, when I try using
the eth0 IPv4 address in the first block, `bind` fails as expected because the
address is not inside `vrf_freifunk`.
If I replace `vrf_freifunk` by `tun-up-a_ak` (which is more like what Bird
does), the behavior remains the same.

I think this is a kernel bug, it seems like setting `SO_BINDTODEVICE` on the
IPv6 socket is just ignored entirely.

This is using a Debian stable backports kernel:

> $ uname -a
> Linux gw1.saar.freifunk.net 4.18.0-0.bpo.3-amd64 #1 SMP Debian 4.18.20-2~bpo9+1 (2018-12-08) x86_64 GNU/Linux

Any help debugging this would be appreciated.
Kind regards,
Ralf

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ