Commit 7fc4eec2 authored by Peilin Ye's avatar Peilin Ye Committed by Greg Kroah-Hartman

openvswitch: Prevent kernel-infoleak in ovs_ct_put_key()

[ Upstream commit 9aba6c5b ]

ovs_ct_put_key() is potentially copying uninitialized kernel stack memory
into socket buffers, since the compiler may leave a 3-byte hole at the end
of `struct ovs_key_ct_tuple_ipv4` and `struct ovs_key_ct_tuple_ipv6`. Fix
it by initializing `orig` with memset().

Fixes: 9dd7f890 ("openvswitch: Add original direction conntrack tuple to sw_flow_key.")
Suggested-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarPeilin Ye <yepeilin.cs@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 55589dfa
...@@ -283,10 +283,6 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key) ...@@ -283,10 +283,6 @@ void ovs_ct_fill_key(const struct sk_buff *skb, struct sw_flow_key *key)
ovs_ct_update_key(skb, NULL, key, false, false); ovs_ct_update_key(skb, NULL, key, false, false);
} }
#define IN6_ADDR_INITIALIZER(ADDR) \
{ (ADDR).s6_addr32[0], (ADDR).s6_addr32[1], \
(ADDR).s6_addr32[2], (ADDR).s6_addr32[3] }
int ovs_ct_put_key(const struct sw_flow_key *swkey, int ovs_ct_put_key(const struct sw_flow_key *swkey,
const struct sw_flow_key *output, struct sk_buff *skb) const struct sw_flow_key *output, struct sk_buff *skb)
{ {
...@@ -308,24 +304,30 @@ int ovs_ct_put_key(const struct sw_flow_key *swkey, ...@@ -308,24 +304,30 @@ int ovs_ct_put_key(const struct sw_flow_key *swkey,
if (swkey->ct_orig_proto) { if (swkey->ct_orig_proto) {
if (swkey->eth.type == htons(ETH_P_IP)) { if (swkey->eth.type == htons(ETH_P_IP)) {
struct ovs_key_ct_tuple_ipv4 orig = { struct ovs_key_ct_tuple_ipv4 orig;
output->ipv4.ct_orig.src,
output->ipv4.ct_orig.dst, memset(&orig, 0, sizeof(orig));
output->ct.orig_tp.src, orig.ipv4_src = output->ipv4.ct_orig.src;
output->ct.orig_tp.dst, orig.ipv4_dst = output->ipv4.ct_orig.dst;
output->ct_orig_proto, orig.src_port = output->ct.orig_tp.src;
}; orig.dst_port = output->ct.orig_tp.dst;
orig.ipv4_proto = output->ct_orig_proto;
if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
sizeof(orig), &orig)) sizeof(orig), &orig))
return -EMSGSIZE; return -EMSGSIZE;
} else if (swkey->eth.type == htons(ETH_P_IPV6)) { } else if (swkey->eth.type == htons(ETH_P_IPV6)) {
struct ovs_key_ct_tuple_ipv6 orig = { struct ovs_key_ct_tuple_ipv6 orig;
IN6_ADDR_INITIALIZER(output->ipv6.ct_orig.src),
IN6_ADDR_INITIALIZER(output->ipv6.ct_orig.dst), memset(&orig, 0, sizeof(orig));
output->ct.orig_tp.src, memcpy(orig.ipv6_src, output->ipv6.ct_orig.src.s6_addr32,
output->ct.orig_tp.dst, sizeof(orig.ipv6_src));
output->ct_orig_proto, memcpy(orig.ipv6_dst, output->ipv6.ct_orig.dst.s6_addr32,
}; sizeof(orig.ipv6_dst));
orig.src_port = output->ct.orig_tp.src;
orig.dst_port = output->ct.orig_tp.dst;
orig.ipv6_proto = output->ct_orig_proto;
if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, if (nla_put(skb, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6,
sizeof(orig), &orig)) sizeof(orig), &orig))
return -EMSGSIZE; return -EMSGSIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment