[ 3.5.y.z extended stable ] Patch "net: ipv6: tcp: fix potential use after free in tcp_v6_do_rcv" has been added to staging queue

Luis Henriques luis.henriques at canonical.com
Fri Sep 20 19:34:21 UTC 2013


This is a note to let you know that I have just added a patch titled

    net: ipv6: tcp: fix potential use after free in tcp_v6_do_rcv

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

>From 0a3da43c575cd71d6fc98946f851c2c55a36d314 Mon Sep 17 00:00:00 2001
From: Daniel Borkmann <dborkman at redhat.com>
Date: Tue, 3 Sep 2013 19:29:12 +0200
Subject: [PATCH] net: ipv6: tcp: fix potential use after free in tcp_v6_do_rcv

commit 3a1c756590633c0e86df606e5c618c190926a0df upstream.

In tcp_v6_do_rcv() code, when processing pkt options, we soley work
on our skb clone opt_skb that we've created earlier before entering
tcp_rcv_established() on our way. However, only in condition ...

  if (np->rxopt.bits.rxtclass)
    np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));

... we work on skb itself. As we extract every other information out
of opt_skb in ipv6_pktoptions path, this seems wrong, since skb can
already be released by tcp_rcv_established() earlier on. When we try
to access it in ipv6_hdr(), we will dereference freed skb.

[ Bug added by commit 4c507d2897bd9b ("net: implement IP_RECVTOS for
  IP_PKTOPTIONS") ]

Signed-off-by: Daniel Borkmann <dborkman at redhat.com>
Cc: Eric Dumazet <eric.dumazet at gmail.com>
Acked-by: Eric Dumazet <edumazet at google.com>
Acked-by: Jiri Benc <jbenc at redhat.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
[ luis: backported to 3.5: adjusted context ]
Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
---
 net/ipv6/tcp_ipv6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 989c024..1467fc7 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1573,7 +1573,7 @@ ipv6_pktoptions:
 		if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
 			np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
 		if (np->rxopt.bits.rxtclass)
-			np->rcv_tclass = ipv6_tclass(ipv6_hdr(skb));
+			np->rcv_tclass = ipv6_tclass(ipv6_hdr(opt_skb));
 		if (ipv6_opt_accepted(sk, opt_skb)) {
 			skb_set_owner_r(opt_skb, sk);
 			opt_skb = xchg(&np->pktoptions, opt_skb);
--
1.8.3.2





More information about the kernel-team mailing list