Hi Joe,

On 09/28/2018 01:26 AM, Joe Stringer wrote:
> Teach the verifier a little bit about a new type of pointer, a
> PTR_TO_SOCKET. This pointer type is accessed from BPF through the
> 'struct bpf_sock' structure.
> 
> Signed-off-by: Joe Stringer <j...@wand.net.nz>
[...]
>       }
> @@ -1726,6 +1755,14 @@ static int check_mem_access(struct bpf_verifier_env 
> *env, int insn_idx, u32 regn
>               err = check_flow_keys_access(env, off, size);
>               if (!err && t == BPF_READ && value_regno >= 0)
>                       mark_reg_unknown(env, regs, value_regno);
> +     } else if (reg->type == PTR_TO_SOCKET) {
> +             if (t == BPF_WRITE) {
> +                     verbose(env, "cannot write into socket\n");
> +                     return -EACCES;
> +             }
> +             err = check_sock_access(env, regno, off, size, t);
> +             if (!err && value_regno >= 0)
> +                     mark_reg_unknown(env, regs, value_regno);

Not an issue today, but this is quite fragile and very easy to miss, if we
allow to enable writes into ptr_to_socket in future e.g. mark or others,
then lifting above will not be enough. E.g. see check_xadd() and friends,
this rejects writes to ctx via f37a8cb84cce ("bpf: reject stores into ctx
via st and xadd") as otherwise this would bypass the context rewriter. So
I think we should add PTR_TO_SOCKET to is_ctx_reg() as well to have a full
guarantee this won't happen.

>       } else {
>               verbose(env, "R%d invalid mem access '%s'\n", regno,
>                       reg_type_str[reg->type]);

Thanks,
Daniel

Reply via email to