Re: [PATCH net 2/3] net: compound page support in skb_seq_read
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: 2021-01-08 23:32:18
On Fri, Jan 8, 2021 at 12:11 PM Willem de Bruijn [off-list ref] wrote:
From: Willem de Bruijn <willemb@google.com>
skb_seq_read iterates over an skb, returning pointer and length of
the next data range with each call.
It relies on kmap_atomic to access highmem pages when needed.
An skb frag may be backed by a compound page, but kmap_atomic maps
only a single page. There are not enough kmap slots to always map all
pages concurrently.
Instead, if kmap_atomic is needed, iterate over each page.
As this increases the number of calls, avoid this unless needed.
The necessary condition is captured in skb_frag_must_loop.
I tried to make the change as obvious as possible. It should be easy
to verify that nothing changes if skb_frag_must_loop returns false.
Tested:
On an x86 platform with
CONFIG_HIGHMEM=y
CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
Run
ip link set dev lo mtu 1500
iptables -A OUTPUT -m string --string 'badstring' -algo bm -j ACCEPT
dd if=/dev/urandom of=in bs=1M count=20
nc -l -p 8000 > /dev/null &
nc -w 1 -q 0 localhost 8000 < in
Signed-off-by: Willem de Bruijn <willemb@google.com>
I don't have a clear Fixes tag for this.
That was also true for commit c613c209c3f3 ("net: add
skb_frag_foreach_page and use with kmap_atomic"), which deals with the
same problem in a few other functions.
It goes back to when compound highmem pages may have appeared in the
skb frag. Possibly with vmsplice, around 2006. The skb_seq_read
interface itself was added in 2005.