Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Pull bpf fixes from Alexei Starovoitov:

- Fix handling of BPF arena relocations (Andrii Nakryiko)

- Fix race in bpf_arch_text_poke() on s390 (Ilya Leoshkevich)

- Fix use of virt_to_phys() on arm64 when mmapping BTF (Lorenz Bauer)

- Reject %p% format string in bprintf-like BPF helpers (Paul Chaignon)

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
libbpf: Fix handling of BPF arena relocations
btf: Fix virt_to_phys() on arm64 when mmapping BTF
selftests/bpf: Stress test attaching a BPF prog to another BPF prog
s390/bpf: Fix bpf_arch_text_poke() with new_addr == NULL again
selftests/bpf: Add negative test cases for snprintf
bpf: Reject %p% format string in bprintf-like helpers

+100 -12
+9 -1
arch/s390/net/bpf_jit_comp.c
··· 566 566 { 567 567 memcpy(plt, &bpf_plt, sizeof(*plt)); 568 568 plt->ret = ret; 569 - plt->target = target; 569 + /* 570 + * (target == NULL) implies that the branch to this PLT entry was 571 + * patched and became a no-op. However, some CPU could have jumped 572 + * to this PLT entry before patching and may be still executing it. 573 + * 574 + * Since the intention in this case is to make the PLT entry a no-op, 575 + * make the target point to the return label instead of NULL. 576 + */ 577 + plt->target = target ?: ret; 570 578 } 571 579 572 580 /*
+8 -3
kernel/bpf/helpers.c
··· 884 884 if (fmt[i] == 'p') { 885 885 sizeof_cur_arg = sizeof(long); 886 886 887 + if (fmt[i + 1] == 0 || isspace(fmt[i + 1]) || 888 + ispunct(fmt[i + 1])) { 889 + if (tmp_buf) 890 + cur_arg = raw_args[num_spec]; 891 + goto nocopy_fmt; 892 + } 893 + 887 894 if ((fmt[i + 1] == 'k' || fmt[i + 1] == 'u') && 888 895 fmt[i + 2] == 's') { 889 896 fmt_ptype = fmt[i + 1]; ··· 898 891 goto fmt_str; 899 892 } 900 893 901 - if (fmt[i + 1] == 0 || isspace(fmt[i + 1]) || 902 - ispunct(fmt[i + 1]) || fmt[i + 1] == 'K' || 894 + if (fmt[i + 1] == 'K' || 903 895 fmt[i + 1] == 'x' || fmt[i + 1] == 's' || 904 896 fmt[i + 1] == 'S') { 905 - /* just kernel pointers */ 906 897 if (tmp_buf) 907 898 cur_arg = raw_args[num_spec]; 908 899 i++;
+1 -1
kernel/bpf/sysfs_btf.c
··· 21 21 { 22 22 unsigned long pages = PAGE_ALIGN(attr->size) >> PAGE_SHIFT; 23 23 size_t vm_size = vma->vm_end - vma->vm_start; 24 - phys_addr_t addr = virt_to_phys(__start_BTF); 24 + phys_addr_t addr = __pa_symbol(__start_BTF); 25 25 unsigned long pfn = addr >> PAGE_SHIFT; 26 26 27 27 if (attr->private != __start_BTF || !PAGE_ALIGNED(addr))
+13 -7
tools/lib/bpf/libbpf.c
··· 735 735 736 736 struct usdt_manager *usdt_man; 737 737 738 - struct bpf_map *arena_map; 738 + int arena_map_idx; 739 739 void *arena_data; 740 740 size_t arena_data_sz; 741 741 ··· 1517 1517 obj->efile.obj_buf_sz = obj_buf_sz; 1518 1518 obj->efile.btf_maps_shndx = -1; 1519 1519 obj->kconfig_map_idx = -1; 1520 + obj->arena_map_idx = -1; 1520 1521 1521 1522 obj->kern_version = get_kernel_version(); 1522 1523 obj->state = OBJ_OPEN; ··· 2965 2964 const long page_sz = sysconf(_SC_PAGE_SIZE); 2966 2965 size_t mmap_sz; 2967 2966 2968 - mmap_sz = bpf_map_mmap_sz(obj->arena_map); 2967 + mmap_sz = bpf_map_mmap_sz(map); 2969 2968 if (roundup(data_sz, page_sz) > mmap_sz) { 2970 2969 pr_warn("elf: sec '%s': declared ARENA map size (%zu) is too small to hold global __arena variables of size %zu\n", 2971 2970 sec_name, mmap_sz, data_sz); ··· 3039 3038 if (map->def.type != BPF_MAP_TYPE_ARENA) 3040 3039 continue; 3041 3040 3042 - if (obj->arena_map) { 3041 + if (obj->arena_map_idx >= 0) { 3043 3042 pr_warn("map '%s': only single ARENA map is supported (map '%s' is also ARENA)\n", 3044 - map->name, obj->arena_map->name); 3043 + map->name, obj->maps[obj->arena_map_idx].name); 3045 3044 return -EINVAL; 3046 3045 } 3047 - obj->arena_map = map; 3046 + obj->arena_map_idx = i; 3048 3047 3049 3048 if (obj->efile.arena_data) { 3050 3049 err = init_arena_map_data(obj, map, ARENA_SEC, obj->efile.arena_data_shndx, ··· 3054 3053 return err; 3055 3054 } 3056 3055 } 3057 - if (obj->efile.arena_data && !obj->arena_map) { 3056 + if (obj->efile.arena_data && obj->arena_map_idx < 0) { 3058 3057 pr_warn("elf: sec '%s': to use global __arena variables the ARENA map should be explicitly declared in SEC(\".maps\")\n", 3059 3058 ARENA_SEC); 3060 3059 return -ENOENT; ··· 4584 4583 if (shdr_idx == obj->efile.arena_data_shndx) { 4585 4584 reloc_desc->type = RELO_DATA; 4586 4585 reloc_desc->insn_idx = insn_idx; 4587 - reloc_desc->map_idx = obj->arena_map - obj->maps; 4586 + reloc_desc->map_idx = obj->arena_map_idx; 4588 4587 reloc_desc->sym_off = sym->st_value; 4588 + 4589 + map = &obj->maps[obj->arena_map_idx]; 4590 + pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n", 4591 + prog->name, obj->arena_map_idx, map->name, map->sec_idx, 4592 + map->sec_offset, insn_idx); 4589 4593 return 0; 4590 4594 } 4591 4595
+67
tools/testing/selftests/bpf/prog_tests/recursive_attach.c
··· 149 149 fentry_recursive_target__destroy(target_skel); 150 150 fentry_recursive__destroy(tracing_skel); 151 151 } 152 + 153 + static void *fentry_target_test_run(void *arg) 154 + { 155 + for (;;) { 156 + int prog_fd = __atomic_load_n((int *)arg, __ATOMIC_SEQ_CST); 157 + LIBBPF_OPTS(bpf_test_run_opts, topts); 158 + int err; 159 + 160 + if (prog_fd == -1) 161 + break; 162 + err = bpf_prog_test_run_opts(prog_fd, &topts); 163 + if (!ASSERT_OK(err, "fentry_target test_run")) 164 + break; 165 + } 166 + 167 + return NULL; 168 + } 169 + 170 + void test_fentry_attach_stress(void) 171 + { 172 + struct fentry_recursive_target *target_skel = NULL; 173 + struct fentry_recursive *tracing_skel = NULL; 174 + struct bpf_program *prog; 175 + int err, i, tgt_prog_fd; 176 + pthread_t thread; 177 + 178 + target_skel = fentry_recursive_target__open_and_load(); 179 + if (!ASSERT_OK_PTR(target_skel, 180 + "fentry_recursive_target__open_and_load")) 181 + goto close_prog; 182 + tgt_prog_fd = bpf_program__fd(target_skel->progs.fentry_target); 183 + err = pthread_create(&thread, NULL, 184 + fentry_target_test_run, &tgt_prog_fd); 185 + if (!ASSERT_OK(err, "bpf_program__set_attach_target")) 186 + goto close_prog; 187 + 188 + for (i = 0; i < 1000; i++) { 189 + tracing_skel = fentry_recursive__open(); 190 + if (!ASSERT_OK_PTR(tracing_skel, "fentry_recursive__open")) 191 + goto stop_thread; 192 + 193 + prog = tracing_skel->progs.recursive_attach; 194 + err = bpf_program__set_attach_target(prog, tgt_prog_fd, 195 + "fentry_target"); 196 + if (!ASSERT_OK(err, "bpf_program__set_attach_target")) 197 + goto stop_thread; 198 + 199 + err = fentry_recursive__load(tracing_skel); 200 + if (!ASSERT_OK(err, "fentry_recursive__load")) 201 + goto stop_thread; 202 + 203 + err = fentry_recursive__attach(tracing_skel); 204 + if (!ASSERT_OK(err, "fentry_recursive__attach")) 205 + goto stop_thread; 206 + 207 + fentry_recursive__destroy(tracing_skel); 208 + tracing_skel = NULL; 209 + } 210 + 211 + stop_thread: 212 + __atomic_store_n(&tgt_prog_fd, -1, __ATOMIC_SEQ_CST); 213 + err = pthread_join(thread, NULL); 214 + ASSERT_OK(err, "pthread_join"); 215 + close_prog: 216 + fentry_recursive__destroy(tracing_skel); 217 + fentry_recursive_target__destroy(target_skel); 218 + }
+2
tools/testing/selftests/bpf/prog_tests/snprintf.c
··· 116 116 ASSERT_ERR(load_single_snprintf("%llc"), "invalid specifier 7"); 117 117 ASSERT_ERR(load_single_snprintf("\x80"), "non ascii character"); 118 118 ASSERT_ERR(load_single_snprintf("\x1"), "non printable character"); 119 + ASSERT_ERR(load_single_snprintf("%p%"), "invalid specifier 8"); 120 + ASSERT_ERR(load_single_snprintf("%s%"), "invalid specifier 9"); 119 121 } 120 122 121 123 void test_snprintf(void)