aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-11-09 09:16:32 +0100
committerDaniel Borkmann <daniel@iogearbox.net>2018-11-09 09:16:33 +0100
commit185067a86a789e490ab4e1bb97b97fb3e2c40066 (patch)
treed89f4a220e92ba787649adc101d2e7861791539d /kernel
parentbpf_load: add map name to load_maps error message (diff)
parentnfp: bpf: relax prog rejection through max_pkt_offset (diff)
Merge branch 'bpf-max-pkt-offset'
Jiong Wang says: ==================== The maximum packet offset accessed by one BPF program is useful information. Because sometimes there could be packet split and it is possible for some reasons (for example performance) we want to reject the BPF program if the maximum packet size would trigger such split. Normally, MTU value is treated as the maximum packet size, but one BPF program does not always access the whole packet, it could only access the head portion of the data. We could let verifier calculate the maximum packet offset ever used and record it inside prog auxiliar information structure as a new field "max_pkt_offset". ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/verifier.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1971ca325fb4..75dab40b19a3 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1455,6 +1455,17 @@ static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off,
verbose(env, "R%d offset is outside of the packet\n", regno);
return err;
}
+
+ /* __check_packet_access has made sure "off + size - 1" is within u16.
+ * reg->umax_value can't be bigger than MAX_PACKET_OFF which is 0xffff,
+ * otherwise find_good_pkt_pointers would have refused to set range info
+ * that __check_packet_access would have rejected this pkt access.
+ * Therefore, "off + reg->umax_value + size - 1" won't overflow u32.
+ */
+ env->prog->aux->max_pkt_offset =
+ max_t(u32, env->prog->aux->max_pkt_offset,
+ off + reg->umax_value + size - 1);
+
return err;
}
@@ -6138,6 +6149,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
*/
prog->cb_access = 1;
env->prog->aux->stack_depth = MAX_BPF_STACK;
+ env->prog->aux->max_pkt_offset = MAX_PACKET_OFF;
/* mark bpf_tail_call as different opcode to avoid
* conditional branch in the interpeter for every normal