Allow passing a pointer to a BTF struct sock_common* when updating a sockmap or sockhash. Since BTF pointers can fault and therefore be NULL at runtime we need to add an additional !sk check to sock_map_update_elem. Since we may be passed a request or timewait socket we also need to check sk_fullsock. Doing this allows calling map_update_elem on sockmap from bpf_iter context, which uses BTF pointers.
Unified · Split
| @@ -3943,7 +3943,7 @@ static int resolve_map_arg_type(struct bpf_verifier_env *env, · 3942 unmodified lines | ||
| 3943 | 3943 | case BPF_MAP_TYPE_SOCKMAP: |
| 3944 | 3944 | case BPF_MAP_TYPE_SOCKHASH: |
| 3945 | 3945 | if (*arg_type == ARG_PTR_TO_MAP_VALUE) { |
| 3946 | − *arg_type = ARG_PTR_TO_SOCKET; | |
| 3946 | + *arg_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON; | |
| 3947 | 3947 | } else { |
| 3948 | 3948 | verbose(env, "invalid arg_type for sockmap/sockhash\n"); |
| 3949 | 3949 | return -EINVAL; |
| @@ -610,6 +610,9 @@ static int sock_map_update_elem(struct bpf_map *map, void *key, · 609 unmodified lines | ||
| 610 | 610 | struct sock *sk = (struct sock *)value; |
| 611 | 611 | int ret; |
| 612 | 612 | |
| 613 | + if (unlikely(!sk || !sk_fullsock(sk))) | |
| 614 | + return -EINVAL; | |
| 615 | + | |
| 613 | 616 | if (!sock_map_sk_is_suitable(sk)) |
| 614 | 617 | return -EOPNOTSUPP; |
| 615 | 618 | |