bpf: remove mark access for SK_SKB program types
authorJohn Fastabend <john.fastabend@gmail.com>
Wed, 18 Oct 2017 14:10:58 +0000 (07:10 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Oct 2017 12:01:29 +0000 (13:01 +0100)
The skb->mark field is a union with reserved_tailroom which is used
in the TCP code paths from stream memory allocation. Allowing SK_SKB
programs to set this field creates a conflict with future code
optimizations, such as "gifting" the skb to the egress path instead
of creating a new skb and doing a memcpy.

Because we do not have a released version of SK_SKB yet lets just
remove it for now. A more appropriate scratch pad to use at the
socket layer is dev_scratch, but lets add that in future kernels
when needed.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/filter.c
tools/testing/selftests/bpf/test_verifier.c

index ca1ba0bbfbc2f9dacf83add0c34fa1134129de76..aa0265997f930c86229ee1658063ba9718c6dc79 100644 (file)
@@ -3684,7 +3684,6 @@ static bool sk_skb_is_valid_access(int off, int size,
 {
        if (type == BPF_WRITE) {
                switch (off) {
-               case bpf_ctx_range(struct __sk_buff, mark):
                case bpf_ctx_range(struct __sk_buff, tc_index):
                case bpf_ctx_range(struct __sk_buff, priority):
                        break;
@@ -3694,6 +3693,7 @@ static bool sk_skb_is_valid_access(int off, int size,
        }
 
        switch (off) {
+       case bpf_ctx_range(struct __sk_buff, mark):
        case bpf_ctx_range(struct __sk_buff, tc_classid):
                return false;
        case bpf_ctx_range(struct __sk_buff, data):
index 3c7d3a45a3c551b291fb715354754504c62ab8c8..50e15cedbb7ffad813cfc737d7618f198357f3c8 100644 (file)
@@ -1130,15 +1130,27 @@ static struct bpf_test tests[] = {
                .errstr = "invalid bpf_context access",
        },
        {
-               "check skb->mark is writeable by SK_SKB",
+               "invalid access of skb->mark for SK_SKB",
+               .insns = {
+                       BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
+                                   offsetof(struct __sk_buff, mark)),
+                       BPF_EXIT_INSN(),
+               },
+               .result =  REJECT,
+               .prog_type = BPF_PROG_TYPE_SK_SKB,
+               .errstr = "invalid bpf_context access",
+       },
+       {
+               "check skb->mark is not writeable by SK_SKB",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
                        BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
                                    offsetof(struct __sk_buff, mark)),
                        BPF_EXIT_INSN(),
                },
-               .result = ACCEPT,
+               .result =  REJECT,
                .prog_type = BPF_PROG_TYPE_SK_SKB,
+               .errstr = "invalid bpf_context access",
        },
        {
                "check skb->tc_index is writeable by SK_SKB",