aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2018-05-27 07:24:08 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-05-30 06:37:38 -0400
commit170a7e3ea0709eae12c8f944b9f33c54fe80c6c1 (patch)
treee15d4fd9b40404cba75181c70d53f7ad3ef72f22
parent9ce64f192d161acff17c99ceec7d9ce3db9252fa (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.c11
-rw-r--r--kernel/trace/bpf_trace.c2
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 {