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 | |
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>
-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 { |