aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-06-02 17:06:37 -0400
committerAlexei Starovoitov <ast@kernel.org>2018-06-03 10:46:55 -0400
commit1fbc2e0cfcf9677683aea2b1f9ea76fbdc6fb6d1 (patch)
tree6e59f51bb75c719968536dabb35e6ababf68bff8
parentcb20b08ead401fd17627a36f035c0bf5bfee5567 (diff)
bpf: make sure to clear unused fields in tunnel/xfrm state fetch
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>
-rw-r--r--include/uapi/linux/bpf.h3
-rw-r--r--net/core/filter.c6
2 files changed, 8 insertions, 1 deletions
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 661318141f72..f0b6608b1f1c 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2268,7 +2268,7 @@ struct bpf_tunnel_key {
2268 }; 2268 };
2269 __u8 tunnel_tos; 2269 __u8 tunnel_tos;
2270 __u8 tunnel_ttl; 2270 __u8 tunnel_ttl;
2271 __u16 tunnel_ext; 2271 __u16 tunnel_ext; /* Padding, future use. */
2272 __u32 tunnel_label; 2272 __u32 tunnel_label;
2273}; 2273};
2274 2274
@@ -2279,6 +2279,7 @@ struct bpf_xfrm_state {
2279 __u32 reqid; 2279 __u32 reqid;
2280 __u32 spi; /* Stored in network byte order */ 2280 __u32 spi; /* Stored in network byte order */
2281 __u16 family; 2281 __u16 family;
2282 __u16 ext; /* Padding, future use. */
2282 union { 2283 union {
2283 __u32 remote_ipv4; /* Stored in network byte order */ 2284 __u32 remote_ipv4; /* Stored in network byte order */
2284 __u32 remote_ipv6[4]; /* Stored in network byte order */ 2285 __u32 remote_ipv6[4]; /* Stored in network byte order */
diff --git a/net/core/filter.c b/net/core/filter.c
index edbfaa613b6d..28e864777c0f 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3445,6 +3445,7 @@ set_compat:
3445 to->tunnel_id = be64_to_cpu(info->key.tun_id); 3445 to->tunnel_id = be64_to_cpu(info->key.tun_id);
3446 to->tunnel_tos = info->key.tos; 3446 to->tunnel_tos = info->key.tos;
3447 to->tunnel_ttl = info->key.ttl; 3447 to->tunnel_ttl = info->key.ttl;
3448 to->tunnel_ext = 0;
3448 3449
3449 if (flags & BPF_F_TUNINFO_IPV6) { 3450 if (flags & BPF_F_TUNINFO_IPV6) {
3450 memcpy(to->remote_ipv6, &info->key.u.ipv6.src, 3451 memcpy(to->remote_ipv6, &info->key.u.ipv6.src,
@@ -3452,6 +3453,8 @@ set_compat:
3452 to->tunnel_label = be32_to_cpu(info->key.label); 3453 to->tunnel_label = be32_to_cpu(info->key.label);
3453 } else { 3454 } else {
3454 to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src); 3455 to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src);
3456 memset(&to->remote_ipv6[1], 0, sizeof(__u32) * 3);
3457 to->tunnel_label = 0;
3455 } 3458 }
3456 3459
3457 if (unlikely(size != sizeof(struct bpf_tunnel_key))) 3460 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,
4047 to->reqid = x->props.reqid; 4050 to->reqid = x->props.reqid;
4048 to->spi = x->id.spi; 4051 to->spi = x->id.spi;
4049 to->family = x->props.family; 4052 to->family = x->props.family;
4053 to->ext = 0;
4054
4050 if (to->family == AF_INET6) { 4055 if (to->family == AF_INET6) {
4051 memcpy(to->remote_ipv6, x->props.saddr.a6, 4056 memcpy(to->remote_ipv6, x->props.saddr.a6,
4052 sizeof(to->remote_ipv6)); 4057 sizeof(to->remote_ipv6));
4053 } else { 4058 } else {
4054 to->remote_ipv4 = x->props.saddr.a4; 4059 to->remote_ipv4 = x->props.saddr.a4;
4060 memset(&to->remote_ipv6[1], 0, sizeof(__u32) * 3);
4055 } 4061 }
4056 4062
4057 return 0; 4063 return 0;