]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 May 2013 21:56:31 +0000 (17:56 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 May 2013 21:56:31 +0000 (17:56 -0400)
added patches:
3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch
3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch
3c59x-fix-pci-resource-management.patch
bridge-fix-race-with-topology-change-timer.patch
if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch
ipv6-do-not-clear-pinet6-field.patch
macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch
net_sched-act_ipt-forward-compat-with-xtables.patch
tcp-force-a-dst-refcount-when-prequeue-packet.patch
xfrm6-release-dev-before-returning-error.patch

queue-3.0/3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch [new file with mode: 0644]
queue-3.0/3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch [new file with mode: 0644]
queue-3.0/3c59x-fix-pci-resource-management.patch [new file with mode: 0644]
queue-3.0/bridge-fix-race-with-topology-change-timer.patch [new file with mode: 0644]
queue-3.0/if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch [new file with mode: 0644]
queue-3.0/ipv6-do-not-clear-pinet6-field.patch [new file with mode: 0644]
queue-3.0/macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch [new file with mode: 0644]
queue-3.0/net_sched-act_ipt-forward-compat-with-xtables.patch [new file with mode: 0644]
queue-3.0/series
queue-3.0/tcp-force-a-dst-refcount-when-prequeue-packet.patch [new file with mode: 0644]
queue-3.0/xfrm6-release-dev-before-returning-error.patch [new file with mode: 0644]

diff --git a/queue-3.0/3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch b/queue-3.0/3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch
new file mode 100644 (file)
index 0000000..f03b187
--- /dev/null
@@ -0,0 +1,49 @@
+From 0720c46f5f766204bb6bbcbf1bdb248fced83b24 Mon Sep 17 00:00:00 2001
+From: Matthew Whitehead <tedheadster@gmail.com>
+Date: Mon, 29 Apr 2013 17:46:53 -0400
+Subject: 3c509.c: call SET_NETDEV_DEV for all device types (ISA/ISAPnP/EISA)
+
+
+From: Matthew Whitehead <tedheadster@gmail.com>
+
+[ Upstream commit 3b54912f9cd167641b91d4a697bd742f70e534fe ]
+
+The venerable 3c509 driver only sets its device parent in one case, the ISAPnP one.
+It does this with the SET_NETDEV_DEV function. It should register with the device
+hierarchy in two additional cases: standard (non-PnP) ISA and EISA.
+
+- Currently they appear here:
+/sys/devices/virtual/net/eth0 (standard ISA)
+/sys/devices/virtual/net/eth1 (EISA)
+
+- Rather, they should instead be here:
+/sys/devices/isa/3c509.0/net/eth0 (standard ISA)
+/sys/devices/pci0000:00/0000:00:07.0/00:04/net/eth1 (EISA)
+
+Tested on ISA and EISA boards.
+
+Signed-off-by: Matthew Whitehead <tedheadster@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/3c509.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/3c509.c
++++ b/drivers/net/3c509.c
+@@ -309,6 +309,7 @@ static int __devinit el3_isa_match(struc
+       if (!dev)
+               return -ENOMEM;
++      SET_NETDEV_DEV(dev, pdev);
+       netdev_boot_setup_check(dev);
+       if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
+@@ -704,6 +705,7 @@ static int __init el3_eisa_probe (struct
+               return -ENOMEM;
+       }
++      SET_NETDEV_DEV(dev, device);
+       netdev_boot_setup_check(dev);
+       el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
diff --git a/queue-3.0/3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch b/queue-3.0/3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch
new file mode 100644 (file)
index 0000000..f50aa3a
--- /dev/null
@@ -0,0 +1,40 @@
+From 3ca30fab517c62dbd72f7cea203e1fcb37c691c5 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Date: Thu, 2 May 2013 11:10:22 +0000
+Subject: 3c59x: fix freeing nonexistent resource on driver unload
+
+
+From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+
+[ Upstream commit c81400be716aa4c76f6ebf339ba94358dbbf6da6 ]
+
+When unloading the driver that drives an EISA board, a message similar to the
+following one is displayed:
+
+Trying to free nonexistent resource <0000000000013000-000000000001301f>
+
+Then an user is unable to reload the driver because the resource it requested in
+the previous load hasn't been freed. This happens most probably due to a typo in
+vortex_eisa_remove() which calls release_region() with 'dev->base_addr'  instead
+of 'edev->base_addr'...
+
+Reported-by: Matthew Whitehead <tedheadster@gmail.com>
+Tested-by: Matthew Whitehead <tedheadster@gmail.com>
+Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/3c59x.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/3c59x.c
++++ b/drivers/net/3c59x.c
+@@ -951,7 +951,7 @@ static int __devexit vortex_eisa_remove(
+       unregister_netdev(dev);
+       iowrite16(TotalReset|0x14, ioaddr + EL3_CMD);
+-      release_region(dev->base_addr, VORTEX_TOTAL_SIZE);
++      release_region(edev->base_addr, VORTEX_TOTAL_SIZE);
+       free_netdev(dev);
+       return 0;
diff --git a/queue-3.0/3c59x-fix-pci-resource-management.patch b/queue-3.0/3c59x-fix-pci-resource-management.patch
new file mode 100644 (file)
index 0000000..b353aa8
--- /dev/null
@@ -0,0 +1,105 @@
+From 83949eb5aed40bca69290317a6a1ec6f0d4453c3 Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Thu, 9 May 2013 11:14:07 +0000
+Subject: 3c59x: fix PCI resource management
+
+
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+
+[ Upstream commit 4b264a1676e70dc656ba53a8cac690f2d4b65f4e ]
+
+The driver wrongly claimed I/O ports at an address returned by pci_iomap() --
+even if it was passed an MMIO address.  Fix this by claiming/releasing all PCI
+resources in the PCI driver's probe()/remove() methods instead and get rid of
+'must_free_region' flag weirdness (why would Cardbus claim anything for us?).
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/3c59x.c |   25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/3c59x.c
++++ b/drivers/net/3c59x.c
+@@ -632,7 +632,6 @@ struct vortex_private {
+               pm_state_valid:1,                               /* pci_dev->saved_config_space has sane contents */
+               open:1,
+               medialock:1,
+-              must_free_region:1,                             /* Flag: if zero, Cardbus owns the I/O region */
+               large_frames:1,                 /* accept large frames */
+               handling_irq:1;                 /* private in_irq indicator */
+       /* {get|set}_wol operations are already serialized by rtnl.
+@@ -1012,6 +1011,12 @@ static int __devinit vortex_init_one(str
+       if (rc < 0)
+               goto out;
++      rc = pci_request_regions(pdev, DRV_NAME);
++      if (rc < 0) {
++              pci_disable_device(pdev);
++              goto out;
++      }
++
+       unit = vortex_cards_found;
+       if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
+@@ -1027,6 +1032,7 @@ static int __devinit vortex_init_one(str
+       if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
+               ioaddr = pci_iomap(pdev, 0, 0);
+       if (!ioaddr) {
++              pci_release_regions(pdev);
+               pci_disable_device(pdev);
+               rc = -ENOMEM;
+               goto out;
+@@ -1036,6 +1042,7 @@ static int __devinit vortex_init_one(str
+                          ent->driver_data, unit);
+       if (rc < 0) {
+               pci_iounmap(pdev, ioaddr);
++              pci_release_regions(pdev);
+               pci_disable_device(pdev);
+               goto out;
+       }
+@@ -1180,11 +1187,6 @@ static int __devinit vortex_probe1(struc
+       /* PCI-only startup logic */
+       if (pdev) {
+-              /* EISA resources already marked, so only PCI needs to do this here */
+-              /* Ignore return value, because Cardbus drivers already allocate for us */
+-              if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
+-                      vp->must_free_region = 1;
+-
+               /* enable bus-mastering if necessary */
+               if (vci->flags & PCI_USES_MASTER)
+                       pci_set_master(pdev);
+@@ -1222,7 +1224,7 @@ static int __devinit vortex_probe1(struc
+                                          &vp->rx_ring_dma);
+       retval = -ENOMEM;
+       if (!vp->rx_ring)
+-              goto free_region;
++              goto free_device;
+       vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE);
+       vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE;
+@@ -1487,9 +1489,7 @@ free_ring:
+                                                       + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
+                                               vp->rx_ring,
+                                               vp->rx_ring_dma);
+-free_region:
+-      if (vp->must_free_region)
+-              release_region(dev->base_addr, vci->io_size);
++free_device:
+       free_netdev(dev);
+       pr_err(PFX "vortex_probe1 fails.  Returns %d\n", retval);
+ out:
+@@ -3253,8 +3253,9 @@ static void __devexit vortex_remove_one(
+                                                       + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
+                                               vp->rx_ring,
+                                               vp->rx_ring_dma);
+-      if (vp->must_free_region)
+-              release_region(dev->base_addr, vp->io_size);
++
++      pci_release_regions(pdev);
++
+       free_netdev(dev);
+ }
diff --git a/queue-3.0/bridge-fix-race-with-topology-change-timer.patch b/queue-3.0/bridge-fix-race-with-topology-change-timer.patch
new file mode 100644 (file)
index 0000000..dce7407
--- /dev/null
@@ -0,0 +1,37 @@
+From eb871268aeff96a27ca7192285e698286136a2d7 Mon Sep 17 00:00:00 2001
+From: stephen hemminger <stephen@networkplumber.org>
+Date: Thu, 2 May 2013 14:23:28 +0000
+Subject: bridge: fix race with topology change timer
+
+
+From: stephen hemminger <stephen@networkplumber.org>
+
+[ Upstream commit 83401eb4990ff6af55aeed8f49681558544192e6 ]
+
+A bridge should only send topology change notice if it is not
+the root bridge. It is possible for message age timer to elect itself
+as a new root bridge, and still have a topology change timer running
+but waiting for bridge lock on other CPU.
+
+Solve the race by checking if we are root bridge before continuing.
+This was the root cause of the cases where br_send_tcn_bpdu would OOPS.
+
+Reported-by: JerryKang <jerry.kang@samsung.com>
+Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_stp_timer.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/bridge/br_stp_timer.c
++++ b/net/bridge/br_stp_timer.c
+@@ -106,7 +106,7 @@ static void br_tcn_timer_expired(unsigne
+       br_debug(br, "tcn timer expired\n");
+       spin_lock(&br->lock);
+-      if (br->dev->flags & IFF_UP) {
++      if (!br_is_root_bridge(br) && (br->dev->flags & IFF_UP)) {
+               br_transmit_tcn(br);
+               mod_timer(&br->tcn_timer,jiffies + br->bridge_hello_time);
diff --git a/queue-3.0/if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch b/queue-3.0/if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch
new file mode 100644 (file)
index 0000000..602ec5f
--- /dev/null
@@ -0,0 +1,40 @@
+From 8a1d1ecb8f7532cc5c0ffb59ec880704c144b01f Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer@redhat.com>
+Date: Wed, 8 May 2013 09:45:47 +0000
+Subject: if_cablemodem.h: Add parenthesis around ioctl macros
+
+
+From: Josh Boyer <jwboyer@redhat.com>
+
+[ Upstream commit 4f924b2aa4d3cb30f07e57d6b608838edcbc0d88 ]
+
+Protect the SIOCGCM* ioctl macros with parenthesis.
+
+Reported-by: Paul Wouters <pwouters@redhat.com>
+Signed-off-by: Josh Boyer <jwboyer@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/if_cablemodem.h |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/include/linux/if_cablemodem.h
++++ b/include/linux/if_cablemodem.h
+@@ -12,11 +12,11 @@
+  */
+ /* some useful defines for sb1000.c e cmconfig.c - fv */
+-#define SIOCGCMSTATS          SIOCDEVPRIVATE+0        /* get cable modem stats */
+-#define SIOCGCMFIRMWARE               SIOCDEVPRIVATE+1        /* get cm firmware version */
+-#define SIOCGCMFREQUENCY      SIOCDEVPRIVATE+2        /* get cable modem frequency */
+-#define SIOCSCMFREQUENCY      SIOCDEVPRIVATE+3        /* set cable modem frequency */
+-#define SIOCGCMPIDS                   SIOCDEVPRIVATE+4        /* get cable modem PIDs */
+-#define SIOCSCMPIDS                   SIOCDEVPRIVATE+5        /* set cable modem PIDs */
++#define SIOCGCMSTATS          (SIOCDEVPRIVATE+0)      /* get cable modem stats */
++#define SIOCGCMFIRMWARE               (SIOCDEVPRIVATE+1)      /* get cm firmware version */
++#define SIOCGCMFREQUENCY      (SIOCDEVPRIVATE+2)      /* get cable modem frequency */
++#define SIOCSCMFREQUENCY      (SIOCDEVPRIVATE+3)      /* set cable modem frequency */
++#define SIOCGCMPIDS                   (SIOCDEVPRIVATE+4)      /* get cable modem PIDs */
++#define SIOCSCMPIDS                   (SIOCDEVPRIVATE+5)      /* set cable modem PIDs */
+ #endif
diff --git a/queue-3.0/ipv6-do-not-clear-pinet6-field.patch b/queue-3.0/ipv6-do-not-clear-pinet6-field.patch
new file mode 100644 (file)
index 0000000..7895c2e
--- /dev/null
@@ -0,0 +1,163 @@
+From 26b563a0f926b18c7d7a75cc9502f786d7bbcfdf Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 9 May 2013 10:28:16 +0000
+Subject: ipv6: do not clear pinet6 field
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f77d602124d865c38705df7fa25c03de9c284ad2 ]
+
+We have seen multiple NULL dereferences in __inet6_lookup_established()
+
+After analysis, I found that inet6_sk() could be NULL while the
+check for sk_family == AF_INET6 was true.
+
+Bug was added in linux-2.6.29 when RCU lookups were introduced in UDP
+and TCP stacks.
+
+Once an IPv6 socket, using SLAB_DESTROY_BY_RCU is inserted in a hash
+table, we no longer can clear pinet6 field.
+
+This patch extends logic used in commit fcbdf09d9652c891
+("net: fix nulls list corruptions in sk_prot_alloc")
+
+TCP/UDP/UDPLite IPv6 protocols provide their own .clear_sk() method
+to make sure we do not clear pinet6 field.
+
+At socket clone phase, we do not really care, as cloning the parent (non
+NULL) pinet6 is not adding a fatal race.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/sock.h  |   12 ++++++++++++
+ net/core/sock.c     |   12 ------------
+ net/ipv6/tcp_ipv6.c |   12 ++++++++++++
+ net/ipv6/udp.c      |   13 ++++++++++++-
+ net/ipv6/udp_impl.h |    2 ++
+ net/ipv6/udplite.c  |    2 +-
+ 6 files changed, 39 insertions(+), 14 deletions(-)
+
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -721,6 +721,18 @@ struct timewait_sock_ops;
+ struct inet_hashinfo;
+ struct raw_hashinfo;
++/*
++ * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
++ * un-modified. Special care is taken when initializing object to zero.
++ */
++static inline void sk_prot_clear_nulls(struct sock *sk, int size)
++{
++      if (offsetof(struct sock, sk_node.next) != 0)
++              memset(sk, 0, offsetof(struct sock, sk_node.next));
++      memset(&sk->sk_node.pprev, 0,
++             size - offsetof(struct sock, sk_node.pprev));
++}
++
+ /* Networking protocol blocks we attach to sockets.
+  * socket layer -> transport layer interface
+  * transport -> network interface is defined by struct inet_proto
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1017,18 +1017,6 @@ static void sock_copy(struct sock *nsk,
+ #endif
+ }
+-/*
+- * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes
+- * un-modified. Special care is taken when initializing object to zero.
+- */
+-static inline void sk_prot_clear_nulls(struct sock *sk, int size)
+-{
+-      if (offsetof(struct sock, sk_node.next) != 0)
+-              memset(sk, 0, offsetof(struct sock, sk_node.next));
+-      memset(&sk->sk_node.pprev, 0,
+-             size - offsetof(struct sock, sk_node.pprev));
+-}
+-
+ void sk_prot_clear_portaddr_nulls(struct sock *sk, int size)
+ {
+       unsigned long nulls1, nulls2;
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -2205,6 +2205,17 @@ void tcp6_proc_exit(struct net *net)
+ }
+ #endif
++static void tcp_v6_clear_sk(struct sock *sk, int size)
++{
++      struct inet_sock *inet = inet_sk(sk);
++
++      /* we do not want to clear pinet6 field, because of RCU lookups */
++      sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6));
++
++      size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
++      memset(&inet->pinet6 + 1, 0, size);
++}
++
+ struct proto tcpv6_prot = {
+       .name                   = "TCPv6",
+       .owner                  = THIS_MODULE,
+@@ -2244,6 +2255,7 @@ struct proto tcpv6_prot = {
+       .compat_setsockopt      = compat_tcp_setsockopt,
+       .compat_getsockopt      = compat_tcp_getsockopt,
+ #endif
++      .clear_sk               = tcp_v6_clear_sk,
+ };
+ static const struct inet6_protocol tcpv6_protocol = {
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1448,6 +1448,17 @@ void udp6_proc_exit(struct net *net) {
+ }
+ #endif /* CONFIG_PROC_FS */
++void udp_v6_clear_sk(struct sock *sk, int size)
++{
++      struct inet_sock *inet = inet_sk(sk);
++
++      /* we do not want to clear pinet6 field, because of RCU lookups */
++      sk_prot_clear_portaddr_nulls(sk, offsetof(struct inet_sock, pinet6));
++
++      size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6);
++      memset(&inet->pinet6 + 1, 0, size);
++}
++
+ /* ------------------------------------------------------------------------ */
+ struct proto udpv6_prot = {
+@@ -1478,7 +1489,7 @@ struct proto udpv6_prot = {
+       .compat_setsockopt = compat_udpv6_setsockopt,
+       .compat_getsockopt = compat_udpv6_getsockopt,
+ #endif
+-      .clear_sk          = sk_prot_clear_portaddr_nulls,
++      .clear_sk          = udp_v6_clear_sk,
+ };
+ static struct inet_protosw udpv6_protosw = {
+--- a/net/ipv6/udp_impl.h
++++ b/net/ipv6/udp_impl.h
+@@ -31,6 +31,8 @@ extern int   udpv6_recvmsg(struct kiocb *i
+ extern int    udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
+ extern void   udpv6_destroy_sock(struct sock *sk);
++extern void udp_v6_clear_sk(struct sock *sk, int size);
++
+ #ifdef CONFIG_PROC_FS
+ extern int    udp6_seq_show(struct seq_file *seq, void *v);
+ #endif
+--- a/net/ipv6/udplite.c
++++ b/net/ipv6/udplite.c
+@@ -55,7 +55,7 @@ struct proto udplitev6_prot = {
+       .compat_setsockopt = compat_udpv6_setsockopt,
+       .compat_getsockopt = compat_udpv6_getsockopt,
+ #endif
+-      .clear_sk          = sk_prot_clear_portaddr_nulls,
++      .clear_sk          = udp_v6_clear_sk,
+ };
+ static struct inet_protosw udplite6_protosw = {
diff --git a/queue-3.0/macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch b/queue-3.0/macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch
new file mode 100644 (file)
index 0000000..6c69fa2
--- /dev/null
@@ -0,0 +1,108 @@
+From ce3ea092d35d901aeb235fa891f40a3fe288119d Mon Sep 17 00:00:00 2001
+From: Jiri Pirko <jiri@resnulli.us>
+Date: Thu, 9 May 2013 04:23:40 +0000
+Subject: macvlan: fix passthru mode race between dev removal and rx path
+
+
+From: Jiri Pirko <jiri@resnulli.us>
+
+[ Upstream commit 233c7df0821c4190e2d3f4be0f2ca0ab40a5ed8c, note
+  that I had to add list_first_or_null_rcu to rculist.h in order
+  to accomodate this fix. ]
+
+Currently, if macvlan in passthru mode is created and data are rxed and
+you remove this device, following panic happens:
+
+NULL pointer dereference at 0000000000000198
+IP: [<ffffffffa0196058>] macvlan_handle_frame+0x153/0x1f7 [macvlan]
+
+I'm using following script to trigger this:
+<script>
+while [ 1 ]
+do
+       ip link add link e1 name macvtap0 type macvtap mode passthru
+       ip link set e1 up
+       ip link set macvtap0 up
+       IFINDEX=`ip link |grep macvtap0 | cut -f 1 -d ':'`
+       cat /dev/tap$IFINDEX  >/dev/null &
+       ip link del dev macvtap0
+done
+</script>
+
+I run this script while "ping -f" is running on another machine to send
+packets to e1 rx.
+
+Reason of the panic is that list_first_entry() is blindly called in
+macvlan_handle_frame() even if the list was empty. vlan is set to
+incorrect pointer which leads to the crash.
+
+I'm fixing this by protecting port->vlans list by rcu and by preventing
+from getting incorrect pointer in case the list is empty.
+
+Introduced by: commit eb06acdc85585f2 "macvlan: Introduce 'passthru' mode to takeover the underlying device"
+
+Signed-off-by: Jiri Pirko <jiri@resnulli.us>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvlan.c   |    7 ++++---
+ include/linux/rculist.h |   17 +++++++++++++++++
+ 2 files changed, 21 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -193,7 +193,8 @@ static rx_handler_result_t macvlan_handl
+       }
+       if (port->passthru)
+-              vlan = list_first_entry(&port->vlans, struct macvlan_dev, list);
++              vlan = list_first_or_null_rcu(&port->vlans,
++                                            struct macvlan_dev, list);
+       else
+               vlan = macvlan_hash_lookup(port, eth->h_dest);
+       if (vlan == NULL)
+@@ -687,7 +688,7 @@ int macvlan_common_newlink(struct net *s
+       if (err < 0)
+               goto destroy_port;
+-      list_add_tail(&vlan->list, &port->vlans);
++      list_add_tail_rcu(&vlan->list, &port->vlans);
+       netif_stacked_transfer_operstate(lowerdev, dev);
+       return 0;
+@@ -713,7 +714,7 @@ void macvlan_dellink(struct net_device *
+ {
+       struct macvlan_dev *vlan = netdev_priv(dev);
+-      list_del(&vlan->list);
++      list_del_rcu(&vlan->list);
+       unregister_netdevice_queue(dev, head);
+ }
+ EXPORT_SYMBOL_GPL(macvlan_dellink);
+--- a/include/linux/rculist.h
++++ b/include/linux/rculist.h
+@@ -242,6 +242,23 @@ static inline void list_splice_init_rcu(
+       list_entry_rcu((ptr)->next, type, member)
+ /**
++ * list_first_or_null_rcu - get the first element from a list
++ * @ptr:        the list head to take the element from.
++ * @type:       the type of the struct this is embedded in.
++ * @member:     the name of the list_struct within the struct.
++ *
++ * Note that if the list is empty, it returns NULL.
++ *
++ * This primitive may safely run concurrently with the _rcu list-mutation
++ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
++ */
++#define list_first_or_null_rcu(ptr, type, member) \
++      ({struct list_head *__ptr = (ptr); \
++        struct list_head __rcu *__next = list_next_rcu(__ptr); \
++        likely(__ptr != __next) ? container_of(__next, type, member) : NULL; \
++      })
++
++/**
+  * list_for_each_entry_rcu    -       iterate over rcu list of given type
+  * @pos:      the type * to use as a loop cursor.
+  * @head:     the head for your list.
diff --git a/queue-3.0/net_sched-act_ipt-forward-compat-with-xtables.patch b/queue-3.0/net_sched-act_ipt-forward-compat-with-xtables.patch
new file mode 100644 (file)
index 0000000..c9eac7f
--- /dev/null
@@ -0,0 +1,78 @@
+From f7def787465d269ba6439c7e26f59c785ca318eb Mon Sep 17 00:00:00 2001
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+Date: Sun, 28 Apr 2013 05:06:38 +0000
+Subject: net_sched: act_ipt forward compat with xtables
+
+
+From: Jamal Hadi Salim <jhs@mojatatu.com>
+
+[ Upstream commit 0dcffd09641f3abb21ac5cabc61542ab289d1a3c ]
+
+Deal with changes in newer xtables while maintaining backward
+compatibility. Thanks to Jan Engelhardt for suggestions.
+
+Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sched/act_ipt.c |   33 ++++++++++++++++++++++++++++++---
+ 1 file changed, 30 insertions(+), 3 deletions(-)
+
+--- a/net/sched/act_ipt.c
++++ b/net/sched/act_ipt.c
+@@ -8,7 +8,7 @@
+  *            as published by the Free Software Foundation; either version
+  *            2 of the License, or (at your option) any later version.
+  *
+- * Copyright: Jamal Hadi Salim (2002-4)
++ * Copyright: Jamal Hadi Salim (2002-13)
+  */
+ #include <linux/types.h>
+@@ -299,17 +299,44 @@ static struct tc_action_ops act_ipt_ops
+       .walk           =       tcf_generic_walker
+ };
+-MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
++static struct tc_action_ops act_xt_ops = {
++      .kind           =       "xt",
++      .hinfo          =       &ipt_hash_info,
++      .type           =       TCA_ACT_IPT,
++      .capab          =       TCA_CAP_NONE,
++      .owner          =       THIS_MODULE,
++      .act            =       tcf_ipt,
++      .dump           =       tcf_ipt_dump,
++      .cleanup        =       tcf_ipt_cleanup,
++      .lookup         =       tcf_hash_search,
++      .init           =       tcf_ipt_init,
++      .walk           =       tcf_generic_walker
++};
++
++MODULE_AUTHOR("Jamal Hadi Salim(2002-13)");
+ MODULE_DESCRIPTION("Iptables target actions");
+ MODULE_LICENSE("GPL");
++MODULE_ALIAS("act_xt");
+ static int __init ipt_init_module(void)
+ {
+-      return tcf_register_action(&act_ipt_ops);
++      int ret1, ret2;
++      ret1 = tcf_register_action(&act_xt_ops);
++      if (ret1 < 0)
++              printk("Failed to load xt action\n");
++      ret2 = tcf_register_action(&act_ipt_ops);
++      if (ret2 < 0)
++              printk("Failed to load ipt action\n");
++
++      if (ret1 < 0 && ret2 < 0)
++              return ret1;
++      else
++              return 0;
+ }
+ static void __exit ipt_cleanup_module(void)
+ {
++      tcf_unregister_action(&act_xt_ops);
+       tcf_unregister_action(&act_ipt_ops);
+ }
index 2d9b1d4703ae687dea419a9e5ae6b1e2ff9b732b..75da0956f2b9c6c973931626c2292e1f4abf1797 100644 (file)
@@ -14,3 +14,13 @@ mwifiex-clear-is_suspended-flag-when-interrupt-is-received-early.patch
 mwifiex-fix-setting-of-multicast-filter.patch
 drm-mm-fix-dump-table-bug.patch
 drm-don-t-check-modeset-locks-in-panic-handler.patch
+tcp-force-a-dst-refcount-when-prequeue-packet.patch
+3c509.c-call-set_netdev_dev-for-all-device-types-isa-isapnp-eisa.patch
+net_sched-act_ipt-forward-compat-with-xtables.patch
+bridge-fix-race-with-topology-change-timer.patch
+3c59x-fix-freeing-nonexistent-resource-on-driver-unload.patch
+3c59x-fix-pci-resource-management.patch
+if_cablemodem.h-add-parenthesis-around-ioctl-macros.patch
+macvlan-fix-passthru-mode-race-between-dev-removal-and-rx-path.patch
+ipv6-do-not-clear-pinet6-field.patch
+xfrm6-release-dev-before-returning-error.patch
diff --git a/queue-3.0/tcp-force-a-dst-refcount-when-prequeue-packet.patch b/queue-3.0/tcp-force-a-dst-refcount-when-prequeue-packet.patch
new file mode 100644 (file)
index 0000000..95116f2
--- /dev/null
@@ -0,0 +1,31 @@
+From 2cf71e86f962d7e7f7c39fc5ca3549fecc06cc14 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 24 Apr 2013 18:34:55 -0700
+Subject: tcp: force a dst refcount when prequeue packet
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 093162553c33e9479283e107b4431378271c735d ]
+
+Before escaping RCU protected section and adding packet into
+prequeue, make sure the dst is refcounted.
+
+Reported-by: Mike Galbraith <bitbucket@online.de>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/tcp.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -902,6 +902,7 @@ static inline int tcp_prequeue(struct so
+       if (sysctl_tcp_low_latency || !tp->ucopy.task)
+               return 0;
++      skb_dst_force(skb);
+       __skb_queue_tail(&tp->ucopy.prequeue, skb);
+       tp->ucopy.memory += skb->truesize;
+       if (tp->ucopy.memory > sk->sk_rcvbuf) {
diff --git a/queue-3.0/xfrm6-release-dev-before-returning-error.patch b/queue-3.0/xfrm6-release-dev-before-returning-error.patch
new file mode 100644 (file)
index 0000000..7296cc1
--- /dev/null
@@ -0,0 +1,37 @@
+From f2e07c264fcbe7ce46ee9e3daa94e2356d2503d3 Mon Sep 17 00:00:00 2001
+From: Cong Wang <amwang@redhat.com>
+Date: Thu, 9 May 2013 22:40:00 +0000
+Subject: xfrm6: release dev before returning error
+
+
+From: Cong Wang <amwang@redhat.com>
+
+[ Upstream commit 84c4a9dfbf430861e7588d95ae3ff61535dca351 ]
+
+We forget to call dev_put() on error path in xfrm6_fill_dst(),
+its caller doesn't handle this.
+
+Signed-off-by: Cong Wang <amwang@redhat.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: David S. Miller <davem@davemloft.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/xfrm6_policy.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/ipv6/xfrm6_policy.c
++++ b/net/ipv6/xfrm6_policy.c
+@@ -96,8 +96,10 @@ static int xfrm6_fill_dst(struct xfrm_ds
+       dev_hold(dev);
+       xdst->u.rt6.rt6i_idev = in6_dev_get(dev);
+-      if (!xdst->u.rt6.rt6i_idev)
++      if (!xdst->u.rt6.rt6i_idev) {
++              dev_put(dev);
+               return -ENODEV;
++      }
+       xdst->u.rt6.rt6i_peer = rt->rt6i_peer;
+       if (rt->rt6i_peer)