aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Schichan <nschichan@freebox.fr>2015-05-06 10:12:27 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-09 17:35:05 -0400
commit4ae92bc77ac8e620f7c8d59b5882a4cb0d1c4ef1 (patch)
treed8a3a893390631cfaf0547929b8b89c715501b08
parent0e00a0f73f9c7f5e9f02d064ed0165a3aeeb2de5 (diff)
net: filter: add a callback to allow classic post-verifier transformations
This is in preparation for use by the seccomp code, the rationale is not to duplicate additional code within the seccomp layer, but instead, have it abstracted and hidden within the classic BPF API. As an interim step, this now also makes bpf_prepare_filter() visible (not as exported symbol though), so that seccomp can reuse that code path instead of reimplementing it. Joint work with Daniel Borkmann. Signed-off-by: Nicolas Schichan <nschichan@freebox.fr> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@plumgrid.com> Cc: Kees Cook <keescook@chromium.org> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/filter.h6
-rw-r--r--net/core/filter.c18
2 files changed, 21 insertions, 3 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index fa11b3a367be..91996247cb55 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -384,7 +384,13 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
384int sk_attach_bpf(u32 ufd, struct sock *sk); 384int sk_attach_bpf(u32 ufd, struct sock *sk);
385int sk_detach_filter(struct sock *sk); 385int sk_detach_filter(struct sock *sk);
386 386
387typedef int (*bpf_aux_classic_check_t)(struct sock_filter *filter,
388 unsigned int flen);
389
387int bpf_check_classic(const struct sock_filter *filter, unsigned int flen); 390int bpf_check_classic(const struct sock_filter *filter, unsigned int flen);
391struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
392 bpf_aux_classic_check_t trans);
393
388int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, 394int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
389 unsigned int len); 395 unsigned int len);
390 396
diff --git a/net/core/filter.c b/net/core/filter.c
index bf831a85c315..e670494f1d83 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -988,7 +988,8 @@ out_err:
988 return ERR_PTR(err); 988 return ERR_PTR(err);
989} 989}
990 990
991static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp) 991struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
992 bpf_aux_classic_check_t trans)
992{ 993{
993 int err; 994 int err;
994 995
@@ -1001,6 +1002,17 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
1001 return ERR_PTR(err); 1002 return ERR_PTR(err);
1002 } 1003 }
1003 1004
1005 /* There might be additional checks and transformations
1006 * needed on classic filters, f.e. in case of seccomp.
1007 */
1008 if (trans) {
1009 err = trans(fp->insns, fp->len);
1010 if (err) {
1011 __bpf_prog_release(fp);
1012 return ERR_PTR(err);
1013 }
1014 }
1015
1004 /* Probe if we can JIT compile the filter and if so, do 1016 /* Probe if we can JIT compile the filter and if so, do
1005 * the compilation of the filter. 1017 * the compilation of the filter.
1006 */ 1018 */
@@ -1050,7 +1062,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
1050 /* bpf_prepare_filter() already takes care of freeing 1062 /* bpf_prepare_filter() already takes care of freeing
1051 * memory in case something goes wrong. 1063 * memory in case something goes wrong.
1052 */ 1064 */
1053 fp = bpf_prepare_filter(fp); 1065 fp = bpf_prepare_filter(fp, NULL);
1054 if (IS_ERR(fp)) 1066 if (IS_ERR(fp))
1055 return PTR_ERR(fp); 1067 return PTR_ERR(fp);
1056 1068
@@ -1135,7 +1147,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
1135 /* bpf_prepare_filter() already takes care of freeing 1147 /* bpf_prepare_filter() already takes care of freeing
1136 * memory in case something goes wrong. 1148 * memory in case something goes wrong.
1137 */ 1149 */
1138 prog = bpf_prepare_filter(prog); 1150 prog = bpf_prepare_filter(prog, NULL);
1139 if (IS_ERR(prog)) 1151 if (IS_ERR(prog))
1140 return PTR_ERR(prog); 1152 return PTR_ERR(prog);
1141 1153