diff options
| author | Sean Young <sean@mess.org> | 2018-05-27 07:24:08 -0400 |
|---|---|---|
| committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-05-30 06:37:38 -0400 |
| commit | 170a7e3ea0709eae12c8f944b9f33c54fe80c6c1 (patch) | |
| tree | e15d4fd9b40404cba75181c70d53f7ad3ef72f22 /kernel | |
| parent | 9ce64f192d161acff17c99ceec7d9ce3db9252fa (diff) | |
bpf: bpf_prog_array_copy() should return -ENOENT if exclude_prog not found
This makes is it possible for bpf prog detach to return -ENOENT.
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/core.c | 11 | ||||
| -rw-r--r-- | kernel/trace/bpf_trace.c | 2 |
2 files changed, 11 insertions, 2 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index b574dddc05b8..527587de8a67 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
| @@ -1616,6 +1616,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, | |||
| 1616 | int new_prog_cnt, carry_prog_cnt = 0; | 1616 | int new_prog_cnt, carry_prog_cnt = 0; |
| 1617 | struct bpf_prog **existing_prog; | 1617 | struct bpf_prog **existing_prog; |
| 1618 | struct bpf_prog_array *array; | 1618 | struct bpf_prog_array *array; |
| 1619 | bool found_exclude = false; | ||
| 1619 | int new_prog_idx = 0; | 1620 | int new_prog_idx = 0; |
| 1620 | 1621 | ||
| 1621 | /* Figure out how many existing progs we need to carry over to | 1622 | /* Figure out how many existing progs we need to carry over to |
| @@ -1624,14 +1625,20 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, | |||
| 1624 | if (old_array) { | 1625 | if (old_array) { |
| 1625 | existing_prog = old_array->progs; | 1626 | existing_prog = old_array->progs; |
| 1626 | for (; *existing_prog; existing_prog++) { | 1627 | for (; *existing_prog; existing_prog++) { |
| 1627 | if (*existing_prog != exclude_prog && | 1628 | if (*existing_prog == exclude_prog) { |
| 1628 | *existing_prog != &dummy_bpf_prog.prog) | 1629 | found_exclude = true; |
| 1630 | continue; | ||
| 1631 | } | ||
| 1632 | if (*existing_prog != &dummy_bpf_prog.prog) | ||
| 1629 | carry_prog_cnt++; | 1633 | carry_prog_cnt++; |
| 1630 | if (*existing_prog == include_prog) | 1634 | if (*existing_prog == include_prog) |
| 1631 | return -EEXIST; | 1635 | return -EEXIST; |
| 1632 | } | 1636 | } |
| 1633 | } | 1637 | } |
| 1634 | 1638 | ||
| 1639 | if (exclude_prog && !found_exclude) | ||
| 1640 | return -ENOENT; | ||
| 1641 | |||
| 1635 | /* How many progs (not NULL) will be in the new array? */ | 1642 | /* How many progs (not NULL) will be in the new array? */ |
| 1636 | new_prog_cnt = carry_prog_cnt; | 1643 | new_prog_cnt = carry_prog_cnt; |
| 1637 | if (include_prog) | 1644 | if (include_prog) |
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 81fdf2fc94ac..af1486d9a0ed 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c | |||
| @@ -1006,6 +1006,8 @@ void perf_event_detach_bpf_prog(struct perf_event *event) | |||
| 1006 | 1006 | ||
| 1007 | old_array = event->tp_event->prog_array; | 1007 | old_array = event->tp_event->prog_array; |
| 1008 | ret = bpf_prog_array_copy(old_array, event->prog, NULL, &new_array); | 1008 | ret = bpf_prog_array_copy(old_array, event->prog, NULL, &new_array); |
| 1009 | if (ret == -ENOENT) | ||
| 1010 | goto unlock; | ||
| 1009 | if (ret < 0) { | 1011 | if (ret < 0) { |
| 1010 | bpf_prog_array_delete_safe(old_array, event->prog); | 1012 | bpf_prog_array_delete_safe(old_array, event->prog); |
| 1011 | } else { | 1013 | } else { |
