mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 00:51:35 +00:00
net: filter: keep original BPF program around
In order to open up the possibility to internally transform a BPF program
into an alternative and possibly non-trivial reversible representation, we
need to keep the original BPF program around, so that it can be passed back
to user space w/o the need of a complex decoder.
The reason for that use case resides in commit a8fc927780
("sk-filter:
Add ability to get socket filter program (v2)"), that is, the ability
to retrieve the currently attached BPF filter from a given socket used
mainly by the checkpoint-restore project, for example.
Therefore, we add two helpers sk_{store,release}_orig_filter for taking
care of that. In the sk_unattached_filter_create() case, there's no such
possibility/requirement to retrieve a loaded BPF program. Therefore, we
can spare us the work in that case.
This approach will simplify and slightly speed up both, sk_get_filter()
and sock_diag_put_filterinfo() handlers as we won't need to successively
decode filters anymore through sk_decode_filter(). As we still need
sk_decode_filter() later on, we're keeping it around.
Joint work with Alexei Starovoitov.
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f8bbbfc3b9
commit
a3ea269b8b
3 changed files with 93 additions and 31 deletions
|
@ -52,9 +52,10 @@ EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
|
|||
int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
|
||||
struct sk_buff *skb, int attrtype)
|
||||
{
|
||||
struct nlattr *attr;
|
||||
struct sock_fprog_kern *fprog;
|
||||
struct sk_filter *filter;
|
||||
unsigned int len;
|
||||
struct nlattr *attr;
|
||||
unsigned int flen;
|
||||
int err = 0;
|
||||
|
||||
if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
|
||||
|
@ -63,24 +64,20 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
|
|||
}
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
filter = rcu_dereference(sk->sk_filter);
|
||||
len = filter ? filter->len * sizeof(struct sock_filter) : 0;
|
||||
if (!filter)
|
||||
goto out;
|
||||
|
||||
attr = nla_reserve(skb, attrtype, len);
|
||||
fprog = filter->orig_prog;
|
||||
flen = sk_filter_proglen(fprog);
|
||||
|
||||
attr = nla_reserve(skb, attrtype, flen);
|
||||
if (attr == NULL) {
|
||||
err = -EMSGSIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
struct sock_filter *fb = (struct sock_filter *)nla_data(attr);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < filter->len; i++, fb++)
|
||||
sk_decode_filter(&filter->insns[i], fb);
|
||||
}
|
||||
|
||||
memcpy(nla_data(attr), fprog->filter, flen);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue