bpf: Use cgroup_{common,current}_func_proto in more hooks
authorStanislav Fomichev <sdf@google.com>
Tue, 23 Aug 2022 22:25:52 +0000 (15:25 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 23 Aug 2022 23:08:21 +0000 (16:08 -0700)
The following hooks are per-cgroup hooks but they are not
using cgroup_{common,current}_func_proto, fix it:

* BPF_PROG_TYPE_CGROUP_SKB (cg_skb)
* BPF_PROG_TYPE_CGROUP_SOCK_ADDR (cg_sock_addr)
* BPF_PROG_TYPE_CGROUP_SOCK (cg_sock)
* BPF_PROG_TYPE_LSM+BPF_LSM_CGROUP

Also:

* move common func_proto's into cgroup func_proto handlers
* make sure bpf_{g,s}et_retval are not accessible from recvmsg,
  getpeername and getsockname (return/errno is ignored in these
  places)
* as a side effect, expose get_current_pid_tgid, get_current_comm_proto,
  get_current_ancestor_cgroup_id, get_cgroup_classid to more cgroup
  hooks

Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20220823222555.523590-3-sdf@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/linux/bpf.h
kernel/bpf/bpf_lsm.c
kernel/bpf/cgroup.c
net/core/filter.c

index 39bd363..99fc7a6 100644 (file)
@@ -2375,6 +2375,7 @@ extern const struct bpf_func_proto bpf_sock_map_update_proto;
 extern const struct bpf_func_proto bpf_sock_hash_update_proto;
 extern const struct bpf_func_proto bpf_get_current_cgroup_id_proto;
 extern const struct bpf_func_proto bpf_get_current_ancestor_cgroup_id_proto;
+extern const struct bpf_func_proto bpf_get_cgroup_classid_curr_proto;
 extern const struct bpf_func_proto bpf_msg_redirect_hash_proto;
 extern const struct bpf_func_proto bpf_msg_redirect_map_proto;
 extern const struct bpf_func_proto bpf_sk_redirect_hash_proto;
index fa71d58..5a97430 100644 (file)
@@ -189,6 +189,14 @@ static const struct bpf_func_proto bpf_get_attach_cookie_proto = {
 static const struct bpf_func_proto *
 bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       if (prog->expected_attach_type == BPF_LSM_CGROUP) {
+               func_proto = cgroup_common_func_proto(func_id, prog);
+               if (func_proto)
+                       return func_proto;
+       }
+
        switch (func_id) {
        case BPF_FUNC_inode_storage_get:
                return &bpf_inode_storage_get_proto;
@@ -212,15 +220,6 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return prog->aux->sleepable ? &bpf_ima_file_hash_proto : NULL;
        case BPF_FUNC_get_attach_cookie:
                return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto : NULL;
-       case BPF_FUNC_get_local_storage:
-               return prog->expected_attach_type == BPF_LSM_CGROUP ?
-                       &bpf_get_local_storage_proto : NULL;
-       case BPF_FUNC_set_retval:
-               return prog->expected_attach_type == BPF_LSM_CGROUP ?
-                       &bpf_set_retval_proto : NULL;
-       case BPF_FUNC_get_retval:
-               return prog->expected_attach_type == BPF_LSM_CGROUP ?
-                       &bpf_get_retval_proto : NULL;
 #ifdef CONFIG_NET
        case BPF_FUNC_setsockopt:
                if (prog->expected_attach_type != BPF_LSM_CGROUP)
index 189380e..0bf2d70 100644 (file)
@@ -2478,9 +2478,35 @@ cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
        case BPF_FUNC_get_local_storage:
                return &bpf_get_local_storage_proto;
        case BPF_FUNC_get_retval:
-               return &bpf_get_retval_proto;
+               switch (prog->expected_attach_type) {
+               case BPF_CGROUP_INET_INGRESS:
+               case BPF_CGROUP_INET_EGRESS:
+               case BPF_CGROUP_SOCK_OPS:
+               case BPF_CGROUP_UDP4_RECVMSG:
+               case BPF_CGROUP_UDP6_RECVMSG:
+               case BPF_CGROUP_INET4_GETPEERNAME:
+               case BPF_CGROUP_INET6_GETPEERNAME:
+               case BPF_CGROUP_INET4_GETSOCKNAME:
+               case BPF_CGROUP_INET6_GETSOCKNAME:
+                       return NULL;
+               default:
+                       return &bpf_get_retval_proto;
+               }
        case BPF_FUNC_set_retval:
-               return &bpf_set_retval_proto;
+               switch (prog->expected_attach_type) {
+               case BPF_CGROUP_INET_INGRESS:
+               case BPF_CGROUP_INET_EGRESS:
+               case BPF_CGROUP_SOCK_OPS:
+               case BPF_CGROUP_UDP4_RECVMSG:
+               case BPF_CGROUP_UDP6_RECVMSG:
+               case BPF_CGROUP_INET4_GETPEERNAME:
+               case BPF_CGROUP_INET6_GETPEERNAME:
+               case BPF_CGROUP_INET4_GETSOCKNAME:
+               case BPF_CGROUP_INET6_GETSOCKNAME:
+                       return NULL;
+               default:
+                       return &bpf_set_retval_proto;
+               }
        default:
                return NULL;
        }
@@ -2493,8 +2519,18 @@ cgroup_current_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
        switch (func_id) {
        case BPF_FUNC_get_current_uid_gid:
                return &bpf_get_current_uid_gid_proto;
+       case BPF_FUNC_get_current_pid_tgid:
+               return &bpf_get_current_pid_tgid_proto;
+       case BPF_FUNC_get_current_comm:
+               return &bpf_get_current_comm_proto;
        case BPF_FUNC_get_current_cgroup_id:
                return &bpf_get_current_cgroup_id_proto;
+       case BPF_FUNC_get_current_ancestor_cgroup_id:
+               return &bpf_get_current_ancestor_cgroup_id_proto;
+#ifdef CONFIG_CGROUP_NET_CLASSID
+       case BPF_FUNC_get_cgroup_classid:
+               return &bpf_get_cgroup_classid_curr_proto;
+#endif
        default:
                return NULL;
        }
index 1acfaff..63e25d8 100644 (file)
@@ -3009,7 +3009,7 @@ BPF_CALL_0(bpf_get_cgroup_classid_curr)
        return __task_get_classid(current);
 }
 
-static const struct bpf_func_proto bpf_get_cgroup_classid_curr_proto = {
+const struct bpf_func_proto bpf_get_cgroup_classid_curr_proto = {
        .func           = bpf_get_cgroup_classid_curr,
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
@@ -7581,34 +7581,23 @@ const struct bpf_func_proto bpf_sk_storage_get_cg_sock_proto __weak;
 static const struct bpf_func_proto *
 sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
+       func_proto = cgroup_current_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
-       /* inet and inet6 sockets are created in a process
-        * context so there is always a valid uid/gid
-        */
-       case BPF_FUNC_get_current_uid_gid:
-               return &bpf_get_current_uid_gid_proto;
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_get_socket_cookie:
                return &bpf_get_socket_cookie_sock_proto;
        case BPF_FUNC_get_netns_cookie:
                return &bpf_get_netns_cookie_sock_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
-       case BPF_FUNC_get_current_pid_tgid:
-               return &bpf_get_current_pid_tgid_proto;
-       case BPF_FUNC_get_current_comm:
-               return &bpf_get_current_comm_proto;
-#ifdef CONFIG_CGROUPS
-       case BPF_FUNC_get_current_cgroup_id:
-               return &bpf_get_current_cgroup_id_proto;
-       case BPF_FUNC_get_current_ancestor_cgroup_id:
-               return &bpf_get_current_ancestor_cgroup_id_proto;
-#endif
-#ifdef CONFIG_CGROUP_NET_CLASSID
-       case BPF_FUNC_get_cgroup_classid:
-               return &bpf_get_cgroup_classid_curr_proto;
-#endif
        case BPF_FUNC_sk_storage_get:
                return &bpf_sk_storage_get_cg_sock_proto;
        case BPF_FUNC_ktime_get_coarse_ns:
@@ -7621,12 +7610,17 @@ sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 static const struct bpf_func_proto *
 sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
+       func_proto = cgroup_current_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
-       /* inet and inet6 sockets are created in a process
-        * context so there is always a valid uid/gid
-        */
-       case BPF_FUNC_get_current_uid_gid:
-               return &bpf_get_current_uid_gid_proto;
        case BPF_FUNC_bind:
                switch (prog->expected_attach_type) {
                case BPF_CGROUP_INET4_CONNECT:
@@ -7639,24 +7633,8 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_get_socket_cookie_sock_addr_proto;
        case BPF_FUNC_get_netns_cookie:
                return &bpf_get_netns_cookie_sock_addr_proto;
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
-       case BPF_FUNC_get_current_pid_tgid:
-               return &bpf_get_current_pid_tgid_proto;
-       case BPF_FUNC_get_current_comm:
-               return &bpf_get_current_comm_proto;
-#ifdef CONFIG_CGROUPS
-       case BPF_FUNC_get_current_cgroup_id:
-               return &bpf_get_current_cgroup_id_proto;
-       case BPF_FUNC_get_current_ancestor_cgroup_id:
-               return &bpf_get_current_ancestor_cgroup_id_proto;
-#endif
-#ifdef CONFIG_CGROUP_NET_CLASSID
-       case BPF_FUNC_get_cgroup_classid:
-               return &bpf_get_cgroup_classid_curr_proto;
-#endif
 #ifdef CONFIG_INET
        case BPF_FUNC_sk_lookup_tcp:
                return &bpf_sock_addr_sk_lookup_tcp_proto;
@@ -7737,9 +7715,13 @@ const struct bpf_func_proto bpf_sk_storage_delete_proto __weak;
 static const struct bpf_func_proto *
 cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_sk_fullsock:
                return &bpf_sk_fullsock_proto;
        case BPF_FUNC_sk_storage_get:
@@ -7979,6 +7961,12 @@ const struct bpf_func_proto bpf_sock_hash_update_proto __weak;
 static const struct bpf_func_proto *
 sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
        case BPF_FUNC_setsockopt:
                return &bpf_sock_ops_setsockopt_proto;
@@ -7992,8 +7980,6 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_sock_hash_update_proto;
        case BPF_FUNC_get_socket_cookie:
                return &bpf_get_socket_cookie_sock_ops_proto;
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
        case BPF_FUNC_sk_storage_get: