Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_log: incorrect offset to network header

NFPROTO_ARP is expecting to find the ARP header at the network offset.

In the particular case of ARP, HTYPE= field shows the initial bytes of
the ethernet header destination MAC address.

netdev out: IN= OUT=bridge0 MACSRC=c2:76:e5:71:e1:de MACDST=36:b0:4a:e2:72:ea MACPROTO=0806 ARP HTYPE=14000 PTYPE=0x4ae2 OPCODE=49782

NFPROTO_NETDEV egress hook is also expecting to find the IP headers at
the network offset.

Fixes: 35b9395104d5 ("netfilter: add generic ARP packet logger")
Reported-by: Tom Yan <tom.ty89@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

+4 -4
+4 -4
net/netfilter/nf_log_syslog.c
··· 67 67 unsigned int logflags; 68 68 struct arphdr _arph; 69 69 70 - ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); 70 + ah = skb_header_pointer(skb, nhoff, sizeof(_arph), &_arph); 71 71 if (!ah) { 72 72 nf_log_buf_add(m, "TRUNCATED"); 73 73 return; ··· 96 96 ah->ar_pln != sizeof(__be32)) 97 97 return; 98 98 99 - ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp); 99 + ap = skb_header_pointer(skb, nhoff + sizeof(_arph), sizeof(_arpp), &_arpp); 100 100 if (!ap) { 101 101 nf_log_buf_add(m, " INCOMPLETE [%zu bytes]", 102 102 skb->len - sizeof(_arph)); ··· 149 149 150 150 nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo, 151 151 prefix); 152 - dump_arp_packet(m, loginfo, skb, 0); 152 + dump_arp_packet(m, loginfo, skb, skb_network_offset(skb)); 153 153 154 154 nf_log_buf_close(m); 155 155 } ··· 850 850 if (in) 851 851 dump_mac_header(m, loginfo, skb); 852 852 853 - dump_ipv4_packet(net, m, loginfo, skb, 0); 853 + dump_ipv4_packet(net, m, loginfo, skb, skb_network_offset(skb)); 854 854 855 855 nf_log_buf_close(m); 856 856 }