bpf: make sure to clear unused fields in tunnel/xfrm state fetch
authorDaniel Borkmann <daniel@iogearbox.net>
Sat, 2 Jun 2018 21:06:37 +0000 (23:06 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Sun, 3 Jun 2018 14:46:55 +0000 (07:46 -0700)
Since the remaining bits are not filled in struct bpf_tunnel_key
resp. struct bpf_xfrm_state and originate from uninitialized stack
space, we should make sure to clear them before handing control
back to the program.

Also add a padding element to struct bpf_xfrm_state for future use
similar as we have in struct bpf_tunnel_key and clear it as well.

  struct bpf_xfrm_state {
      __u32                      reqid;            /*     0     4 */
      __u32                      spi;              /*     4     4 */
      __u16                      family;           /*     8     2 */

      /* XXX 2 bytes hole, try to pack */

      union {
          __u32              remote_ipv4;          /*           4 */
          __u32              remote_ipv6[4];       /*          16 */
      };                                           /*    12    16 */

      /* size: 28, cachelines: 1, members: 4 */
      /* sum members: 26, holes: 1, sum holes: 2 */
      /* last cacheline: 28 bytes */
  };

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
include/uapi/linux/bpf.h
net/core/filter.c

index 6613181..f0b6608 100644 (file)
@@ -2268,7 +2268,7 @@ struct bpf_tunnel_key {
        };
        __u8 tunnel_tos;
        __u8 tunnel_ttl;
-       __u16 tunnel_ext;
+       __u16 tunnel_ext;       /* Padding, future use. */
        __u32 tunnel_label;
 };
 
@@ -2279,6 +2279,7 @@ struct bpf_xfrm_state {
        __u32 reqid;
        __u32 spi;      /* Stored in network byte order */
        __u16 family;
+       __u16 ext;      /* Padding, future use. */
        union {
                __u32 remote_ipv4;      /* Stored in network byte order */
                __u32 remote_ipv6[4];   /* Stored in network byte order */
index edbfaa6..28e8647 100644 (file)
@@ -3445,6 +3445,7 @@ set_compat:
        to->tunnel_id = be64_to_cpu(info->key.tun_id);
        to->tunnel_tos = info->key.tos;
        to->tunnel_ttl = info->key.ttl;
+       to->tunnel_ext = 0;
 
        if (flags & BPF_F_TUNINFO_IPV6) {
                memcpy(to->remote_ipv6, &info->key.u.ipv6.src,
@@ -3452,6 +3453,8 @@ set_compat:
                to->tunnel_label = be32_to_cpu(info->key.label);
        } else {
                to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src);
+               memset(&to->remote_ipv6[1], 0, sizeof(__u32) * 3);
+               to->tunnel_label = 0;
        }
 
        if (unlikely(size != sizeof(struct bpf_tunnel_key)))
@@ -4047,11 +4050,14 @@ BPF_CALL_5(bpf_skb_get_xfrm_state, struct sk_buff *, skb, u32, index,
        to->reqid = x->props.reqid;
        to->spi = x->id.spi;
        to->family = x->props.family;
+       to->ext = 0;
+
        if (to->family == AF_INET6) {
                memcpy(to->remote_ipv6, x->props.saddr.a6,
                       sizeof(to->remote_ipv6));
        } else {
                to->remote_ipv4 = x->props.saddr.a4;
+               memset(&to->remote_ipv6[1], 0, sizeof(__u32) * 3);
        }
 
        return 0;