linux/net
Willem de Bruijn d4bac0288a bpf: support SKF_NET_OFF and SKF_LL_OFF on skb frags
Classic BPF socket filters with SKB_NET_OFF and SKB_LL_OFF fail to
read when these offsets extend into frags.

This has been observed with iwlwifi and reproduced with tun with
IFF_NAPI_FRAGS. The below straightforward socket filter on UDP port,
applied to a RAW socket, will silently miss matching packets.

    const int offset_proto = offsetof(struct ip6_hdr, ip6_nxt);
    const int offset_dport = sizeof(struct ip6_hdr) + offsetof(struct udphdr, dest);
    struct sock_filter filter_code[] = {
            BPF_STMT(BPF_LD  + BPF_B   + BPF_ABS, SKF_AD_OFF + SKF_AD_PKTTYPE),
            BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, PACKET_HOST, 0, 4),
            BPF_STMT(BPF_LD  + BPF_B   + BPF_ABS, SKF_NET_OFF + offset_proto),
            BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 2),
            BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, SKF_NET_OFF + offset_dport),

This is unexpected behavior. Socket filter programs should be
consistent regardless of environment. Silent misses are
particularly concerning as hard to detect.

Use skb_copy_bits for offsets outside linear, same as done for
non-SKF_(LL|NET) offsets.

Offset is always positive after subtracting the reference threshold
SKB_(LL|NET)_OFF, so is always >= skb_(mac|network)_offset. The sum of
the two is an offset against skb->data, and may be negative, but it
cannot point before skb->head, as skb_(mac|network)_offset would too.

This appears to go back to when frag support was introduced to
sk_run_filter in linux-2.4.4, before the introduction of git.

The amount of code change and 8/16/32 bit duplication are unfortunate.
But any attempt I made to be smarter saved very few LoC while
complicating the code.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Link: https://lore.kernel.org/netdev/20250122200402.3461154-1-maze@google.com/
Link: https://elixir.bootlin.com/linux/2.4.4/source/net/core/filter.c#L244
Reported-by: Matt Moeller <moeller.matt@gmail.com>
Co-developed-by: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Willem de Bruijn <willemb@google.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://lore.kernel.org/r/20250408132833.195491-2-willemdebruijn.kernel@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2025-04-09 20:02:51 -07:00
..
6lowpan
9p 9p: Use hashtable.h for hash_errmap 2025-03-23 06:20:48 +09:00
802
8021q net: vlan: don't propagate flags on open 2025-03-20 09:57:37 +01:00
appletalk
atm atm: Fix NULL pointer dereference 2025-03-25 13:54:36 -07:00
ax25 ax25: Remove broken autobind 2025-03-24 10:26:53 +00:00
batman-adv Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-03-20 21:38:01 +01:00
bluetooth Bluetooth: MGMT: Add LL Privacy Setting 2025-03-25 15:22:49 -04:00
bpf
bridge Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-03-26 09:32:10 -07:00
caif rtnetlink: Pack newlink() params into struct 2025-02-21 15:28:02 -08:00
can Networking changes for 6.15. 2025-03-26 21:48:21 -07:00
ceph
core bpf: support SKF_NET_OFF and SKF_LL_OFF on skb frags 2025-04-09 20:02:51 -07:00
dcb
dccp tcp/dccp: remove icsk->icsk_ack.timeout 2025-03-25 10:34:33 -07:00
devlink devlink: fix xa_alloc_cyclic() error handling 2025-03-19 09:57:36 +00:00
dns_resolver
dsa net: move misc netdev_lock flavors to a separate header 2025-03-08 09:06:50 -08:00
ethernet
ethtool net-timestamp: COMPLETION timestamp on packet tx completion 2025-03-25 12:48:05 -04:00
handshake
hsr net: hsr: Add KUnit test for PRP 2025-03-13 10:04:22 +01:00
ieee802154 inet: frags: save a pair of atomic operations in reassembly 2025-03-18 13:18:36 +01:00
ife
ipv4 net: fix geneve_opt length integer overflow 2025-04-03 15:47:35 -07:00
ipv6 ipv6: Do not consider link down nexthops in path selection 2025-04-04 07:30:07 -07:00
iucv s390: Convert MACHINE_IS_[LPAR|VM|KVM], etc, machine_is_[lpar|vm|kvm]() 2025-03-04 17:18:07 +01:00
kcm
key
l2tp net: move misc netdev_lock flavors to a separate header 2025-03-08 09:06:50 -08:00
l3mdev
lapb
llc llc: do not use skb_get() before dev_queue_xmit() 2025-03-03 14:00:04 +00:00
mac80211 More features for 6.15, major changes: 2025-03-25 08:04:13 -07:00
mac802154
mctp net: mctp: unshare packets when reassembling 2025-03-11 13:12:19 +01:00
mpls percpu: use TYPEOF_UNQUAL() in variable declarations 2025-03-16 22:05:53 -07:00
mptcp mptcp: fix NULL pointer in can_accept_new_subflow 2025-03-31 16:52:39 -07:00
ncsi
netfilter netfilter pull request 25-04-03 2025-04-03 16:23:01 -07:00
netlabel
netlink Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-02-27 10:20:58 -08:00
netrom
nfc
nsh
openvswitch tunnels: Accept PACKET_HOST in skb_tunnel_check_pmtu(). 2025-04-02 17:22:39 -07:00
packet
phonet
psample
qrtr
rds Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-02-27 10:20:58 -08:00
rfkill
rose
rxrpc afs: Use the per-peer app data provided by rxrpc 2025-03-10 09:47:15 +00:00
sched net: fix geneve_opt length integer overflow 2025-04-03 15:47:35 -07:00
sctp sctp: add mutual exclusion in proc_sctp_do_udp_port() 2025-04-02 16:04:19 -07:00
shaper
smc net/smc: use the correct ndev to find pnetid by pnetid table 2025-03-14 12:54:40 +00:00
strparser
sunrpc NFS client updates for Linux 6.15 2025-04-02 17:06:31 -07:00
switchdev net: switchdev: Convert blocking notification chain to a raw one 2025-03-11 11:30:28 +01:00
tipc tipc: Reduce scope for the variable “fdefq” in tipc_link_tnl_prepare() 2025-03-04 17:19:49 -08:00
tls This update includes the following changes: 2025-03-29 10:01:55 -07:00
unix unix: fix up for "apparmor: add fine grained af_unix mediation" 2025-03-26 09:31:18 -07:00
vmw_vsock vsock: avoid timeout during connect() if the socket is closing 2025-04-02 17:19:30 -07:00
wireless wifi: nl80211: re-enable multi-link reconfiguration 2025-03-18 14:52:11 +01:00
x25
xdp xsk: Fix __xsk_generic_xmit() error code when cq is full 2025-04-02 21:55:43 -07:00
xfrm This update includes the following changes: 2025-03-29 10:01:55 -07:00
compat.c
devres.c
Kconfig
Kconfig.debug
Makefile
socket.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-03-26 09:32:10 -07:00
sysctl_net.c