summaryrefslogtreecommitdiffstats
path: root/kernel/bpf
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2015-03-12 12:21:42 -0400
committerDavid S. Miller <davem@davemloft.net>2015-03-12 15:29:31 -0400
commit80f1d68ccba70b1060c9c7360ca83da430f66bed (patch)
tree499ac28f25cf910e1bc14ab8044134d97b575dd9 /kernel/bpf
parent20453d88ccb6eb269787f37181202625fc12ccdc (diff)
ebpf: verifier: check that call reg with ARG_ANYTHING is initialized
I noticed that a helper function with argument type ARG_ANYTHING does not need to have an initialized value (register). This can worst case lead to unintented stack memory leakage in future helper functions if they are not carefully designed, or unintended application behaviour in case the application developer was not careful enough to match a correct helper function signature in the API. The underlying issue is that ARG_ANYTHING should actually be split into two different semantics: 1) ARG_DONTCARE for function arguments that the helper function does not care about (in other words: the default for unused function arguments), and 2) ARG_ANYTHING that is an argument actually being used by a helper function and *guaranteed* to be an initialized register. The current risk is low: ARG_ANYTHING is only used for the 'flags' argument (r4) in bpf_map_update_elem() that internally does strict checking. Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/verifier.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index bdf4192a889b..e6b522496250 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -755,7 +755,7 @@ static int check_func_arg(struct verifier_env *env, u32 regno,
755 enum bpf_reg_type expected_type; 755 enum bpf_reg_type expected_type;
756 int err = 0; 756 int err = 0;
757 757
758 if (arg_type == ARG_ANYTHING) 758 if (arg_type == ARG_DONTCARE)
759 return 0; 759 return 0;
760 760
761 if (reg->type == NOT_INIT) { 761 if (reg->type == NOT_INIT) {
@@ -763,6 +763,9 @@ static int check_func_arg(struct verifier_env *env, u32 regno,
763 return -EACCES; 763 return -EACCES;
764 } 764 }
765 765
766 if (arg_type == ARG_ANYTHING)
767 return 0;
768
766 if (arg_type == ARG_PTR_TO_STACK || arg_type == ARG_PTR_TO_MAP_KEY || 769 if (arg_type == ARG_PTR_TO_STACK || arg_type == ARG_PTR_TO_MAP_KEY ||
767 arg_type == ARG_PTR_TO_MAP_VALUE) { 770 arg_type == ARG_PTR_TO_MAP_VALUE) {
768 expected_type = PTR_TO_STACK; 771 expected_type = PTR_TO_STACK;