Commit 0ab1fa1c authored by David S. Miller's avatar David S. Miller

Merge branch 'fragment-stack-oob-read'

Davide Caratti says:

====================
fix stack OOB read while fragmenting IPv4 packets

- patch 1/2 fixes openvswitch IPv4 fragmentation, that does a stack OOB
read after commit d52e5a7e ("ipv4: lock mtu in fnhe when received
PMTU < net.ipv4.route.min_pmt")
- patch 2/2 fixes the same issue in TC 'sch_frag' code
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 94604548 31fe34a0
...@@ -827,17 +827,17 @@ static void ovs_fragment(struct net *net, struct vport *vport, ...@@ -827,17 +827,17 @@ static void ovs_fragment(struct net *net, struct vport *vport,
} }
if (key->eth.type == htons(ETH_P_IP)) { if (key->eth.type == htons(ETH_P_IP)) {
struct dst_entry ovs_dst; struct rtable ovs_rt = { 0 };
unsigned long orig_dst; unsigned long orig_dst;
prepare_frag(vport, skb, orig_network_offset, prepare_frag(vport, skb, orig_network_offset,
ovs_key_mac_proto(key)); ovs_key_mac_proto(key));
dst_init(&ovs_dst, &ovs_dst_ops, NULL, 1, dst_init(&ovs_rt.dst, &ovs_dst_ops, NULL, 1,
DST_OBSOLETE_NONE, DST_NOCOUNT); DST_OBSOLETE_NONE, DST_NOCOUNT);
ovs_dst.dev = vport->dev; ovs_rt.dst.dev = vport->dev;
orig_dst = skb->_skb_refdst; orig_dst = skb->_skb_refdst;
skb_dst_set_noref(skb, &ovs_dst); skb_dst_set_noref(skb, &ovs_rt.dst);
IPCB(skb)->frag_max_size = mru; IPCB(skb)->frag_max_size = mru;
ip_do_fragment(net, skb->sk, skb, ovs_vport_output); ip_do_fragment(net, skb->sk, skb, ovs_vport_output);
......
...@@ -90,16 +90,16 @@ static int sch_fragment(struct net *net, struct sk_buff *skb, ...@@ -90,16 +90,16 @@ static int sch_fragment(struct net *net, struct sk_buff *skb,
} }
if (skb_protocol(skb, true) == htons(ETH_P_IP)) { if (skb_protocol(skb, true) == htons(ETH_P_IP)) {
struct dst_entry sch_frag_dst; struct rtable sch_frag_rt = { 0 };
unsigned long orig_dst; unsigned long orig_dst;
sch_frag_prepare_frag(skb, xmit); sch_frag_prepare_frag(skb, xmit);
dst_init(&sch_frag_dst, &sch_frag_dst_ops, NULL, 1, dst_init(&sch_frag_rt.dst, &sch_frag_dst_ops, NULL, 1,
DST_OBSOLETE_NONE, DST_NOCOUNT); DST_OBSOLETE_NONE, DST_NOCOUNT);
sch_frag_dst.dev = skb->dev; sch_frag_rt.dst.dev = skb->dev;
orig_dst = skb->_skb_refdst; orig_dst = skb->_skb_refdst;
skb_dst_set_noref(skb, &sch_frag_dst); skb_dst_set_noref(skb, &sch_frag_rt.dst);
IPCB(skb)->frag_max_size = mru; IPCB(skb)->frag_max_size = mru;
ret = ip_do_fragment(net, skb->sk, skb, sch_frag_xmit); ret = ip_do_fragment(net, skb->sk, skb, sch_frag_xmit);
......
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