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

bpf: Enable bpf_{g,s}etsockopt in BPF_CGROUP_INET{4,6}_GET{PEER,SOCK}NAME

Those hooks run as BPF_CGROUP_RUN_SA_PROG_LOCK and operate on
a locked socket.

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20210127232853.3753823-3-sdf@google.com

authored by

Stanislav Fomichev and committed by
Daniel Borkmann
073f4ec1 62476cc1

+24
+8
net/core/filter.c
··· 7025 7025 case BPF_CGROUP_INET6_CONNECT: 7026 7026 case BPF_CGROUP_UDP4_SENDMSG: 7027 7027 case BPF_CGROUP_UDP6_SENDMSG: 7028 + case BPF_CGROUP_INET4_GETPEERNAME: 7029 + case BPF_CGROUP_INET6_GETPEERNAME: 7030 + case BPF_CGROUP_INET4_GETSOCKNAME: 7031 + case BPF_CGROUP_INET6_GETSOCKNAME: 7028 7032 return &bpf_sock_addr_setsockopt_proto; 7029 7033 default: 7030 7034 return NULL; ··· 7041 7037 case BPF_CGROUP_INET6_CONNECT: 7042 7038 case BPF_CGROUP_UDP4_SENDMSG: 7043 7039 case BPF_CGROUP_UDP6_SENDMSG: 7040 + case BPF_CGROUP_INET4_GETPEERNAME: 7041 + case BPF_CGROUP_INET6_GETPEERNAME: 7042 + case BPF_CGROUP_INET4_GETSOCKNAME: 7043 + case BPF_CGROUP_INET6_GETSOCKNAME: 7044 7044 return &bpf_sock_addr_getsockopt_proto; 7045 7045 default: 7046 7046 return NULL;
+8
tools/testing/selftests/bpf/progs/connect_force_port4.c
··· 10 10 #include <bpf/bpf_helpers.h> 11 11 #include <bpf/bpf_endian.h> 12 12 13 + #include <bpf_sockopt_helpers.h> 14 + 13 15 char _license[] SEC("license") = "GPL"; 14 16 int _version SEC("version") = 1; 15 17 ··· 60 58 SEC("cgroup/getsockname4") 61 59 int getsockname4(struct bpf_sock_addr *ctx) 62 60 { 61 + if (!get_set_sk_priority(ctx)) 62 + return 1; 63 + 63 64 /* Expose local server as 1.2.3.4:60000 to client. */ 64 65 if (ctx->user_port == bpf_htons(60123)) { 65 66 ctx->user_ip4 = bpf_htonl(0x01020304); ··· 75 70 int getpeername4(struct bpf_sock_addr *ctx) 76 71 { 77 72 struct svc_addr *orig; 73 + 74 + if (!get_set_sk_priority(ctx)) 75 + return 1; 78 76 79 77 /* Expose service 1.2.3.4:60000 as peer instead of backend. */ 80 78 if (ctx->user_port == bpf_htons(60123)) {
+8
tools/testing/selftests/bpf/progs/connect_force_port6.c
··· 9 9 #include <bpf/bpf_helpers.h> 10 10 #include <bpf/bpf_endian.h> 11 11 12 + #include <bpf_sockopt_helpers.h> 13 + 12 14 char _license[] SEC("license") = "GPL"; 13 15 int _version SEC("version") = 1; 14 16 ··· 65 63 SEC("cgroup/getsockname6") 66 64 int getsockname6(struct bpf_sock_addr *ctx) 67 65 { 66 + if (!get_set_sk_priority(ctx)) 67 + return 1; 68 + 68 69 /* Expose local server as [fc00::1]:60000 to client. */ 69 70 if (ctx->user_port == bpf_htons(60124)) { 70 71 ctx->user_ip6[0] = bpf_htonl(0xfc000000); ··· 83 78 int getpeername6(struct bpf_sock_addr *ctx) 84 79 { 85 80 struct svc_addr *orig; 81 + 82 + if (!get_set_sk_priority(ctx)) 83 + return 1; 86 84 87 85 /* Expose service [fc00::1]:60000 as peer instead of backend. */ 88 86 if (ctx->user_port == bpf_htons(60124)) {