Patchwork [net-2.6] ip: NULL pointer dereferrence in tcp_v(4|6)_send_ack

login
register
mail settings
Submitter Denis V. Lunev
Date Sept. 30, 2008, 4:29 p.m.
Message ID <1222792151-11861-1-git-send-email-den@openvz.org>
Download mbox | patch
Permalink /patch/2110/
State Accepted
Delegated to: David Miller
Headers show

Comments

Denis V. Lunev - Sept. 30, 2008, 4:29 p.m.
The following actions are possible:
tcp_v4_rcv
  skb->dev = NULL;
  tcp_v4_do_rcv
    tcp_v4_hnd_req
      tcp_check_req
        req->rsk_ops->send_ack == tcp_v4_send_ack

So, skb->dev can be NULL in tcp_v4_send_ack. We must obtain namespace
from dst entry. IPv6 codepath is similar.

Thanks to Vitaliy Gusev <vgusev@openvz.org> for initial oops decoding.

Signed-off-by: Denis V. Lunev <den@openvz.org>
---
 net/ipv4/tcp_ipv4.c |    2 +-
 net/ipv6/tcp_ipv6.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
David Miller - Oct. 1, 2008, 8:52 a.m.
From: "Denis V. Lunev" <den@openvz.org>
Date: Tue, 30 Sep 2008 20:29:11 +0400

> The following actions are possible:
> tcp_v4_rcv
>   skb->dev = NULL;
>   tcp_v4_do_rcv
>     tcp_v4_hnd_req
>       tcp_check_req
>         req->rsk_ops->send_ack == tcp_v4_send_ack
> 
> So, skb->dev can be NULL in tcp_v4_send_ack. We must obtain namespace
> from dst entry. IPv6 codepath is similar.
> 
> Thanks to Vitaliy Gusev <vgusev@openvz.org> for initial oops decoding.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>

Vitaliy sent the same patch first, so I applied his copy :-)

Thanks everyone.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller - Oct. 1, 2008, 9:03 a.m.
From: Vitaliy Gusev <vgusev@openvz.org>
Date: Wed, 1 Oct 2008 13:06:15 +0400

> On 1 October 2008 12:52:46 David Miller wrote:
> > Vitaliy sent the same patch first, so I applied his copy :-)
> 
> Den's patch is not the same. My patch didn't fix IPv6 code.

Whoops... Denis can you resubmit just the ipv6 side
fix then?  I already pushed Vitaliy's commit out
to net-2.6

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Vitaliy Gusev - Oct. 1, 2008, 9:06 a.m.
On 1 October 2008 12:52:46 David Miller wrote:
> From: "Denis V. Lunev" <den@openvz.org>
> Date: Tue, 30 Sep 2008 20:29:11 +0400
> 
> > The following actions are possible:
> > tcp_v4_rcv
> >   skb->dev = NULL;
> >   tcp_v4_do_rcv
> >     tcp_v4_hnd_req
> >       tcp_check_req
> >         req->rsk_ops->send_ack == tcp_v4_send_ack
> > 
> > So, skb->dev can be NULL in tcp_v4_send_ack. We must obtain namespace
> > from dst entry. IPv6 codepath is similar.
> > 
> > Thanks to Vitaliy Gusev <vgusev@openvz.org> for initial oops decoding.
> > 
> > Signed-off-by: Denis V. Lunev <den@openvz.org>
> 
> Vitaliy sent the same patch first, so I applied his copy :-)

Den's patch is not the same. My patch didn't fix IPv6 code.

> 
> Thanks everyone.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

Patch

diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 1b4fee2..011478e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -618,7 +618,7 @@  static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
 			];
 	} rep;
 	struct ip_reply_arg arg;
-	struct net *net = dev_net(skb->dev);
+	struct net *net = dev_net(skb->dst->dev);
 
 	memset(&rep.th, 0, sizeof(struct tcphdr));
 	memset(&arg, 0, sizeof(arg));
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index b585c85..10e22fd 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1050,7 +1050,7 @@  static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
 	struct tcphdr *th = tcp_hdr(skb), *t1;
 	struct sk_buff *buff;
 	struct flowi fl;
-	struct net *net = dev_net(skb->dev);
+	struct net *net = dev_net(skb->dst->dev);
 	struct sock *ctl_sk = net->ipv6.tcp_sk;
 	unsigned int tot_len = sizeof(struct tcphdr);
 	__be32 *topt;