diff options
author | Stanislav Fomichev <sdf@google.com> | 2019-04-01 13:57:33 -0700 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2019-04-03 16:49:48 +0200 |
commit | 2ee7fba0d62d638d8b6dbe30cada3a531ec042af (patch) | |
tree | 885eee23a75ca15ab8336bca87f53edc65fc0836 /net | |
parent | b9e9c8599f0f23e3d2051befc9966a84b639f64f (diff) | |
download | linux-stable-2ee7fba0d62d638d8b6dbe30cada3a531ec042af.tar.gz linux-stable-2ee7fba0d62d638d8b6dbe30cada3a531ec042af.tar.bz2 linux-stable-2ee7fba0d62d638d8b6dbe30cada3a531ec042af.zip |
flow_dissector: allow access only to a subset of __sk_buff fields
Use whitelist instead of a blacklist and allow only a small set of
fields that might be relevant in the context of flow dissector:
* data
* data_end
* flow_keys
This is required for the eth_get_headlen case where we have only a
chunk of data to dissect (i.e. trying to read the other skb fields
doesn't make sense).
Note, that it is a breaking API change! However, we've provided
flow_keys->n_proto as a substitute for skb->protocol; and there is
no need to manually handle skb->vlan_present. So even if we
break somebody, the migration is trivial. Unfortunately, we can't
support eth_get_headlen use-case without those breaking changes.
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/filter.c | 16 |
1 files changed, 3 insertions, 13 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 647c63a7b25b..fc92ebc4e200 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6613,14 +6613,8 @@ static bool flow_dissector_is_valid_access(int off, int size, const struct bpf_prog *prog, struct bpf_insn_access_aux *info) { - if (type == BPF_WRITE) { - switch (off) { - case bpf_ctx_range_till(struct __sk_buff, cb[0], cb[4]): - break; - default: - return false; - } - } + if (type == BPF_WRITE) + return false; switch (off) { case bpf_ctx_range(struct __sk_buff, data): @@ -6632,11 +6626,7 @@ static bool flow_dissector_is_valid_access(int off, int size, case bpf_ctx_range_ptr(struct __sk_buff, flow_keys): info->reg_type = PTR_TO_FLOW_KEYS; break; - case bpf_ctx_range(struct __sk_buff, tc_classid): - case bpf_ctx_range(struct __sk_buff, data_meta): - case bpf_ctx_range_till(struct __sk_buff, family, local_port): - case bpf_ctx_range(struct __sk_buff, tstamp): - case bpf_ctx_range(struct __sk_buff, wire_len): + default: return false; } |