TencentOS-kernel/net/ipv6
Yonghong Song a0302bc09c net: fix pos incrementment in ipv6_route_seq_next
[ Upstream commit 6617dfd440149e42ce4d2be615eb31a4755f4d30 ]

Commit 4fc427e05158 ("ipv6_route_seq_next should increase position index")
tried to fix the issue where seq_file pos is not increased
if a NULL element is returned with seq_ops->next(). See bug
  https://bugzilla.kernel.org/show_bug.cgi?id=206283
The commit effectively does:
  - increase pos for all seq_ops->start()
  - increase pos for all seq_ops->next()

For ipv6_route, increasing pos for all seq_ops->next() is correct.
But increasing pos for seq_ops->start() is not correct
since pos is used to determine how many items to skip during
seq_ops->start():
  iter->skip = *pos;
seq_ops->start() just fetches the *current* pos item.
The item can be skipped only after seq_ops->show() which essentially
is the beginning of seq_ops->next().

For example, I have 7 ipv6 route entries,
  root@arch-fb-vm1:~/net-next dd if=/proc/net/ipv6_route bs=4096
  00000000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000400 00000001 00000000 00000001     eth0
  fe800000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000001 00000000 00000001     eth0
  00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000000 00200200       lo
  00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000003 00000000 80200001       lo
  fe800000000000002050e3fffebd3be8 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000002 00000000 80200001     eth0
  ff000000000000000000000000000000 08 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000004 00000000 00000001     eth0
  00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000000 00200200       lo
  0+1 records in
  0+1 records out
  1050 bytes (1.0 kB, 1.0 KiB) copied, 0.00707908 s, 148 kB/s
  root@arch-fb-vm1:~/net-next

In the above, I specify buffer size 4096, so all records can be returned
to user space with a single trip to the kernel.

If I use buffer size 128, since each record size is 149, internally
kernel seq_read() will read 149 into its internal buffer and return the data
to user space in two read() syscalls. Then user read() syscall will trigger
next seq_ops->start(). Since the current implementation increased pos even
for seq_ops->start(), it will skip record #2, #4 and #6, assuming the first
record is #1.

  root@arch-fb-vm1:~/net-next dd if=/proc/net/ipv6_route bs=128
  00000000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000400 00000001 00000000 00000001     eth0
  00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000000 00200200       lo
  fe800000000000002050e3fffebd3be8 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000002 00000000 80200001     eth0
  00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000000 00200200       lo
4+1 records in
4+1 records out
600 bytes copied, 0.00127758 s, 470 kB/s

To fix the problem, create a fake pos pointer so seq_ops->start()
won't actually increase seq_file pos. With this fix, the
above `dd` command with `bs=128` will show correct result.

Fixes: 4fc427e05158 ("ipv6_route_seq_next should increase position index")
Cc: Alexei Starovoitov <ast@kernel.org>
Suggested-by: Vasily Averin <vvs@virtuozzo.com>
Reviewed-by: Vasily Averin <vvs@virtuozzo.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-03-16 16:38:13 +08:00
..
ila Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
netfilter Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
Kconfig net: ipv6: fix kconfig dependency warning for IPV6_SEG6_HMAC 2021-03-16 16:36:27 +08:00
Makefile Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
addrconf.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
addrconf_core.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
addrlabel.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
af_inet6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ah6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
anycast.c ipv6: fix memory leaks on IPV6_ADDRFORM path 2021-03-16 16:33:08 +08:00
calipso.c netlabel: cope with NULL catmap 2021-03-16 16:27:47 +08:00
datagram.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
esp6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
esp6_offload.c esp6: get the right proto for transport mode in esp6_gso_encap 2021-03-16 16:28:40 +08:00
exthdrs.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
exthdrs_core.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
exthdrs_offload.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
fib6_notifier.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
fib6_rules.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
fou6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
icmp.c ip: Fix SO_MARK in RST, ACK and ICMP packets 2021-03-16 16:31:46 +08:00
inet6_connection_sock.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
inet6_hashtables.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_checksum.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_fib.c net: fix pos incrementment in ipv6_route_seq_next 2021-03-16 16:38:13 +08:00
ip6_flowlabel.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_gre.c ip6_gre: fix null-ptr-deref in ip6gre_init_net() 2021-03-16 16:32:41 +08:00
ip6_icmp.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_input.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_offload.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_offload.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_output.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_tunnel.c gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY 2021-03-16 16:34:43 +08:00
ip6_udp_tunnel.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6_vti.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ip6mr.c net: don't return invalid table id error when we fall back to PF_UNSPEC 2021-03-16 16:28:22 +08:00
ipcomp6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ipv6_sockglue.c ipv6: fix memory leaks on IPV6_ADDRFORM path 2021-03-16 16:33:08 +08:00
mcast.c mld: fix memory leak in ipv6_mc_destroy_dev() 2021-03-16 16:30:45 +08:00
mcast_snoop.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
mip6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ndisc.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
netfilter.c netfilter: avoid ipv6 -> nf_defrag_ipv6 module dependency 2021-03-16 16:35:05 +08:00
output_core.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
ping.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
proc.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
protocol.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
raw.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
reassembly.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
route.c ipv6: Fix nexthop refcnt leak when creating ipv6 route info 2021-03-16 16:33:08 +08:00
seg6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
seg6_hmac.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
seg6_iptunnel.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
seg6_local.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sit.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
syncookies.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
sysctl_net_ipv6.c ipv6: Fix sysctl max for fib_multipath_hash_policy 2021-03-16 16:35:46 +08:00
tcp_ipv6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
tcpv6_offload.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
tunnel6.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
udp.c udp: Improve load balancing for SO_REUSEPORT. 2021-03-16 16:32:43 +08:00
udp_impl.h Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
udp_offload.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
udplite.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
xfrm6_input.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
xfrm6_output.c xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish 2021-03-16 16:26:53 +08:00
xfrm6_policy.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
xfrm6_protocol.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
xfrm6_state.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00
xfrm6_tunnel.c Init Repo base on linux 5.4.32 long term, and add base tlinux kernel interfaces. 2021-03-16 11:01:34 +08:00