On Wed, Jan 11, 2017 at 4:23 PM, Konstantin Bukin <notificati...@github.com>
wrote:

> Here is a diff against kernel 4.9.2:
>
> build-test1:linux-4.9.2$git diff
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index c201017..64516be 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -327,6 +327,7 @@ extern const struct bpf_func_proto 
> bpf_get_current_comm_proto;
>  extern const struct bpf_func_proto bpf_skb_vlan_push_proto;
>  extern const struct bpf_func_proto bpf_skb_vlan_pop_proto;
>  extern const struct bpf_func_proto bpf_get_stackid_proto;
> +extern const struct bpf_func_proto bpf_strnlen_proto;
>
>  /* Shared helpers among cBPF and eBPF. */
>  void bpf_user_rnd_init_once(void);
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index f09c70b..38c6400 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -426,6 +426,16 @@ enum bpf_func_id {
>      */
>     BPF_FUNC_set_hash_invalid,
>
> +    /**
> +     * bpf_strnlen(str, size)
> +     * Get the size of a user string INCLUDING final NUL
> +     * @str: The string to measure.
> +     * @count: Maximum count (including NUL character)
> +     *
> +     * see comments for strnlen_user(const char __user *str, long count)
> +     */
> +   BPF_FUNC_strnlen,
> +
>     __BPF_FUNC_MAX_ID,
>  };
>
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index aa6d981..ab04742 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -1048,6 +1048,7 @@ const struct bpf_func_proto bpf_ktime_get_ns_proto 
> __weak;
>  const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
>  const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
>  const struct bpf_func_proto bpf_get_current_comm_proto __weak;
> +const struct bpf_func_proto bpf_strnlen __weak;
>
>  const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
>  {
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 3991840..ec64244 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -120,6 +120,17 @@ const struct bpf_func_proto 
> bpf_get_current_pid_tgid_proto = {
>     .ret_type   = RET_INTEGER,
>  };
>
> +BPF_CALL_2(bpf_strnlen, const char __user *, buf, u32, size)
> +{
> +    return strnlen_user(buf, size);
> +}
>
> unfortunately it's not so straightforward, since
strnlen_user() can only be called on user pointer in user context.
access_ok() macro just recently got
WARN_ON_IN_IRQ() warning to prevent such misuse.

btw, verifier just recently got support for variable length
bpf_probe_read(buf, len, unsafe_ptr)
where 'buf' can be a pointer inside map's value
and 'len' can be capped variable.

I think we need to solve it more generically than
adding strlen/strcpy helpers.

>
> +
> +const struct bpf_func_proto bpf_strnlen_proto = {
> +   .func       = bpf_strnlen,
> +   .gpl_only   = false,
> +   .ret_type   = RET_INTEGER,
> +};
> +
>
>
_______________________________________________
iovisor-dev mailing list
iovisor-dev@lists.iovisor.org
https://lists.iovisor.org/mailman/listinfo/iovisor-dev

Reply via email to