On 05/10/2017 09:09 PM, David Miller wrote:
Add a new field, "prog_flags", and an initial flag value
BPF_F_STRCIT_ALIGNMENT.
When set, the verifier will enforce strict pointer alignment
regardless of the setting of CONFIG_EFFICIENT_UNALIGNED_ACCESS.
The verifier, in this mode, will also use a fixed value of "2" in
place of NET_IP_ALIGN.
This facilitates test cases that will exercise and validate this part
of the verifier even when run on architectures where alignment doesn't
matter.
Signed-off-by: David S. Miller <[email protected]>
[...]
@@ -833,10 +838,12 @@ static int check_val_ptr_alignment(const struct
bpf_reg_state *reg,
return 0;
}
+static bool strict_alignment;
+
static int check_ptr_alignment(const struct bpf_reg_state *reg,
int off, int size)
{
- bool strict = false;
+ bool strict = strict_alignment;
if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
strict = true;
@@ -3574,6 +3581,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr
*attr)
} else {
log_level = 0;
}
+ if (attr->prog_flags & BPF_F_STRICT_ALIGNMENT)
+ strict_alignment = true;
+ else
+ strict_alignment = false;
Just minor nit: Can we move this into struct bpf_verifier_env
here instead of global var? The only change it would need is
in check_ptr_alignment() to pass the env from check_mem_access().
check_ptr_alignment() can then infer this from env.
ret = replace_map_fd_with_map_ptr(env);
if (ret < 0)
@@ -3679,6 +3690,7 @@ int bpf_analyzer(struct bpf_prog *prog, const struct
bpf_ext_analyzer_ops *ops,
mutex_lock(&bpf_verifier_lock);
log_level = 0;
+ strict_alignment = false;
env->explored_states = kcalloc(env->prog->len,
sizeof(struct bpf_verifier_state_list *),
Rest looks good:
Acked-by: Daniel Borkmann <[email protected]>