bpf: Do not dereference user pointer in bpf_test_finish().
authorDavid Miller <davem@davemloft.net>
Tue, 2 May 2017 15:36:33 +0000 (11:36 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 2 May 2017 15:46:28 +0000 (11:46 -0400)
Instead, pass the kattr in which has a kernel side copy of this
data structure from userspace already.

Fix based upon a suggestion from Alexei Starovoitov.

Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
net/bpf/test_run.c

index 8a6d0a37c30ce42efda89c889a2554640d816abe..f946912c8a8109e7e2f66813a84e2dc8de9b8e63 100644 (file)
@@ -49,10 +49,11 @@ static u32 bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat, u32 *time)
        return ret;
 }
 
-static int bpf_test_finish(union bpf_attr __user *uattr, const void *data,
+static int bpf_test_finish(const union bpf_attr *kattr,
+                          union bpf_attr __user *uattr, const void *data,
                           u32 size, u32 retval, u32 duration)
 {
-       void __user *data_out = u64_to_user_ptr(uattr->test.data_out);
+       void __user *data_out = u64_to_user_ptr(kattr->test.data_out);
        int err = -EFAULT;
 
        if (data_out && copy_to_user(data_out, data, size))
@@ -140,7 +141,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
        /* bpf program can never convert linear skb to non-linear */
        if (WARN_ON_ONCE(skb_is_nonlinear(skb)))
                size = skb_headlen(skb);
-       ret = bpf_test_finish(uattr, skb->data, size, retval, duration);
+       ret = bpf_test_finish(kattr, uattr, skb->data, size, retval, duration);
        kfree_skb(skb);
        return ret;
 }
@@ -166,7 +167,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
        retval = bpf_test_run(prog, &xdp, repeat, &duration);
        if (xdp.data != data + XDP_PACKET_HEADROOM)
                size = xdp.data_end - xdp.data;
-       ret = bpf_test_finish(uattr, xdp.data, size, retval, duration);
+       ret = bpf_test_finish(kattr, uattr, xdp.data, size, retval, duration);
        kfree(data);
        return ret;
 }