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]
Message-ID: <3D696DFB-7D22-44A6-9869-D2EFDEBDDEEB@juniper.net>
Date:   Wed, 2 Dec 2020 11:31:42 +0000
From:   Preethi Ramachandra <preethir@...iper.net>
To:     "dsahern@...il.com" <dsahern@...il.com>,
        "netdev@...r.kernel.org" <netdev@...r.kernel.org>
CC:     Jimmy Jose <jimmyj@...iper.net>,
        Reji Thomas <rejithomas@...iper.net>,
        Yogesh Ankolekar <ayogesh@...iper.net>
Subject: Linux IPV6 TCP egress path device passed for LOCAL_OUT hook is
 incorrect

Hi David Ahren,

In TCP egress path for ipv6 the device passed to NF_INET_LOCAL_OUT hook should be skb_dst(skb)->dev instead of dst->dev.

https://elixir.bootlin.com/linux/latest/source/net/ipv6/ip6_output.c#L202
struct dst_entry *dst = skb_dst(skb); >>> This may return slave device.

In this code path the DST Dev and SKB DST Dev will be set to VRF master device.
ip6_xmit->l3mdev_ip6_out->vrf_l3_out->vrf_ip6_out (This will set SKB DST Dev to vrf0)

However, once the control passes back to ip6_xmit, https://elixir.bootlin.com/linux/latest/source/net/ipv6/ip6_output.c#L280
Slave device is passed to LOCAL_OUT nf_hook instead of skb_dst(skb)->dev.

return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
       net, (struct sock *)sk, skb, NULL, dst->dev, <<<< Should be skb_dst(skb)->dev
       dst_output);

This will cause a bug in firewall filters. nf_hook->ip6table_mangle_hook->ip6table_filter_hook (Device passed is slave device). If the firewall filter rule is configured with device as VRF it will fail to apply the filter. As per Linux documentation filters should work for VRF devices.

Firewall Rule:

ip6tables -A OUTPUT -o vrf0 -m comment --comment F-outer6_T-B-lo0_I-1001 -j outer6 (or -A OUTPUT -o vrf0 -m mark --mark 0x1000000 -m comment --comment F-outer6_T-B-lo0_I-1001 -j outer6 (Rule fails to apply for TCP packets)

Linux firewall doc:

https://www.kernel.org/doc/Documentation/networking/vrf.txt

[2] Iptables on ingress supports PREROUTING with skb->dev set to the real
    ingress device and both INPUT and PREROUTING rules with skb->dev set to
    the VRF device. For egress POSTROUTING and OUTPUT rules can be written
    using either the VRF device or real egress device.

Comparison on device passed to LOCALOUT hook for IPV4 TCP and IPV6 raw/udp scenarios.

TCP IPV4 egress : In __ip_local_out to NF_INET_LOCAL_OUT skb_dst(skb)->dev is passed.

https://elixir.bootlin.com/linux/latest/source/net/ipv4/ip_output.c#L115
return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
                      net, sk, skb, NULL, skb_dst(skb)->dev, << will be set to vrf0
                      dst_output);
}

Raw/UDP V6 egress path: skb_dst(skb)->dev is passed onto NF_INET_LOCAL_OUT

rawv6_sendmsg-> ip6_send_skb-> ip6_local_out-> __ip6_local_out (LOCAL_OUT hook, device passed is SKB DST which is VRF)->nf_hook-> ip6table_mangle_hook->ip6table_filter_hook

https://elixir.bootlin.com/linux/latest/source/net/ipv6/output_core.c#L167

return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
       net, sk, skb, NULL, skb_dst(skb)->dev,
       dst_output);

Thanks,
Preethi


Juniper Business Use Only

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ