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: <CAJGXZLgcH6bjmj7YR-hAWpEQW1CPjEcOdMN01hqsVk18E4ScZQ@mail.gmail.com>
Date:   Tue, 11 Apr 2023 17:47:34 +0300
From:   Aleksey Shumnik <ashumnik9@...il.com>
To:     "netdev@...r.kernel.org" <netdev@...r.kernel.org>
Cc:     Jakub Kicinski <kuba@...nel.org>, waltje@...lt.nl.mugnet.org,
        gw4pts@...pts.ampr.org, xeb@...l.ru, kuznet@....inr.ac.ru,
        rzsfl@...uni-sb.de
Subject: [BUG] In af_packet.c::dev_parse_header() skb.network_header does not
 point to the network header

Dear maintainers,

I wrote the ip6gre_header_parser() function in ip6_gre.c, the
implementation is similar to ipgre_header_parser() in ip_gre.c. (By
the way, it is strange that this function is not implemented in
ip6_gre.c)
The implementation of the function is presented below.
It should parse the ip6 header and take the source address and its
length from there. To get a pointer to the ip header, it is logical to
use skb_network_header(), but it does not work correctly and returns a
pointer to payload (skb.data).
Also in ip_gre.c::ipgre_header_parser() skb_mac_header() returns a
pointer to the ip header and everything works correctly (although it
seems that this is also an error, because the pointer to the mac
header should have been returned, and logically the
skb_network_header() function should be applied), but in ip6_gre.c all
skb_mac_header(), skb_network_header(), skb_tranport_header() returns
a pointer to payload (skb.data).
This function is called when receiving a packet and parsing it in
af_packet.c::packet_rcv() in dev_parse_header().
The problem is that there is no way to accurately determine the
beginning of the ip header.

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 90565b8..0d0c37b 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1404,8 +1404,16 @@ static int ip6gre_header(struct sk_buff *skb,
struct net_device *dev,
  return -t->hlen;
 }

+static int ip6gre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+{
+ const struct ipv6hdr *ipv6h = (const struct ipv6hdr *) skb_mac_header(skb);
+ memcpy(haddr, &ipv6h->saddr, 16);
+ return 16;
+}
+
 static const struct header_ops ip6gre_header_ops = {
  .create = ip6gre_header,
+ .parse = ip6gre_header_parse,
 };

 static const struct net_device_ops ip6gre_netdev_ops = {

Would you answer whether this behavior is an error and why the
behavior in ip_gre.c and ip6_gre.c differs?

Regards,
Aleksey

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ