bpf: Don't return EINVAL from {get,set}sockopt when optlen > PAGE_SIZE
authorStanislav Fomichev <sdf@google.com>
Wed, 17 Jun 2020 01:04:14 +0000 (18:04 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 17 Jun 2020 17:54:05 +0000 (10:54 -0700)
commitd8fe449a9c51a37d844ab607e14e2f5c657d3cf2
tree3eb04395d33c0251158c01b7b36e7e088658cfd2
parent99c51064fb06146b3d494b745c947e438a10aaa7
bpf: Don't return EINVAL from {get,set}sockopt when optlen > PAGE_SIZE

Attaching to these hooks can break iptables because its optval is
usually quite big, or at least bigger than the current PAGE_SIZE limit.
David also mentioned some SCTP options can be big (around 256k).

For such optvals we expose only the first PAGE_SIZE bytes to
the BPF program. BPF program has two options:
1. Set ctx->optlen to 0 to indicate that the BPF's optval
   should be ignored and the kernel should use original userspace
   value.
2. Set ctx->optlen to something that's smaller than the PAGE_SIZE.

v5:
* use ctx->optlen == 0 with trimmed buffer (Alexei Starovoitov)
* update the docs accordingly

v4:
* use temporary buffer to avoid optval == optval_end == NULL;
  this removes the corner case in the verifier that might assume
  non-zero PTR_TO_PACKET/PTR_TO_PACKET_END.

v3:
* don't increase the limit, bypass the argument

v2:
* proper comments formatting (Jakub Kicinski)

Fixes: 0d01da6afc54 ("bpf: implement getsockopt and setsockopt hooks")
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Cc: David Laight <David.Laight@ACULAB.COM>
Link: https://lore.kernel.org/bpf/20200617010416.93086-1-sdf@google.com
kernel/bpf/cgroup.c