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>] [day] [month] [year] [list]
Date:   Tue, 30 Aug 2022 18:20:48 +0300
From:   Aleksey Shumnik <ashumnik9@...il.com>
To:     netdev@...r.kernel.org
Cc:     Jakub Kicinski <kuba@...nel.org>, xeb@...l.ru,
        kuznet@....inr.ac.ru, David Ahern <dsahern@...il.com>,
        Ido Schimmel <idosch@...sch.org>
Subject: [PATCH] net/ipv6/ip6_gre.c NBMA support

Dear Maintainers,

While I was studying the capabilities of the ip6_gre driver to support
NBMA networks, I found a bug:
When sending a packet over the NBMA network, the following sequence of
functions occurs:

ip6gre_tunnel_xmit() -> ip6_tnl_xmit_ctl() -> ip6_tnl_get_cap() ->
  ...
  if (ltype == IPV6_ADDR_ANY || rtype == IPV6_ADDR_ANY) {

      flags = IP6_TNL_F_CAP_PER_PACKET;
  ...

After that, the packages are dropped, but if skip ip6_tnl_xmit_ctl()

ip6gre_tunnel_xmit() -> ip6gre_xmit_ipv4() / ip6gre_xmit_ipv6() /
ip6gre_xmit_other() -> __gre6_xmit() -> ip6_tnl_xmit() ->
  ...
  /* NBMA tunnel */

  if (ipv6_addr_any(&t->parms.raddr)) {
  ...

It is strange that at first when checking addr_type == IPV6_ADDR_ANY
packages are dropped, but after that there is ipv6_addr_any(addr)
which leads to neigh_lookup() end etc.
It turns out that the same check leads to different actions. In
addition, due to the fact that the package is dropped, there is no
neighbor_lookup and the package will not be sent.
It looks like ip6_gre supports NBMA, but does not allow it to work,
because of this and other possible bugs.

This is most likely not the final patch, but for now I offer such a
patch to solve the problem.

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index a9051df..34c6c5b 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -896,8 +896,14 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
  if (!pskb_inet_may_pull(skb))
  goto tx_err;

- if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
- goto tx_err;
+ if (dev->header_ops) {
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *)skb->data;
+ if (!ip6_tnl_xmit_ctl(t, &ipv6h->saddr, &ipv6h->daddr))
+ goto tx_err;
+ } else {
+ if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
+ goto tx_err;
+ }

  switch (skb->protocol) {
  case htons(ETH_P_IP):

If the network is NBMA, then the remote address is not set in the
tunnel parameters, and then the packets will always drop on the
ip6_tnl_xmit_ctl() function, I propose a solution, if there is an ipv6
header in skb, then take the destination and source addresses from
skb, and not from the tunnel parameters.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ