| @@ -812,6 +812,7 @@ int bpf_convert_ctx_accesses(struct bpf_verifier_env *env) · 811 unmodified lines |
| 812 | | 812 | |
| 813 | for (i = 0; i < insn_cnt; i++, insn++) { | 813 | for (i = 0; i < insn_cnt; i++, insn++) { |
| 814 | bpf_convert_ctx_access_t convert_ctx_access; | 814 | bpf_convert_ctx_access_t convert_ctx_access; |
| | 815 | enum bpf_reg_type ptr_type; |
| 815 | u8 mode; | 816 | u8 mode; |
| 816 | | 817 | |
| 817 | if (env->insn_aux_data[i + delta].nospec) { | 818 | if (env->insn_aux_data[i + delta].nospec) { |
| @@ -904,7 +905,8 @@ int bpf_convert_ctx_accesses(struct bpf_verifier_env *env) · 86 unmodified lines |
| 904 | continue; | 905 | continue; |
| 905 | } | 906 | } |
| 906 | | 907 | |
| 907 | switch ((int)env->insn_aux_data[i + delta].ptr_type) { | 908 | ptr_type = env->insn_aux_data[i + delta].ptr_type; |
| | 909 | switch ((int)ptr_type) { |
| 908 | case PTR_TO_CTX: | 910 | case PTR_TO_CTX: |
| 909 | if (!ops->convert_ctx_access) | 911 | if (!ops->convert_ctx_access) |
| 910 | continue; | 912 | continue; |
| @@ -920,26 +922,6 @@ int bpf_convert_ctx_accesses(struct bpf_verifier_env *env) · 9 unmodified lines |
| 920 | case PTR_TO_XDP_SOCK: | 922 | case PTR_TO_XDP_SOCK: |
| 921 | convert_ctx_access = bpf_xdp_sock_convert_ctx_access; | 923 | convert_ctx_access = bpf_xdp_sock_convert_ctx_access; |
| 922 | break; | 924 | break; |
| 923 | case PTR_TO_BTF_ID: | | |
| 924 | case PTR_TO_BTF_ID | PTR_UNTRUSTED: | | |
| 925 | /* PTR_TO_BTF_ID | MEM_ALLOC always has a valid lifetime, unlike | | |
| 926 | * PTR_TO_BTF_ID, and an active referenced id, but the same cannot | | |
| 927 | * be said once it is marked PTR_UNTRUSTED, hence we must handle | | |
| 928 | * any faults for loads into such types. BPF_WRITE is disallowed | | |
| 929 | * for this case. | | |
| 930 | */ | | |
| 931 | case PTR_TO_BTF_ID | MEM_ALLOC | PTR_UNTRUSTED: | | |
| 932 | case PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED: | | |
| 933 | if (type == BPF_READ) { | | |
| 934 | if (BPF_MODE(insn->code) == BPF_MEM) | | |
| 935 | insn->code = BPF_LDX | BPF_PROBE_MEM | | | |
| 936 | BPF_SIZE((insn)->code); | | |
| 937 | else | | |
| 938 | insn->code = BPF_LDX | BPF_PROBE_MEMSX | | | |
| 939 | BPF_SIZE((insn)->code); | | |
| 940 | env->prog->aux->num_exentries++; | | |
| 941 | } | | |
| 942 | continue; | | |
| 943 | case PTR_TO_ARENA: | 925 | case PTR_TO_ARENA: |
| 944 | if (BPF_MODE(insn->code) == BPF_MEMSX) { | 926 | if (BPF_MODE(insn->code) == BPF_MEMSX) { |
| 945 | if (!bpf_jit_supports_insn(insn, true)) { | 927 | if (!bpf_jit_supports_insn(insn, true)) { |
| @@ -953,6 +935,29 @@ int bpf_convert_ctx_accesses(struct bpf_verifier_env *env) · 7 unmodified lines |
| 953 | env->prog->aux->num_exentries++; | 935 | env->prog->aux->num_exentries++; |
| 954 | continue; | 936 | continue; |
| 955 | default: | 937 | default: |
| | 938 | /* |
| | 939 | * A pointer which may fault on a dereference must not |
| | 940 | * be loaded from without fault protection, hence turn |
| | 941 | * the BPF_LDX into a BPF_PROBE_MEM one so that a bad |
| | 942 | * address is handled rather than panicking the kernel. |
| | 943 | * A store through one is rejected earlier, there is no |
| | 944 | * probed counterpart to rewrite it into. |
| | 945 | */ |
| | 946 | if (bpf_is_ptr_to_mem_or_btf_id(ptr_type) && |
| | 947 | bpf_may_fault_on_deref(ptr_type) && |
| | 948 | type == BPF_READ) { |
| | 949 | if (BPF_MODE(insn->code) == BPF_MEM) |
| | 950 | insn->code = BPF_LDX | BPF_PROBE_MEM | |
| | 951 | BPF_SIZE(insn->code); |
| | 952 | else |
| | 953 | insn->code = BPF_LDX | BPF_PROBE_MEMSX | |
| | 954 | BPF_SIZE(insn->code); |
| | 955 | env->prog->aux->num_exentries++; |
| | 956 | continue; |
| | 957 | } |
| | 958 | if (verifier_bug_if(bpf_may_fault_on_deref(ptr_type), env, |
| | 959 | "access to a fault prone pointer is not rewritten as a probed one")) |
| | 960 | return -EFAULT; |
| 956 | continue; | 961 | continue; |
| 957 | } | 962 | } |
| 958 | | 963 | |