Commit 4ae92bc7 authored by Nicolas Schichan's avatar Nicolas Schichan Committed by David S. Miller

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: default avatarNicolas Schichan <nschichan@freebox.fr>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Kees Cook <keescook@chromium.org>
Acked-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0e00a0f7
...@@ -384,7 +384,13 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); ...@@ -384,7 +384,13 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
int sk_attach_bpf(u32 ufd, struct sock *sk); int sk_attach_bpf(u32 ufd, struct sock *sk);
int sk_detach_filter(struct sock *sk); int sk_detach_filter(struct sock *sk);
typedef int (*bpf_aux_classic_check_t)(struct sock_filter *filter,
unsigned int flen);
int bpf_check_classic(const struct sock_filter *filter, unsigned int flen); int bpf_check_classic(const struct sock_filter *filter, unsigned int flen);
struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
bpf_aux_classic_check_t trans);
int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
unsigned int len); unsigned int len);
......
...@@ -988,7 +988,8 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp) ...@@ -988,7 +988,8 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp)
return ERR_PTR(err); return ERR_PTR(err);
} }
static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp) struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp,
bpf_aux_classic_check_t trans)
{ {
int err; int err;
...@@ -1001,6 +1002,17 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp) ...@@ -1001,6 +1002,17 @@ static struct bpf_prog *bpf_prepare_filter(struct bpf_prog *fp)
return ERR_PTR(err); return ERR_PTR(err);
} }
/* There might be additional checks and transformations
* needed on classic filters, f.e. in case of seccomp.
*/
if (trans) {
err = trans(fp->insns, fp->len);
if (err) {
__bpf_prog_release(fp);
return ERR_PTR(err);
}
}
/* Probe if we can JIT compile the filter and if so, do /* Probe if we can JIT compile the filter and if so, do
* the compilation of the filter. * the compilation of the filter.
*/ */
...@@ -1050,7 +1062,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog) ...@@ -1050,7 +1062,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
/* bpf_prepare_filter() already takes care of freeing /* bpf_prepare_filter() already takes care of freeing
* memory in case something goes wrong. * memory in case something goes wrong.
*/ */
fp = bpf_prepare_filter(fp); fp = bpf_prepare_filter(fp, NULL);
if (IS_ERR(fp)) if (IS_ERR(fp))
return PTR_ERR(fp); return PTR_ERR(fp);
...@@ -1135,7 +1147,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) ...@@ -1135,7 +1147,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
/* bpf_prepare_filter() already takes care of freeing /* bpf_prepare_filter() already takes care of freeing
* memory in case something goes wrong. * memory in case something goes wrong.
*/ */
prog = bpf_prepare_filter(prog); prog = bpf_prepare_filter(prog, NULL);
if (IS_ERR(prog)) if (IS_ERR(prog))
return PTR_ERR(prog); return PTR_ERR(prog);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment