Skip to content

Commit 5d52c90

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2021-07-09 The following pull-request contains BPF updates for your *net* tree. We've added 9 non-merge commits during the last 9 day(s) which contain a total of 13 files changed, 118 insertions(+), 62 deletions(-). The main changes are: 1) Fix runqslower task->state access from BPF, from SanjayKumar Jeyakumar. 2) Fix subprog poke descriptor tracking use-after-free, from John Fastabend. 3) Fix sparse complaint from prior devmap RCU conversion, from Toke Høiland-Jørgensen. 4) Fix missing va_end in bpftool JIT json dump's error path, from Gu Shengxian. 5) Fix tools/bpf install target from missing runqslower install, from Wei Li. 6) Fix xdpsock BPF sample to unload program on shared umem option, from Wang Hai. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 67a9c94 + 1fb5ba2 commit 5d52c90

File tree

13 files changed

+118
-62
lines changed

13 files changed

+118
-62
lines changed

arch/x86/net/bpf_jit_comp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,9 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog)
570570

571571
for (i = 0; i < prog->aux->size_poke_tab; i++) {
572572
poke = &prog->aux->poke_tab[i];
573+
if (poke->aux && poke->aux != prog->aux)
574+
continue;
575+
573576
WARN_ON_ONCE(READ_ONCE(poke->tailcall_target_stable));
574577

575578
if (poke->reason != BPF_POKE_REASON_TAIL_CALL)

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ struct bpf_jit_poke_descriptor {
780780
void *tailcall_target;
781781
void *tailcall_bypass;
782782
void *bypass_addr;
783+
void *aux;
783784
union {
784785
struct {
785786
struct bpf_map *map;

kernel/bpf/core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2236,8 +2236,14 @@ static void bpf_prog_free_deferred(struct work_struct *work)
22362236
#endif
22372237
if (aux->dst_trampoline)
22382238
bpf_trampoline_put(aux->dst_trampoline);
2239-
for (i = 0; i < aux->func_cnt; i++)
2239+
for (i = 0; i < aux->func_cnt; i++) {
2240+
/* We can just unlink the subprog poke descriptor table as
2241+
* it was originally linked to the main program and is also
2242+
* released along with it.
2243+
*/
2244+
aux->func[i]->aux->poke_tab = NULL;
22402245
bpf_jit_free(aux->func[i]);
2246+
}
22412247
if (aux->func_cnt) {
22422248
kfree(aux->func);
22432249
bpf_prog_unlock_free(aux->prog);

kernel/bpf/devmap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,8 @@ int dev_map_enqueue_multi(struct xdp_buff *xdp, struct net_device *dev_rx,
558558

559559
if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
560560
for (i = 0; i < map->max_entries; i++) {
561-
dst = READ_ONCE(dtab->netdev_map[i]);
561+
dst = rcu_dereference_check(dtab->netdev_map[i],
562+
rcu_read_lock_bh_held());
562563
if (!is_valid_dst(dst, xdp, exclude_ifindex))
563564
continue;
564565

@@ -654,7 +655,8 @@ int dev_map_redirect_multi(struct net_device *dev, struct sk_buff *skb,
654655

655656
if (map->map_type == BPF_MAP_TYPE_DEVMAP) {
656657
for (i = 0; i < map->max_entries; i++) {
657-
dst = READ_ONCE(dtab->netdev_map[i]);
658+
dst = rcu_dereference_check(dtab->netdev_map[i],
659+
rcu_read_lock_bh_held());
658660
if (!dst || dst->dev->ifindex == exclude_ifindex)
659661
continue;
660662

kernel/bpf/verifier.c

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12121,33 +12121,19 @@ static int jit_subprogs(struct bpf_verifier_env *env)
1212112121
goto out_free;
1212212122
func[i]->is_func = 1;
1212312123
func[i]->aux->func_idx = i;
12124-
/* the btf and func_info will be freed only at prog->aux */
12124+
/* Below members will be freed only at prog->aux */
1212512125
func[i]->aux->btf = prog->aux->btf;
1212612126
func[i]->aux->func_info = prog->aux->func_info;
12127+
func[i]->aux->poke_tab = prog->aux->poke_tab;
12128+
func[i]->aux->size_poke_tab = prog->aux->size_poke_tab;
1212712129

1212812130
for (j = 0; j < prog->aux->size_poke_tab; j++) {
12129-
u32 insn_idx = prog->aux->poke_tab[j].insn_idx;
12130-
int ret;
12131+
struct bpf_jit_poke_descriptor *poke;
1213112132

12132-
if (!(insn_idx >= subprog_start &&
12133-
insn_idx <= subprog_end))
12134-
continue;
12135-
12136-
ret = bpf_jit_add_poke_descriptor(func[i],
12137-
&prog->aux->poke_tab[j]);
12138-
if (ret < 0) {
12139-
verbose(env, "adding tail call poke descriptor failed\n");
12140-
goto out_free;
12141-
}
12142-
12143-
func[i]->insnsi[insn_idx - subprog_start].imm = ret + 1;
12144-
12145-
map_ptr = func[i]->aux->poke_tab[ret].tail_call.map;
12146-
ret = map_ptr->ops->map_poke_track(map_ptr, func[i]->aux);
12147-
if (ret < 0) {
12148-
verbose(env, "tracking tail call prog failed\n");
12149-
goto out_free;
12150-
}
12133+
poke = &prog->aux->poke_tab[j];
12134+
if (poke->insn_idx < subprog_end &&
12135+
poke->insn_idx >= subprog_start)
12136+
poke->aux = func[i]->aux;
1215112137
}
1215212138

1215312139
/* Use bpf_prog_F_tag to indicate functions in stack traces.
@@ -12178,18 +12164,6 @@ static int jit_subprogs(struct bpf_verifier_env *env)
1217812164
cond_resched();
1217912165
}
1218012166

12181-
/* Untrack main program's aux structs so that during map_poke_run()
12182-
* we will not stumble upon the unfilled poke descriptors; each
12183-
* of the main program's poke descs got distributed across subprogs
12184-
* and got tracked onto map, so we are sure that none of them will
12185-
* be missed after the operation below
12186-
*/
12187-
for (i = 0; i < prog->aux->size_poke_tab; i++) {
12188-
map_ptr = prog->aux->poke_tab[i].tail_call.map;
12189-
12190-
map_ptr->ops->map_poke_untrack(map_ptr, prog->aux);
12191-
}
12192-
1219312167
/* at this point all bpf functions were successfully JITed
1219412168
* now populate all bpf_calls with correct addresses and
1219512169
* run last pass of JIT
@@ -12267,14 +12241,22 @@ static int jit_subprogs(struct bpf_verifier_env *env)
1226712241
bpf_prog_jit_attempt_done(prog);
1226812242
return 0;
1226912243
out_free:
12244+
/* We failed JIT'ing, so at this point we need to unregister poke
12245+
* descriptors from subprogs, so that kernel is not attempting to
12246+
* patch it anymore as we're freeing the subprog JIT memory.
12247+
*/
12248+
for (i = 0; i < prog->aux->size_poke_tab; i++) {
12249+
map_ptr = prog->aux->poke_tab[i].tail_call.map;
12250+
map_ptr->ops->map_poke_untrack(map_ptr, prog->aux);
12251+
}
12252+
/* At this point we're guaranteed that poke descriptors are not
12253+
* live anymore. We can just unlink its descriptor table as it's
12254+
* released with the main prog.
12255+
*/
1227012256
for (i = 0; i < env->subprog_cnt; i++) {
1227112257
if (!func[i])
1227212258
continue;
12273-
12274-
for (j = 0; j < func[i]->aux->size_poke_tab; j++) {
12275-
map_ptr = func[i]->aux->poke_tab[j].tail_call.map;
12276-
map_ptr->ops->map_poke_untrack(map_ptr, func[i]->aux);
12277-
}
12259+
func[i]->aux->poke_tab = NULL;
1227812260
bpf_jit_free(func[i]);
1227912261
}
1228012262
kfree(func);

samples/bpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ $(obj)/%.o: $(src)/%.c
331331
-Wno-gnu-variable-sized-type-not-at-end \
332332
-Wno-address-of-packed-member -Wno-tautological-compare \
333333
-Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \
334+
-fno-asynchronous-unwind-tables \
334335
-I$(srctree)/samples/bpf/ -include asm_goto_workaround.h \
335336
-O2 -emit-llvm -Xclang -disable-llvm-passes -c $< -o - | \
336337
$(OPT) -O2 -mtriple=bpf-pc-linux | $(LLVM_DIS) | \

samples/bpf/xdpsock_user.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static int opt_xsk_frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
9696
static int opt_timeout = 1000;
9797
static bool opt_need_wakeup = true;
9898
static u32 opt_num_xsks = 1;
99+
static u32 prog_id;
99100
static bool opt_busy_poll;
100101
static bool opt_reduced_cap;
101102

@@ -461,6 +462,23 @@ static void *poller(void *arg)
461462
return NULL;
462463
}
463464

465+
static void remove_xdp_program(void)
466+
{
467+
u32 curr_prog_id = 0;
468+
469+
if (bpf_get_link_xdp_id(opt_ifindex, &curr_prog_id, opt_xdp_flags)) {
470+
printf("bpf_get_link_xdp_id failed\n");
471+
exit(EXIT_FAILURE);
472+
}
473+
474+
if (prog_id == curr_prog_id)
475+
bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags);
476+
else if (!curr_prog_id)
477+
printf("couldn't find a prog id on a given interface\n");
478+
else
479+
printf("program on interface changed, not removing\n");
480+
}
481+
464482
static void int_exit(int sig)
465483
{
466484
benchmark_done = true;
@@ -471,6 +489,9 @@ static void __exit_with_error(int error, const char *file, const char *func,
471489
{
472490
fprintf(stderr, "%s:%s:%i: errno: %d/\"%s\"\n", file, func,
473491
line, error, strerror(error));
492+
493+
if (opt_num_xsks > 1)
494+
remove_xdp_program();
474495
exit(EXIT_FAILURE);
475496
}
476497

@@ -490,6 +511,9 @@ static void xdpsock_cleanup(void)
490511
if (write(sock, &cmd, sizeof(int)) < 0)
491512
exit_with_error(errno);
492513
}
514+
515+
if (opt_num_xsks > 1)
516+
remove_xdp_program();
493517
}
494518

495519
static void swap_mac_addresses(void *data)
@@ -857,6 +881,10 @@ static struct xsk_socket_info *xsk_configure_socket(struct xsk_umem_info *umem,
857881
if (ret)
858882
exit_with_error(-ret);
859883

884+
ret = bpf_get_link_xdp_id(opt_ifindex, &prog_id, opt_xdp_flags);
885+
if (ret)
886+
exit_with_error(-ret);
887+
860888
xsk->app_stats.rx_empty_polls = 0;
861889
xsk->app_stats.fill_fail_polls = 0;
862890
xsk->app_stats.copy_tx_sendtos = 0;

tools/bpf/Makefile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ clean: bpftool_clean runqslower_clean resolve_btfids_clean
9797
$(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.bpf
9898
$(Q)$(RM) -r -- $(OUTPUT)feature
9999

100-
install: $(PROGS) bpftool_install runqslower_install
100+
install: $(PROGS) bpftool_install
101101
$(call QUIET_INSTALL, bpf_jit_disasm)
102102
$(Q)$(INSTALL) -m 0755 -d $(DESTDIR)$(prefix)/bin
103103
$(Q)$(INSTALL) $(OUTPUT)bpf_jit_disasm $(DESTDIR)$(prefix)/bin/bpf_jit_disasm
@@ -118,9 +118,6 @@ bpftool_clean:
118118
runqslower:
119119
$(call descend,runqslower)
120120

121-
runqslower_install:
122-
$(call descend,runqslower,install)
123-
124121
runqslower_clean:
125122
$(call descend,runqslower,clean)
126123

@@ -131,5 +128,5 @@ resolve_btfids_clean:
131128
$(call descend,resolve_btfids,clean)
132129

133130
.PHONY: all install clean bpftool bpftool_install bpftool_clean \
134-
runqslower runqslower_install runqslower_clean \
131+
runqslower runqslower_clean \
135132
resolve_btfids resolve_btfids_clean

tools/bpf/bpftool/jit_disasm.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,13 @@ static int fprintf_json(void *out, const char *fmt, ...)
4343
{
4444
va_list ap;
4545
char *s;
46+
int err;
4647

4748
va_start(ap, fmt);
48-
if (vasprintf(&s, fmt, ap) < 0)
49-
return -1;
49+
err = vasprintf(&s, fmt, ap);
5050
va_end(ap);
51+
if (err < 0)
52+
return -1;
5153

5254
if (!oper_count) {
5355
int i;

tools/bpf/runqslower/runqslower.bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ int handle__sched_switch(u64 *ctx)
7474
u32 pid;
7575

7676
/* ivcsw: treat like an enqueue event and store timestamp */
77-
if (prev->state == TASK_RUNNING)
77+
if (prev->__state == TASK_RUNNING)
7878
trace_enqueue(prev);
7979

8080
pid = next->pid;

tools/lib/bpf/libbpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10136,7 +10136,7 @@ int bpf_link__unpin(struct bpf_link *link)
1013610136

1013710137
err = unlink(link->pin_path);
1013810138
if (err != 0)
10139-
return libbpf_err_errno(err);
10139+
return -errno;
1014010140

1014110141
pr_debug("link fd=%d: unpinned from %s\n", link->fd, link->pin_path);
1014210142
zfree(&link->pin_path);
@@ -11197,7 +11197,7 @@ int perf_buffer__poll(struct perf_buffer *pb, int timeout_ms)
1119711197

1119811198
cnt = epoll_wait(pb->epoll_fd, pb->events, pb->cpu_cnt, timeout_ms);
1119911199
if (cnt < 0)
11200-
return libbpf_err_errno(cnt);
11200+
return -errno;
1120111201

1120211202
for (i = 0; i < cnt; i++) {
1120311203
struct perf_cpu_buf *cpu_buf = pb->events[i].data.ptr;

tools/testing/selftests/bpf/prog_tests/tailcalls.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,8 @@ static void test_tailcall_bpf2bpf_3(void)
715715
bpf_object__close(obj);
716716
}
717717

718+
#include "tailcall_bpf2bpf4.skel.h"
719+
718720
/* test_tailcall_bpf2bpf_4 checks that tailcall counter is correctly preserved
719721
* across tailcalls combined with bpf2bpf calls. for making sure that tailcall
720722
* counter behaves correctly, bpf program will go through following flow:
@@ -727,10 +729,15 @@ static void test_tailcall_bpf2bpf_3(void)
727729
* the loop begins. At the end of the test make sure that the global counter is
728730
* equal to 31, because tailcall counter includes the first two tailcalls
729731
* whereas global counter is incremented only on loop presented on flow above.
732+
*
733+
* The noise parameter is used to insert bpf_map_update calls into the logic
734+
* to force verifier to patch instructions. This allows us to ensure jump
735+
* logic remains correct with instruction movement.
730736
*/
731-
static void test_tailcall_bpf2bpf_4(void)
737+
static void test_tailcall_bpf2bpf_4(bool noise)
732738
{
733-
int err, map_fd, prog_fd, main_fd, data_fd, i, val;
739+
int err, map_fd, prog_fd, main_fd, data_fd, i;
740+
struct tailcall_bpf2bpf4__bss val;
734741
struct bpf_map *prog_array, *data_map;
735742
struct bpf_program *prog;
736743
struct bpf_object *obj;
@@ -774,11 +781,6 @@ static void test_tailcall_bpf2bpf_4(void)
774781
goto out;
775782
}
776783

777-
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0,
778-
&duration, &retval, NULL);
779-
CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n",
780-
err, errno, retval);
781-
782784
data_map = bpf_object__find_map_by_name(obj, "tailcall.bss");
783785
if (CHECK_FAIL(!data_map || !bpf_map__is_internal(data_map)))
784786
return;
@@ -787,10 +789,22 @@ static void test_tailcall_bpf2bpf_4(void)
787789
if (CHECK_FAIL(map_fd < 0))
788790
return;
789791

792+
i = 0;
793+
val.noise = noise;
794+
val.count = 0;
795+
err = bpf_map_update_elem(data_fd, &i, &val, BPF_ANY);
796+
if (CHECK_FAIL(err))
797+
goto out;
798+
799+
err = bpf_prog_test_run(main_fd, 1, &pkt_v4, sizeof(pkt_v4), 0,
800+
&duration, &retval, NULL);
801+
CHECK(err || retval != sizeof(pkt_v4) * 3, "tailcall", "err %d errno %d retval %d\n",
802+
err, errno, retval);
803+
790804
i = 0;
791805
err = bpf_map_lookup_elem(data_fd, &i, &val);
792-
CHECK(err || val != 31, "tailcall count", "err %d errno %d count %d\n",
793-
err, errno, val);
806+
CHECK(err || val.count != 31, "tailcall count", "err %d errno %d count %d\n",
807+
err, errno, val.count);
794808

795809
out:
796810
bpf_object__close(obj);
@@ -815,5 +829,7 @@ void test_tailcalls(void)
815829
if (test__start_subtest("tailcall_bpf2bpf_3"))
816830
test_tailcall_bpf2bpf_3();
817831
if (test__start_subtest("tailcall_bpf2bpf_4"))
818-
test_tailcall_bpf2bpf_4();
832+
test_tailcall_bpf2bpf_4(false);
833+
if (test__start_subtest("tailcall_bpf2bpf_5"))
834+
test_tailcall_bpf2bpf_4(true);
819835
}

tools/testing/selftests/bpf/progs/tailcall_bpf2bpf4.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
#include <linux/bpf.h>
33
#include <bpf/bpf_helpers.h>
44

5+
struct {
6+
__uint(type, BPF_MAP_TYPE_ARRAY);
7+
__uint(max_entries, 1);
8+
__uint(key_size, sizeof(__u32));
9+
__uint(value_size, sizeof(__u32));
10+
} nop_table SEC(".maps");
11+
512
struct {
613
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
714
__uint(max_entries, 3);
@@ -10,10 +17,21 @@ struct {
1017
} jmp_table SEC(".maps");
1118

1219
int count = 0;
20+
int noise = 0;
21+
22+
__always_inline int subprog_noise(void)
23+
{
24+
__u32 key = 0;
25+
26+
bpf_map_lookup_elem(&nop_table, &key);
27+
return 0;
28+
}
1329

1430
__noinline
1531
int subprog_tail_2(struct __sk_buff *skb)
1632
{
33+
if (noise)
34+
subprog_noise();
1735
bpf_tail_call_static(skb, &jmp_table, 2);
1836
return skb->len * 3;
1937
}

0 commit comments

Comments
 (0)