From: Greg Kroah-Hartman Date: Tue, 7 Aug 2012 21:23:17 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.5.1~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7be248395434d52416f3991e8b5d2be711da6b56;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: caif-fix-null-pointer-check.patch net-fix-references-to-out-of-scope-variables-in-put_cmsg_compat.patch net-fix-rtnetlink-iff_promisc-and-iff_allmulti-handling.patch net-tun-fix-ioctl-based-info-leaks.patch r8169-revert-add-byte-queue-limit-support.patch tcp-add-tcp_user_timeout-negative-value-check.patch tcp-perform-dma-to-userspace-only-if-there-is-a-task-waiting-for-it.patch usb-kaweth.c-use-gfp_atomic-under-spin_lock.patch wanmain-comparing-array-with-null.patch --- diff --git a/queue-3.5/caif-fix-null-pointer-check.patch b/queue-3.5/caif-fix-null-pointer-check.patch new file mode 100644 index 00000000000..85c180b7a30 --- /dev/null +++ b/queue-3.5/caif-fix-null-pointer-check.patch @@ -0,0 +1,31 @@ +From 8c084d34621fc96d1fa8f2fa7baa3b7edae59101 Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Tue, 24 Jul 2012 02:42:14 +0000 +Subject: caif: fix NULL pointer check + + +From: Alan Cox + +[ Upstream commit c66b9b7d365444b433307ebb18734757cb668a02 ] + +Reported-by: +Resolves-bug: http://bugzilla.kernel.org/show_bug?44441 +Signed-off-by: Alan Cox +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/caif/caif_serial.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/caif/caif_serial.c ++++ b/drivers/net/caif/caif_serial.c +@@ -325,6 +325,9 @@ static int ldisc_open(struct tty_struct + + sprintf(name, "cf%s", tty->name); + dev = alloc_netdev(sizeof(*ser), name, caifdev_setup); ++ if (!dev) ++ return -ENOMEM; ++ + ser = netdev_priv(dev); + ser->tty = tty_kref_get(tty); + ser->dev = dev; diff --git a/queue-3.5/net-fix-references-to-out-of-scope-variables-in-put_cmsg_compat.patch b/queue-3.5/net-fix-references-to-out-of-scope-variables-in-put_cmsg_compat.patch new file mode 100644 index 00000000000..625bd8a80ff --- /dev/null +++ b/queue-3.5/net-fix-references-to-out-of-scope-variables-in-put_cmsg_compat.patch @@ -0,0 +1,48 @@ +From 8002dead821ba6aad5d1e8a17fb0d06ca398ab26 Mon Sep 17 00:00:00 2001 +From: Jesper Juhl +Date: Sun, 22 Jul 2012 11:37:20 +0000 +Subject: net: Fix references to out-of-scope variables in put_cmsg_compat() + + +From: Jesper Juhl + +[ Upstream commit 818810472b129004c16fc51bf0a570b60776bfb7 ] + +In net/compat.c::put_cmsg_compat() we may assign 'data' the address of +either the 'ctv' or 'cts' local variables inside the 'if +(!COMPAT_USE_64BIT_TIME)' branch. + +Those variables go out of scope at the end of the 'if' statement, so +when we use 'data' further down in 'copy_to_user(CMSG_COMPAT_DATA(cm), +data, cmlen - sizeof(struct compat_cmsghdr))' there's no telling what +it may be refering to - not good. + +Fix the problem by simply giving 'ctv' and 'cts' function scope. + +Signed-off-by: Jesper Juhl +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/compat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/compat.c ++++ b/net/compat.c +@@ -221,6 +221,8 @@ int put_cmsg_compat(struct msghdr *kmsg, + { + struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control; + struct compat_cmsghdr cmhdr; ++ struct compat_timeval ctv; ++ struct compat_timespec cts[3]; + int cmlen; + + if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) { +@@ -229,8 +231,6 @@ int put_cmsg_compat(struct msghdr *kmsg, + } + + if (!COMPAT_USE_64BIT_TIME) { +- struct compat_timeval ctv; +- struct compat_timespec cts[3]; + if (level == SOL_SOCKET && type == SCM_TIMESTAMP) { + struct timeval *tv = (struct timeval *)data; + ctv.tv_sec = tv->tv_sec; diff --git a/queue-3.5/net-fix-rtnetlink-iff_promisc-and-iff_allmulti-handling.patch b/queue-3.5/net-fix-rtnetlink-iff_promisc-and-iff_allmulti-handling.patch new file mode 100644 index 00000000000..179076f91cd --- /dev/null +++ b/queue-3.5/net-fix-rtnetlink-iff_promisc-and-iff_allmulti-handling.patch @@ -0,0 +1,57 @@ +From 959aecedc11194f7aeeddc8bc78d7c77cf640ffc Mon Sep 17 00:00:00 2001 +From: Jiri Benc +Date: Fri, 27 Jul 2012 02:58:22 +0000 +Subject: net: fix rtnetlink IFF_PROMISC and IFF_ALLMULTI handling + + +From: Jiri Benc + +[ Upstream commit b1beb681cba5358f62e6187340660ade226a5fcc ] + +When device flags are set using rtnetlink, IFF_PROMISC and IFF_ALLMULTI +flags are handled specially. Function dev_change_flags sets IFF_PROMISC and +IFF_ALLMULTI bits in dev->gflags according to the passed value but +do_setlink passes a result of rtnl_dev_combine_flags which takes those bits +from dev->flags. + +This can be easily trigerred by doing: + +tcpdump -i eth0 & +ip l s up eth0 + +ip sets IFF_UP flag in ifi_flags and ifi_change, which is combined with +IFF_PROMISC by rtnl_dev_combine_flags, causing __dev_change_flags to set +IFF_PROMISC in gflags. + +Reported-by: Max Matveev +Signed-off-by: Jiri Benc +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/rtnetlink.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -674,6 +674,12 @@ static void set_operstate(struct net_dev + } + } + ++static unsigned int rtnl_dev_get_flags(const struct net_device *dev) ++{ ++ return (dev->flags & ~(IFF_PROMISC | IFF_ALLMULTI)) | ++ (dev->gflags & (IFF_PROMISC | IFF_ALLMULTI)); ++} ++ + static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, + const struct ifinfomsg *ifm) + { +@@ -682,7 +688,7 @@ static unsigned int rtnl_dev_combine_fla + /* bugwards compatibility: ifi_change == 0 is treated as ~0 */ + if (ifm->ifi_change) + flags = (flags & ifm->ifi_change) | +- (dev->flags & ~ifm->ifi_change); ++ (rtnl_dev_get_flags(dev) & ~ifm->ifi_change); + + return flags; + } diff --git a/queue-3.5/net-tun-fix-ioctl-based-info-leaks.patch b/queue-3.5/net-tun-fix-ioctl-based-info-leaks.patch new file mode 100644 index 00000000000..738327ebcfa --- /dev/null +++ b/queue-3.5/net-tun-fix-ioctl-based-info-leaks.patch @@ -0,0 +1,39 @@ +From 8792d0c90a7952d7677cf197bbd504028352361e Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 29 Jul 2012 19:45:14 +0000 +Subject: net/tun: fix ioctl() based info leaks + + +From: Mathias Krause + +[ Upstream commits a117dacde0288f3ec60b6e5bcedae8fa37ee0dfc + and 8bbb181308bc348e02bfdbebdedd4e4ec9d452ce ] + +The tun module leaks up to 36 bytes of memory by not fully initializing +a structure located on the stack that gets copied to user memory by the +TUNGETIFF and SIOCGIFHWADDR ioctl()s. + +Signed-off-by: Mathias Krause +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/tun.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/tun.c ++++ b/drivers/net/tun.c +@@ -1255,10 +1255,12 @@ static long __tun_chr_ioctl(struct file + int vnet_hdr_sz; + int ret; + +- if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) ++ if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) { + if (copy_from_user(&ifr, argp, ifreq_len)) + return -EFAULT; +- ++ } else { ++ memset(&ifr, 0, sizeof(ifr)); ++ } + if (cmd == TUNGETFEATURES) { + /* Currently this just means: "what IFF flags are valid?". + * This is needed because we never checked for invalid flags on diff --git a/queue-3.5/r8169-revert-add-byte-queue-limit-support.patch b/queue-3.5/r8169-revert-add-byte-queue-limit-support.patch new file mode 100644 index 00000000000..65b77f961ef --- /dev/null +++ b/queue-3.5/r8169-revert-add-byte-queue-limit-support.patch @@ -0,0 +1,92 @@ +From 895ec173842174bba01946902f65fe15559a29ea Mon Sep 17 00:00:00 2001 +From: Francois Romieu +Date: Mon, 23 Jul 2012 22:55:55 +0200 +Subject: r8169: revert "add byte queue limit support". + + +From: Francois Romieu + +[ Upstream commit 17bcb684f08649a2ab6a7dcd8288332e72d208f1 ] + +This reverts commit 036dafa28da1e2565a8529de2ae663c37b7a0060. + +First it appears in bisection, then reverting it solves the usual +netdev watchdog problem for different people. I don't have a proper +fix yet so get rid of it. + +Bisected-and-reported-by: Alex VillacĂ­s Lasso +Signed-off-by: Francois Romieu +Cc: Josh Boyer +Cc: Hayes Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/realtek/r8169.c | 27 +++++---------------------- + 1 file changed, 5 insertions(+), 22 deletions(-) + +--- a/drivers/net/ethernet/realtek/r8169.c ++++ b/drivers/net/ethernet/realtek/r8169.c +@@ -5380,7 +5380,6 @@ static void rtl8169_tx_clear(struct rtl8 + { + rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); + tp->cur_tx = tp->dirty_tx = 0; +- netdev_reset_queue(tp->dev); + } + + static void rtl_reset_work(struct rtl8169_private *tp) +@@ -5535,8 +5534,6 @@ static netdev_tx_t rtl8169_start_xmit(st + + txd->opts2 = cpu_to_le32(opts[1]); + +- netdev_sent_queue(dev, skb->len); +- + skb_tx_timestamp(skb); + + wmb(); +@@ -5633,16 +5630,9 @@ static void rtl8169_pcierr_interrupt(str + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); + } + +-struct rtl_txc { +- int packets; +- int bytes; +-}; +- + static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) + { +- struct rtl8169_stats *tx_stats = &tp->tx_stats; + unsigned int dirty_tx, tx_left; +- struct rtl_txc txc = { 0, 0 }; + + dirty_tx = tp->dirty_tx; + smp_rmb(); +@@ -5661,24 +5651,17 @@ static void rtl_tx(struct net_device *de + rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, + tp->TxDescArray + entry); + if (status & LastFrag) { +- struct sk_buff *skb = tx_skb->skb; +- +- txc.packets++; +- txc.bytes += skb->len; +- dev_kfree_skb(skb); ++ u64_stats_update_begin(&tp->tx_stats.syncp); ++ tp->tx_stats.packets++; ++ tp->tx_stats.bytes += tx_skb->skb->len; ++ u64_stats_update_end(&tp->tx_stats.syncp); ++ dev_kfree_skb(tx_skb->skb); + tx_skb->skb = NULL; + } + dirty_tx++; + tx_left--; + } + +- u64_stats_update_begin(&tx_stats->syncp); +- tx_stats->packets += txc.packets; +- tx_stats->bytes += txc.bytes; +- u64_stats_update_end(&tx_stats->syncp); +- +- netdev_completed_queue(dev, txc.packets, txc.bytes); +- + if (tp->dirty_tx != dirty_tx) { + tp->dirty_tx = dirty_tx; + /* Sync with rtl8169_start_xmit: diff --git a/queue-3.5/series b/queue-3.5/series index 342add3d992..be656c5293b 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -97,3 +97,12 @@ ext4-don-t-let-i_reserved_meta_blocks-go-negative.patch ext4-undo-ext4_calc_metadata_amount-if-we-fail-to-claim-space.patch ext4-use-proper-csum-calculation-in-ext4_rename.patch ext4-use-s_csum_seed-instead-of-i_csum_seed-for-xattr-block.patch +net-fix-references-to-out-of-scope-variables-in-put_cmsg_compat.patch +r8169-revert-add-byte-queue-limit-support.patch +caif-fix-null-pointer-check.patch +wanmain-comparing-array-with-null.patch +tcp-add-tcp_user_timeout-negative-value-check.patch +usb-kaweth.c-use-gfp_atomic-under-spin_lock.patch +net-fix-rtnetlink-iff_promisc-and-iff_allmulti-handling.patch +tcp-perform-dma-to-userspace-only-if-there-is-a-task-waiting-for-it.patch +net-tun-fix-ioctl-based-info-leaks.patch diff --git a/queue-3.5/tcp-add-tcp_user_timeout-negative-value-check.patch b/queue-3.5/tcp-add-tcp_user_timeout-negative-value-check.patch new file mode 100644 index 00000000000..6baf497ee41 --- /dev/null +++ b/queue-3.5/tcp-add-tcp_user_timeout-negative-value-check.patch @@ -0,0 +1,37 @@ +From f4f6a0061b804289da8bcdd5ce47429acb0fa08d Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +Date: Thu, 26 Jul 2012 22:52:21 +0000 +Subject: tcp: Add TCP_USER_TIMEOUT negative value check + + +From: Hangbin Liu + +[ Upstream commit 42493570100b91ef663c4c6f0c0fdab238f9d3c2 ] + +TCP_USER_TIMEOUT is a TCP level socket option that takes an unsigned int. But +patch "tcp: Add TCP_USER_TIMEOUT socket option"(dca43c75) didn't check the negative +values. If a user assign -1 to it, the socket will set successfully and wait +for 4294967295 miliseconds. This patch add a negative value check to avoid +this issue. + +Signed-off-by: Hangbin Liu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2625,7 +2625,10 @@ static int do_tcp_setsockopt(struct sock + /* Cap the max timeout in ms TCP will retry/retrans + * before giving up and aborting (ETIMEDOUT) a connection. + */ +- icsk->icsk_user_timeout = msecs_to_jiffies(val); ++ if (val < 0) ++ err = -EINVAL; ++ else ++ icsk->icsk_user_timeout = msecs_to_jiffies(val); + break; + default: + err = -ENOPROTOOPT; diff --git a/queue-3.5/tcp-perform-dma-to-userspace-only-if-there-is-a-task-waiting-for-it.patch b/queue-3.5/tcp-perform-dma-to-userspace-only-if-there-is-a-task-waiting-for-it.patch new file mode 100644 index 00000000000..f53672e0a01 --- /dev/null +++ b/queue-3.5/tcp-perform-dma-to-userspace-only-if-there-is-a-task-waiting-for-it.patch @@ -0,0 +1,54 @@ +From 3e241e1c7f427c937000fd51e8fe13719ce7afca Mon Sep 17 00:00:00 2001 +From: Jiri Kosina +Date: Fri, 27 Jul 2012 10:38:50 +0000 +Subject: tcp: perform DMA to userspace only if there is a task waiting for it + + +From: Jiri Kosina + +[ Upstream commit 59ea33a68a9083ac98515e4861c00e71efdc49a1 ] + +Back in 2006, commit 1a2449a87b ("[I/OAT]: TCP recv offload to I/OAT") +added support for receive offloading to IOAT dma engine if available. + +The code in tcp_rcv_established() tries to perform early DMA copy if +applicable. It however does so without checking whether the userspace +task is actually expecting the data in the buffer. + +This is not a problem under normal circumstances, but there is a corner +case where this doesn't work -- and that's when MSG_TRUNC flag to +recvmsg() is used. + +If the IOAT dma engine is not used, the code properly checks whether +there is a valid ucopy.task and the socket is owned by userspace, but +misses the check in the dmaengine case. + +This problem can be observed in real trivially -- for example 'tbench' is a +good reproducer, as it makes a heavy use of MSG_TRUNC. On systems utilizing +IOAT, you will soon find tbench waiting indefinitely in sk_wait_data(), as they +have been already early-copied in tcp_rcv_established() using dma engine. + +This patch introduces the same check we are performing in the simple +iovec copy case to the IOAT case as well. It fixes the indefinite +recvmsg(MSG_TRUNC) hangs. + +Signed-off-by: Jiri Kosina +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5602,7 +5602,9 @@ int tcp_rcv_established(struct sock *sk, + if (tp->copied_seq == tp->rcv_nxt && + len - tcp_header_len <= tp->ucopy.len) { + #ifdef CONFIG_NET_DMA +- if (tcp_dma_try_early_copy(sk, skb, tcp_header_len)) { ++ if (tp->ucopy.task == current && ++ sock_owned_by_user(sk) && ++ tcp_dma_try_early_copy(sk, skb, tcp_header_len)) { + copied_early = 1; + eaten = 1; + } diff --git a/queue-3.5/usb-kaweth.c-use-gfp_atomic-under-spin_lock.patch b/queue-3.5/usb-kaweth.c-use-gfp_atomic-under-spin_lock.patch new file mode 100644 index 00000000000..a53246b237c --- /dev/null +++ b/queue-3.5/usb-kaweth.c-use-gfp_atomic-under-spin_lock.patch @@ -0,0 +1,38 @@ +From 9be1965516b5222212def100b3a1afba32836878 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Fri, 27 Jul 2012 01:46:51 +0000 +Subject: USB: kaweth.c: use GFP_ATOMIC under spin_lock + + +From: Dan Carpenter + +[ Upstream commit e4c7f259c5be99dcfc3d98f913590663b0305bf8 ] + +The problem is that we call this with a spin lock held. The call tree +is: + kaweth_start_xmit() holds kaweth->device_lock. + -> kaweth_async_set_rx_mode() + -> kaweth_control() + -> kaweth_internal_control_msg() + +The kaweth_internal_control_msg() function is only called from +kaweth_control() which used GFP_ATOMIC for its allocations. + +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/kaweth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/kaweth.c ++++ b/drivers/net/usb/kaweth.c +@@ -1314,7 +1314,7 @@ static int kaweth_internal_control_msg(s + int retv; + int length = 0; /* shut up GCC */ + +- urb = usb_alloc_urb(0, GFP_NOIO); ++ urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + diff --git a/queue-3.5/wanmain-comparing-array-with-null.patch b/queue-3.5/wanmain-comparing-array-with-null.patch new file mode 100644 index 00000000000..566b7184508 --- /dev/null +++ b/queue-3.5/wanmain-comparing-array-with-null.patch @@ -0,0 +1,82 @@ +From ae9b4d61397057fcc252fac4a6a4021a98519505 Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Tue, 24 Jul 2012 08:16:25 +0000 +Subject: wanmain: comparing array with NULL + + +From: Alan Cox + +[ Upstream commit 8b72ff6484fe303e01498b58621810a114f3cf09 ] + +gcc really should warn about these ! + +Signed-off-by: Alan Cox +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/wanrouter/wanmain.c | 53 +++++++++++++++++++++--------------------------- + 1 file changed, 24 insertions(+), 29 deletions(-) + +--- a/net/wanrouter/wanmain.c ++++ b/net/wanrouter/wanmain.c +@@ -602,36 +602,31 @@ static int wanrouter_device_new_if(struc + * successfully, add it to the interface list. + */ + +- if (dev->name == NULL) { +- err = -EINVAL; +- } else { +- +- #ifdef WANDEBUG +- printk(KERN_INFO "%s: registering interface %s...\n", +- wanrouter_modname, dev->name); +- #endif +- +- err = register_netdev(dev); +- if (!err) { +- struct net_device *slave = NULL; +- unsigned long smp_flags=0; +- +- lock_adapter_irq(&wandev->lock, &smp_flags); +- +- if (wandev->dev == NULL) { +- wandev->dev = dev; +- } else { +- for (slave=wandev->dev; +- DEV_TO_SLAVE(slave); +- slave = DEV_TO_SLAVE(slave)) +- DEV_TO_SLAVE(slave) = dev; +- } +- ++wandev->ndev; +- +- unlock_adapter_irq(&wandev->lock, &smp_flags); +- err = 0; /* done !!! */ +- goto out; ++#ifdef WANDEBUG ++ printk(KERN_INFO "%s: registering interface %s...\n", ++ wanrouter_modname, dev->name); ++#endif ++ ++ err = register_netdev(dev); ++ if (!err) { ++ struct net_device *slave = NULL; ++ unsigned long smp_flags=0; ++ ++ lock_adapter_irq(&wandev->lock, &smp_flags); ++ ++ if (wandev->dev == NULL) { ++ wandev->dev = dev; ++ } else { ++ for (slave=wandev->dev; ++ DEV_TO_SLAVE(slave); ++ slave = DEV_TO_SLAVE(slave)) ++ DEV_TO_SLAVE(slave) = dev; + } ++ ++wandev->ndev; ++ ++ unlock_adapter_irq(&wandev->lock, &smp_flags); ++ err = 0; /* done !!! */ ++ goto out; + } + if (wandev->del_if) + wandev->del_if(wandev, dev);