Alexei Starovoitov says: ==================== pull-request: bpf 2020-11-06 1) Pre-allocated per-cpu hashmap needs to zero-fill reused element, from David. 2) Tighten bpf_lsm function check, from KP. 3) Fix bpftool attaching to flow dissector, from Lorenz. 4) Use -fno-gcse for the whole kernel/bpf/core.c instead of function attribute, from Ard. * git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: bpf: Update verification logic for LSM programs bpf: Zero-fill re-used per-cpu map element bpf: BPF_PRELOAD depends on BPF_SYSCALL tools/bpftool: Fix attaching flow dissector libbpf: Fix possible use after free in xsk_socket__delete libbpf: Fix null dereference in xsk_socket__delete libbpf, hashmap: Fix undefined behavior in hash_bits bpf: Don't rely on GCC __attribute__((optimize)) to disable GCSE tools, bpftool: Remove two unused variables. tools, bpftool: Avoid array index warnings. xsk: Fix possible memory leak at socket close bpf: Add struct bpf_redir_neigh forward declaration to BPF helper defs samples/bpf: Set rlimit for memlock to infinity in all samples bpf: Fix -Wshadow warnings selftest/bpf: Fix profiler test using CO-RE relocation for enums ====================
Showing the changes to kernel (5 of 25 files). Show all
Unified · Split
| @@ -1,6 +1,10 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | obj-y := core.o | 2 | obj-y := core.o |
| 3 | CFLAGS_core.o += $(call cc-disable-warning, override-init) | 3 | ifneq ($(CONFIG_BPF_JIT_ALWAYS_ON),y) |
| 4 | # ___bpf_prog_run() needs GCSE disabled on x86; see 3193c0836f203 for details | ||
| 5 | cflags-nogcse-$(CONFIG_X86)$(CONFIG_CC_IS_GCC) := -fno-gcse | ||
| 6 | endif | ||
| 7 | CFLAGS_core.o += $(call cc-disable-warning, override-init) $(cflags-nogcse-yy) | ||
| 4 | 8 | ||
| 5 | obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o bpf_iter.o map_iter.o task_iter.o prog_iter.o | 9 | obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o bpf_iter.o map_iter.o task_iter.o prog_iter.o |
| 6 | obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o | 10 | obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/bpf_verifier.h> | 13 | #include <linux/bpf_verifier.h> |
| 14 | #include <net/bpf_sk_storage.h> | 14 | #include <net/bpf_sk_storage.h> |
| 15 | #include <linux/bpf_local_storage.h> | 15 | #include <linux/bpf_local_storage.h> |
| 16 | #include <linux/btf_ids.h> | ||
| 16 | 17 | ||
| 17 | /* For every LSM hook that allows attachment of BPF programs, declare a nop | 18 | /* For every LSM hook that allows attachment of BPF programs, declare a nop |
| 18 | * function where a BPF program can be attached. | 19 | * function where a BPF program can be attached. |
| @@ -26,7 +27,11 @@ noinline RET bpf_lsm_##NAME(__VA_ARGS__) \ · 7 unmodified lines | |||
| 26 | #include <linux/lsm_hook_defs.h> | 27 | #include <linux/lsm_hook_defs.h> |
| 27 | #undef LSM_HOOK | 28 | #undef LSM_HOOK |
| 28 | 29 | ||
| 29 | #define BPF_LSM_SYM_PREFX "bpf_lsm_" | 30 | #define LSM_HOOK(RET, DEFAULT, NAME, ...) BTF_ID(func, bpf_lsm_##NAME) |
| 31 | BTF_SET_START(bpf_lsm_hooks) | ||
| 32 | #include <linux/lsm_hook_defs.h> | ||
| 33 | #undef LSM_HOOK | ||
| 34 | BTF_SET_END(bpf_lsm_hooks) | ||
| 30 | 35 | ||
| 31 | int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, | 36 | int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, |
| 32 | const struct bpf_prog *prog) | 37 | const struct bpf_prog *prog) |
| @@ -37,8 +42,7 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, · 4 unmodified lines | |||
| 37 | return -EINVAL; | 42 | return -EINVAL; |
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | if (strncmp(BPF_LSM_SYM_PREFX, prog->aux->attach_func_name, | 45 | if (!btf_id_set_contains(&bpf_lsm_hooks, prog->aux->attach_btf_id)) { |
| 41 | sizeof(BPF_LSM_SYM_PREFX) - 1)) { | ||
| 42 | bpf_log(vlog, "attach_btf_id %u points to wrong type name %s\n", | 46 | bpf_log(vlog, "attach_btf_id %u points to wrong type name %s\n", |
| 43 | prog->aux->attach_btf_id, prog->aux->attach_func_name); | 47 | prog->aux->attach_btf_id, prog->aux->attach_func_name); |
| 44 | return -EINVAL; | 48 | return -EINVAL; |
| @@ -1369,7 +1369,7 @@ u64 __weak bpf_probe_read_kernel(void *dst, u32 size, const void *unsafe_ptr) · 1368 unmodified lines | |||
| 1369 | * | 1369 | * |
| 1370 | * Decode and execute eBPF instructions. | 1370 | * Decode and execute eBPF instructions. |
| 1371 | */ | 1371 | */ |
| 1372 | static u64 __no_fgcse ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack) | 1372 | static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack) |
| 1373 | { | 1373 | { |
| 1374 | #define BPF_INSN_2_LBL(x, y) [BPF_##x | BPF_##y] = &&x##_##y | 1374 | #define BPF_INSN_2_LBL(x, y) [BPF_##x | BPF_##y] = &&x##_##y |
| 1375 | #define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z | 1375 | #define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z |
| @@ -821,6 +821,32 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, · 820 unmodified lines | |||
| 821 | } | 821 | } |
| 822 | } | 822 | } |
| 823 | 823 | ||
| 824 | static void pcpu_init_value(struct bpf_htab *htab, void __percpu *pptr, | ||
| 825 | void *value, bool onallcpus) | ||
| 826 | { | ||
| 827 | /* When using prealloc and not setting the initial value on all cpus, | ||
| 828 | * zero-fill element values for other cpus (just as what happens when | ||
| 829 | * not using prealloc). Otherwise, bpf program has no way to ensure | ||
| 830 | * known initial values for cpus other than current one | ||
| 831 | * (onallcpus=false always when coming from bpf prog). | ||
| 832 | */ | ||
| 833 | if (htab_is_prealloc(htab) && !onallcpus) { | ||
| 834 | u32 size = round_up(htab->map.value_size, 8); | ||
| 835 | int current_cpu = raw_smp_processor_id(); | ||
| 836 | int cpu; | ||
| 837 | |||
| 838 | for_each_possible_cpu(cpu) { | ||
| 839 | if (cpu == current_cpu) | ||
| 840 | bpf_long_memcpy(per_cpu_ptr(pptr, cpu), value, | ||
| 841 | size); | ||
| 842 | else | ||
| 843 | memset(per_cpu_ptr(pptr, cpu), 0, size); | ||
| 844 | } | ||
| 845 | } else { | ||
| 846 | pcpu_copy_value(htab, pptr, value, onallcpus); | ||
| 847 | } | ||
| 848 | } | ||
| 849 | |||
| 824 | static bool fd_htab_map_needs_adjust(const struct bpf_htab *htab) | 850 | static bool fd_htab_map_needs_adjust(const struct bpf_htab *htab) |
| 825 | { | 851 | { |
| 826 | return htab->map.map_type == BPF_MAP_TYPE_HASH_OF_MAPS && | 852 | return htab->map.map_type == BPF_MAP_TYPE_HASH_OF_MAPS && |
| @@ -891,7 +917,7 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, · 64 unmodified lines | |||
| 891 | } | 917 | } |
| 892 | } | 918 | } |
| 893 | 919 | ||
| 894 | pcpu_copy_value(htab, pptr, value, onallcpus); | 920 | pcpu_init_value(htab, pptr, value, onallcpus); |
| 895 | 921 | ||
| 896 | if (!prealloc) | 922 | if (!prealloc) |
| 897 | htab_elem_set_ptr(l_new, key_size, pptr); | 923 | htab_elem_set_ptr(l_new, key_size, pptr); |
| @@ -1183,7 +1209,7 @@ static int __htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key, · 285 unmodified lines | |||
| 1183 | pcpu_copy_value(htab, htab_elem_get_ptr(l_old, key_size), | 1209 | pcpu_copy_value(htab, htab_elem_get_ptr(l_old, key_size), |
| 1184 | value, onallcpus); | 1210 | value, onallcpus); |
| 1185 | } else { | 1211 | } else { |
| 1186 | pcpu_copy_value(htab, htab_elem_get_ptr(l_new, key_size), | 1212 | pcpu_init_value(htab, htab_elem_get_ptr(l_new, key_size), |
| 1187 | value, onallcpus); | 1213 | value, onallcpus); |
| 1188 | hlist_nulls_add_head_rcu(&l_new->hash_node, head); | 1214 | hlist_nulls_add_head_rcu(&l_new->hash_node, head); |
| 1189 | l_new = NULL; | 1215 | l_new = NULL; |
| @@ -6,6 +6,7 @@ config USERMODE_DRIVER · 5 unmodified lines | |||
| 6 | menuconfig BPF_PRELOAD | 6 | menuconfig BPF_PRELOAD |
| 7 | bool "Preload BPF file system with kernel specific program and map iterators" | 7 | bool "Preload BPF file system with kernel specific program and map iterators" |
| 8 | depends on BPF | 8 | depends on BPF |
| 9 | depends on BPF_SYSCALL | ||
| 9 | # The dependency on !COMPILE_TEST prevents it from being enabled | 10 | # The dependency on !COMPILE_TEST prevents it from being enabled |
| 10 | # in allmodconfig or allyesconfig configurations | 11 | # in allmodconfig or allyesconfig configurations |
| 11 | depends on !COMPILE_TEST | 12 | depends on !COMPILE_TEST |