diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bpf/cgroup.c | 2 | ||||
-rw-r--r-- | kernel/bpf/core.c | 1 | ||||
-rw-r--r-- | kernel/bpf/helpers.c | 20 | ||||
-rw-r--r-- | kernel/bpf/verifier.c | 18 |
4 files changed, 41 insertions, 0 deletions
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index ddfa6cc13e57..0a4fe5a7dc91 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c | |||
@@ -684,6 +684,8 @@ cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) | |||
684 | return &bpf_map_delete_elem_proto; | 684 | return &bpf_map_delete_elem_proto; |
685 | case BPF_FUNC_get_current_uid_gid: | 685 | case BPF_FUNC_get_current_uid_gid: |
686 | return &bpf_get_current_uid_gid_proto; | 686 | return &bpf_get_current_uid_gid_proto; |
687 | case BPF_FUNC_get_local_storage: | ||
688 | return &bpf_get_local_storage_proto; | ||
687 | case BPF_FUNC_trace_printk: | 689 | case BPF_FUNC_trace_printk: |
688 | if (capable(CAP_SYS_ADMIN)) | 690 | if (capable(CAP_SYS_ADMIN)) |
689 | return bpf_get_trace_printk_proto(); | 691 | return bpf_get_trace_printk_proto(); |
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 9abcf25ebf9f..4d09e610777f 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
@@ -1795,6 +1795,7 @@ const struct bpf_func_proto bpf_get_current_comm_proto __weak; | |||
1795 | const struct bpf_func_proto bpf_sock_map_update_proto __weak; | 1795 | const struct bpf_func_proto bpf_sock_map_update_proto __weak; |
1796 | const struct bpf_func_proto bpf_sock_hash_update_proto __weak; | 1796 | const struct bpf_func_proto bpf_sock_hash_update_proto __weak; |
1797 | const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak; | 1797 | const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak; |
1798 | const struct bpf_func_proto bpf_get_local_storage_proto __weak; | ||
1798 | 1799 | ||
1799 | const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void) | 1800 | const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void) |
1800 | { | 1801 | { |
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 73065e2d23c2..1991466b8327 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c | |||
@@ -193,4 +193,24 @@ const struct bpf_func_proto bpf_get_current_cgroup_id_proto = { | |||
193 | .gpl_only = false, | 193 | .gpl_only = false, |
194 | .ret_type = RET_INTEGER, | 194 | .ret_type = RET_INTEGER, |
195 | }; | 195 | }; |
196 | |||
197 | DECLARE_PER_CPU(void*, bpf_cgroup_storage); | ||
198 | |||
199 | BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags) | ||
200 | { | ||
201 | /* map and flags arguments are not used now, | ||
202 | * but provide an ability to extend the API | ||
203 | * for other types of local storages. | ||
204 | * verifier checks that their values are correct. | ||
205 | */ | ||
206 | return (unsigned long) this_cpu_read(bpf_cgroup_storage); | ||
207 | } | ||
208 | |||
209 | const struct bpf_func_proto bpf_get_local_storage_proto = { | ||
210 | .func = bpf_get_local_storage, | ||
211 | .gpl_only = false, | ||
212 | .ret_type = RET_PTR_TO_MAP_VALUE, | ||
213 | .arg1_type = ARG_CONST_MAP_PTR, | ||
214 | .arg2_type = ARG_ANYTHING, | ||
215 | }; | ||
196 | #endif | 216 | #endif |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1ede16c8bb40..587468a9c37d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -2127,6 +2127,10 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env, | |||
2127 | func_id != BPF_FUNC_current_task_under_cgroup) | 2127 | func_id != BPF_FUNC_current_task_under_cgroup) |
2128 | goto error; | 2128 | goto error; |
2129 | break; | 2129 | break; |
2130 | case BPF_MAP_TYPE_CGROUP_STORAGE: | ||
2131 | if (func_id != BPF_FUNC_get_local_storage) | ||
2132 | goto error; | ||
2133 | break; | ||
2130 | /* devmap returns a pointer to a live net_device ifindex that we cannot | 2134 | /* devmap returns a pointer to a live net_device ifindex that we cannot |
2131 | * allow to be modified from bpf side. So do not allow lookup elements | 2135 | * allow to be modified from bpf side. So do not allow lookup elements |
2132 | * for now. | 2136 | * for now. |
@@ -2209,6 +2213,10 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env, | |||
2209 | if (map->map_type != BPF_MAP_TYPE_SOCKHASH) | 2213 | if (map->map_type != BPF_MAP_TYPE_SOCKHASH) |
2210 | goto error; | 2214 | goto error; |
2211 | break; | 2215 | break; |
2216 | case BPF_FUNC_get_local_storage: | ||
2217 | if (map->map_type != BPF_MAP_TYPE_CGROUP_STORAGE) | ||
2218 | goto error; | ||
2219 | break; | ||
2212 | default: | 2220 | default: |
2213 | break; | 2221 | break; |
2214 | } | 2222 | } |
@@ -2533,6 +2541,16 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn | |||
2533 | } | 2541 | } |
2534 | 2542 | ||
2535 | regs = cur_regs(env); | 2543 | regs = cur_regs(env); |
2544 | |||
2545 | /* check that flags argument in get_local_storage(map, flags) is 0, | ||
2546 | * this is required because get_local_storage() can't return an error. | ||
2547 | */ | ||
2548 | if (func_id == BPF_FUNC_get_local_storage && | ||
2549 | !register_is_null(®s[BPF_REG_2])) { | ||
2550 | verbose(env, "get_local_storage() doesn't support non-zero flags\n"); | ||
2551 | return -EINVAL; | ||
2552 | } | ||
2553 | |||
2536 | /* reset caller saved regs */ | 2554 | /* reset caller saved regs */ |
2537 | for (i = 0; i < CALLER_SAVED_REGS; i++) { | 2555 | for (i = 0; i < CALLER_SAVED_REGS; i++) { |
2538 | mark_reg_not_init(env, regs, caller_saved[i]); | 2556 | mark_reg_not_init(env, regs, caller_saved[i]); |