bpf: enforce TCP only support for sockmap
authorJohn Fastabend <john.fastabend@gmail.com>
Wed, 18 Oct 2017 14:10:15 +0000 (07:10 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Oct 2017 12:01:29 +0000 (13:01 +0100)
Only TCP sockets have been tested and at the moment the state change
callback only handles TCP sockets. This adds a check to ensure that
sockets actually being added are TCP sockets.

For net-next we can consider UDP support.

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>
kernel/bpf/sockmap.c
tools/testing/selftests/bpf/test_maps.c

index 6424ce0e49698abee1da6242a0a8494d8ba0f03f..c68899d5b246360d32c4863228fba84d67863c18 100644 (file)
@@ -840,6 +840,12 @@ static int sock_map_update_elem(struct bpf_map *map,
                return -EINVAL;
        }
 
+       if (skops.sk->sk_type != SOCK_STREAM ||
+           skops.sk->sk_protocol != IPPROTO_TCP) {
+               fput(socket->file);
+               return -EOPNOTSUPP;
+       }
+
        err = sock_map_ctx_update_elem(&skops, map, key, flags);
        fput(socket->file);
        return err;
index fe3a443a110228efb99bc893d2f0820cd03e6763..50ce52d2013d6feddadcb6a2f61cdc4667b3d78d 100644 (file)
@@ -466,7 +466,7 @@ static void test_sockmap(int tasks, void *data)
        int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc;
        struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break;
        int ports[] = {50200, 50201, 50202, 50204};
-       int err, i, fd, sfd[6] = {0xdeadbeef};
+       int err, i, fd, udp, sfd[6] = {0xdeadbeef};
        u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
        int parse_prog, verdict_prog;
        struct sockaddr_in addr;
@@ -548,6 +548,16 @@ static void test_sockmap(int tasks, void *data)
                goto out_sockmap;
        }
 
+       /* Test update with unsupported UDP socket */
+       udp = socket(AF_INET, SOCK_DGRAM, 0);
+       i = 0;
+       err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY);
+       if (!err) {
+               printf("Failed socket SOCK_DGRAM allowed '%i:%i'\n",
+                      i, udp);
+               goto out_sockmap;
+       }
+
        /* Test update without programs */
        for (i = 0; i < 6; i++) {
                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);