diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 5d141f16f6fa..272071e9112f 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -1707,20 +1707,26 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr) | |||
1707 | if (err) | 1707 | if (err) |
1708 | goto free_used_maps; | 1708 | goto free_used_maps; |
1709 | 1709 | ||
1710 | err = bpf_prog_new_fd(prog); | 1710 | /* Upon success of bpf_prog_alloc_id(), the BPF prog is |
1711 | if (err < 0) { | 1711 | * effectively publicly exposed. However, retrieving via |
1712 | /* failed to allocate fd. | 1712 | * bpf_prog_get_fd_by_id() will take another reference, |
1713 | * bpf_prog_put() is needed because the above | 1713 | * therefore it cannot be gone underneath us. |
1714 | * bpf_prog_alloc_id() has published the prog | 1714 | * |
1715 | * to the userspace and the userspace may | 1715 | * Only for the time /after/ successful bpf_prog_new_fd() |
1716 | * have refcnt-ed it through BPF_PROG_GET_FD_BY_ID. | 1716 | * and before returning to userspace, we might just hold |
1717 | */ | 1717 | * one reference and any parallel close on that fd could |
1718 | bpf_prog_put(prog); | 1718 | * rip everything out. Hence, below notifications must |
1719 | return err; | 1719 | * happen before bpf_prog_new_fd(). |
1720 | } | 1720 | * |
1721 | 1721 | * Also, any failure handling from this point onwards must | |
1722 | * be using bpf_prog_put() given the program is exposed. | ||
1723 | */ | ||
1722 | bpf_prog_kallsyms_add(prog); | 1724 | bpf_prog_kallsyms_add(prog); |
1723 | perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0); | 1725 | perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0); |
1726 | |||
1727 | err = bpf_prog_new_fd(prog); | ||
1728 | if (err < 0) | ||
1729 | bpf_prog_put(prog); | ||
1724 | return err; | 1730 | return err; |
1725 | 1731 | ||
1726 | free_used_maps: | 1732 | free_used_maps: |