From: Greg Kroah-Hartman Date: Tue, 28 Jul 2009 19:19:12 +0000 (-0700) Subject: more .30 patches X-Git-Tag: v2.6.30.4~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9acbb381cfb835a745a6c8abab62e0ccf1af4ffe;p=thirdparty%2Fkernel%2Fstable-queue.git more .30 patches --- diff --git a/queue-2.6.30/input-wistron_btns-recognize-maxdata-pro-7000-notebooks.patch b/queue-2.6.30/input-wistron_btns-recognize-maxdata-pro-7000-notebooks.patch new file mode 100644 index 00000000000..645052c7285 --- /dev/null +++ b/queue-2.6.30/input-wistron_btns-recognize-maxdata-pro-7000-notebooks.patch @@ -0,0 +1,45 @@ +From e705cee427e319665969ef7ac664f3612dec8899 Mon Sep 17 00:00:00 2001 +From: Giuseppe Mazzotta +Date: Sun, 12 Jul 2009 21:02:27 -0700 +Subject: Input: wistron_btns - recognize Maxdata Pro 7000 notebooks + +From: Giuseppe Mazzotta + +commit e705cee427e319665969ef7ac664f3612dec8899 upstream. + +This patch adds DMI information to automatically load the correct +layout for the Maxdata Pro 7000X/DX notebook models. Such notebooks +are clones of Fujitsu Amilo V2000, the hook for the v2000 is being +used and I have tested that perfectly works. + +The immediate result of integrating this patch is that the five +special buttons will work on these specific notebook models and that +the RF killswitch will not be activated after suspend. This patch +definitively obsoletes the fsam7400 module which I was still needing +to enable wifi and to fix the RF killswitch suspend problem; in the +current 2.6.30 kernel it is necessary to load the wistron_btns module +with options 'force=1 keymap=1557/MS2141', which was not anyway a +complete workaround. + +Signed-off-by: Giuseppe Mazzotta +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- a/drivers/input/misc/wistron_btns.c ++++ b/drivers/input/misc/wistron_btns.c +@@ -646,6 +646,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { + }, + { + .callback = dmi_matched, ++ .ident = "Maxdata Pro 7000 DX", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), ++ }, ++ .driver_data = keymap_fs_amilo_pro_v2000 ++ }, ++ { ++ .callback = dmi_matched, + .ident = "Fujitsu N3510", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), diff --git a/queue-2.6.30/libata-fix-follow-up-srst-failure-path.patch b/queue-2.6.30/libata-fix-follow-up-srst-failure-path.patch new file mode 100644 index 00000000000..39ce8437fef --- /dev/null +++ b/queue-2.6.30/libata-fix-follow-up-srst-failure-path.patch @@ -0,0 +1,36 @@ +From fe2c4d018fc6127610fef677e020b3bb41cfaaaf Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Wed, 8 Jul 2009 12:16:37 +0900 +Subject: libata: fix follow-up SRST failure path + +From: Tejun Heo + +commit fe2c4d018fc6127610fef677e020b3bb41cfaaaf upstream. + +ata_eh_reset() was missing error return handling after follow-up SRST +allowing EH to continue the normal probing path after reset failure. +This was discovered while testing new WD 2TB drives which take longer +than 10 secs to spin up and cause the first follow-up SRST to time +out. + +Signed-off-by: Tejun Heo +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/libata-eh.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2517,6 +2517,10 @@ int ata_eh_reset(struct ata_link *link, + + ata_eh_about_to_do(link, NULL, ATA_EH_RESET); + rc = ata_do_reset(link, reset, classes, deadline, true); ++ if (rc) { ++ failed_link = link; ++ goto fail; ++ } + } + } else { + if (verbose) diff --git a/queue-2.6.30/netdev-restore-mac-address-set-and-validate-operations.patch b/queue-2.6.30/netdev-restore-mac-address-set-and-validate-operations.patch new file mode 100644 index 00000000000..354493a45a4 --- /dev/null +++ b/queue-2.6.30/netdev-restore-mac-address-set-and-validate-operations.patch @@ -0,0 +1,145 @@ +From 240c102d9c54fee7fdc87a4ef2fabc7eb539e00a Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 9 Jul 2009 17:54:35 +0000 +Subject: netdev: restore MAC address set and validate operations + +From: Ben Hutchings + +commit 240c102d9c54fee7fdc87a4ef2fabc7eb539e00a upstream. + +alloc_etherdev() used to install default implementations of these +operations, but they must now be explicitly installed in struct +net_device_ops. + +Signed-off-by: Ben Hutchings +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/arm/ixp4xx_eth.c | 3 ++- + drivers/net/ehea/ehea_main.c | 1 + + drivers/net/gianfar.c | 2 ++ + drivers/net/plip.c | 2 ++ + drivers/net/ps3_gelic_net.c | 1 + + drivers/net/ps3_gelic_wireless.c | 1 + + drivers/net/sunvnet.c | 1 + + drivers/net/usb/kaweth.c | 2 ++ + drivers/net/usb/pegasus.c | 2 ++ + drivers/net/wireless/orinoco/main.c | 3 ++- + 10 files changed, 16 insertions(+), 2 deletions(-) + +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -1140,7 +1140,8 @@ static const struct net_device_ops ixp4x + .ndo_start_xmit = eth_xmit, + .ndo_set_multicast_list = eth_set_mcast_list, + .ndo_do_ioctl = eth_ioctl, +- ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + }; + + static int __devinit eth_init_one(struct platform_device *pdev) +--- a/drivers/net/ehea/ehea_main.c ++++ b/drivers/net/ehea/ehea_main.c +@@ -3081,6 +3081,7 @@ static const struct net_device_ops ehea_ + #endif + .ndo_get_stats = ehea_get_stats, + .ndo_set_mac_address = ehea_set_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + .ndo_set_multicast_list = ehea_set_multicast_list, + .ndo_change_mtu = ehea_change_mtu, + .ndo_vlan_rx_register = ehea_vlan_rx_register, +--- a/drivers/net/gianfar.c ++++ b/drivers/net/gianfar.c +@@ -155,6 +155,8 @@ static const struct net_device_ops gfar_ + .ndo_tx_timeout = gfar_timeout, + .ndo_do_ioctl = gfar_ioctl, + .ndo_vlan_rx_register = gfar_vlan_rx_register, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = gfar_netpoll, + #endif +--- a/drivers/net/plip.c ++++ b/drivers/net/plip.c +@@ -270,6 +270,8 @@ static const struct net_device_ops plip_ + .ndo_stop = plip_close, + .ndo_start_xmit = plip_tx_packet, + .ndo_do_ioctl = plip_ioctl, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + }; + + /* Entry point of PLIP driver. +--- a/drivers/net/ps3_gelic_net.c ++++ b/drivers/net/ps3_gelic_net.c +@@ -1410,6 +1410,7 @@ static const struct net_device_ops gelic + .ndo_set_multicast_list = gelic_net_set_multi, + .ndo_change_mtu = gelic_net_change_mtu, + .ndo_tx_timeout = gelic_net_tx_timeout, ++ .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = gelic_net_poll_controller, +--- a/drivers/net/ps3_gelic_wireless.c ++++ b/drivers/net/ps3_gelic_wireless.c +@@ -2707,6 +2707,7 @@ static const struct net_device_ops gelic + .ndo_set_multicast_list = gelic_net_set_multi, + .ndo_change_mtu = gelic_net_change_mtu, + .ndo_tx_timeout = gelic_net_tx_timeout, ++ .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + #ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = gelic_net_poll_controller, +--- a/drivers/net/sunvnet.c ++++ b/drivers/net/sunvnet.c +@@ -1017,6 +1017,7 @@ static const struct net_device_ops vnet_ + .ndo_stop = vnet_close, + .ndo_set_multicast_list = vnet_set_rx_mode, + .ndo_set_mac_address = vnet_set_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + .ndo_tx_timeout = vnet_tx_timeout, + .ndo_change_mtu = vnet_change_mtu, + .ndo_start_xmit = vnet_start_xmit, +--- a/drivers/net/usb/kaweth.c ++++ b/drivers/net/usb/kaweth.c +@@ -982,6 +982,8 @@ static const struct net_device_ops kawet + .ndo_tx_timeout = kaweth_tx_timeout, + .ndo_set_multicast_list = kaweth_set_rx_mode, + .ndo_get_stats = kaweth_netdev_stats, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + }; + + static int kaweth_probe( +--- a/drivers/net/usb/pegasus.c ++++ b/drivers/net/usb/pegasus.c +@@ -1493,6 +1493,8 @@ static const struct net_device_ops pegas + .ndo_set_multicast_list = pegasus_set_multicast, + .ndo_get_stats = pegasus_netdev_stats, + .ndo_tx_timeout = pegasus_tx_timeout, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + }; + + static struct usb_driver pegasus_driver = { +--- a/drivers/net/wireless/orinoco/main.c ++++ b/drivers/net/wireless/orinoco/main.c +@@ -2521,6 +2521,8 @@ static const struct net_device_ops orino + .ndo_start_xmit = orinoco_xmit, + .ndo_set_multicast_list = orinoco_set_multicast_list, + .ndo_change_mtu = orinoco_change_mtu, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_validate_addr = eth_validate_addr, + .ndo_tx_timeout = orinoco_tx_timeout, + .ndo_get_stats = orinoco_get_stats, + }; +@@ -2555,7 +2557,6 @@ struct net_device + priv->wireless_data.spy_data = &priv->spy_data; + dev->wireless_data = &priv->wireless_data; + #endif +- /* we use the default eth_mac_addr for setting the MAC addr */ + + /* Reserve space in skb for the SNAP header */ + dev->hard_header_len += ENCAPS_OVERHEAD; diff --git a/queue-2.6.30/netdev-restore-mtu-change-operation.patch b/queue-2.6.30/netdev-restore-mtu-change-operation.patch new file mode 100644 index 00000000000..975ce777675 --- /dev/null +++ b/queue-2.6.30/netdev-restore-mtu-change-operation.patch @@ -0,0 +1,134 @@ +From ben@decadent.org.uk Tue Jul 28 12:05:43 2009 +From: Ben Hutchings +Date: Sun, 12 Jul 2009 23:56:27 +0100 +Subject: netdev: restore MTU change operation +To: stable@kernel.org +Message-ID: <1247439387.21924.190.camel@deadeye> + +From: Ben Hutchings + +commit 635ecaa70e862f85f652581305fe0074810893be upstream + +netdev: restore MTU change operation + +alloc_etherdev() used to install a default implementation of this +operation, but it must now be explicitly installed in struct +net_device_ops. + +Signed-off-by: Ben Hutchings +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/8139too.c | 1 + + drivers/net/arm/ixp4xx_eth.c | 1 + + drivers/net/ehea/ehea_main.c | 1 + + drivers/net/plip.c | 1 + + drivers/net/smc91x.c | 1 + + drivers/net/smsc911x.c | 1 + + drivers/net/sunvnet.c | 1 + + drivers/net/usb/kaweth.c | 1 + + drivers/net/usb/pegasus.c | 1 + + drivers/net/via-rhine.c | 1 + + 10 files changed, 10 insertions(+) + +--- a/drivers/net/8139too.c ++++ b/drivers/net/8139too.c +@@ -917,6 +917,7 @@ static const struct net_device_ops rtl81 + .ndo_open = rtl8139_open, + .ndo_stop = rtl8139_close, + .ndo_get_stats = rtl8139_get_stats, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = rtl8139_set_mac_address, + .ndo_start_xmit = rtl8139_start_xmit, +--- a/drivers/net/arm/ixp4xx_eth.c ++++ b/drivers/net/arm/ixp4xx_eth.c +@@ -1140,6 +1140,7 @@ static const struct net_device_ops ixp4x + .ndo_start_xmit = eth_xmit, + .ndo_set_multicast_list = eth_set_mcast_list, + .ndo_do_ioctl = eth_ioctl, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + }; +--- a/drivers/net/ehea/ehea_main.c ++++ b/drivers/net/ehea/ehea_main.c +@@ -3080,6 +3080,7 @@ static const struct net_device_ops ehea_ + .ndo_poll_controller = ehea_netpoll, + #endif + .ndo_get_stats = ehea_get_stats, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = ehea_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_multicast_list = ehea_set_multicast_list, +--- a/drivers/net/plip.c ++++ b/drivers/net/plip.c +@@ -270,6 +270,7 @@ static const struct net_device_ops plip_ + .ndo_stop = plip_close, + .ndo_start_xmit = plip_tx_packet, + .ndo_do_ioctl = plip_ioctl, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + }; +--- a/drivers/net/smc91x.c ++++ b/drivers/net/smc91x.c +@@ -1774,6 +1774,7 @@ static const struct net_device_ops smc_n + .ndo_start_xmit = smc_hard_start_xmit, + .ndo_tx_timeout = smc_timeout, + .ndo_set_multicast_list = smc_set_multicast_list, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + #ifdef CONFIG_NET_POLL_CONTROLLER +--- a/drivers/net/smsc911x.c ++++ b/drivers/net/smsc911x.c +@@ -1766,6 +1766,7 @@ static const struct net_device_ops smsc9 + .ndo_get_stats = smsc911x_get_stats, + .ndo_set_multicast_list = smsc911x_set_multicast_list, + .ndo_do_ioctl = smsc911x_do_ioctl, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = smsc911x_set_mac_address, + #ifdef CONFIG_NET_POLL_CONTROLLER +--- a/drivers/net/sunvnet.c ++++ b/drivers/net/sunvnet.c +@@ -1016,6 +1016,7 @@ static const struct net_device_ops vnet_ + .ndo_open = vnet_open, + .ndo_stop = vnet_close, + .ndo_set_multicast_list = vnet_set_rx_mode, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = vnet_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_tx_timeout = vnet_tx_timeout, +--- a/drivers/net/usb/kaweth.c ++++ b/drivers/net/usb/kaweth.c +@@ -982,6 +982,7 @@ static const struct net_device_ops kawet + .ndo_tx_timeout = kaweth_tx_timeout, + .ndo_set_multicast_list = kaweth_set_rx_mode, + .ndo_get_stats = kaweth_netdev_stats, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + }; +--- a/drivers/net/usb/pegasus.c ++++ b/drivers/net/usb/pegasus.c +@@ -1493,6 +1493,7 @@ static const struct net_device_ops pegas + .ndo_set_multicast_list = pegasus_set_multicast, + .ndo_get_stats = pegasus_netdev_stats, + .ndo_tx_timeout = pegasus_tx_timeout, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + }; +--- a/drivers/net/via-rhine.c ++++ b/drivers/net/via-rhine.c +@@ -622,6 +622,7 @@ static const struct net_device_ops rhine + .ndo_start_xmit = rhine_start_tx, + .ndo_get_stats = rhine_get_stats, + .ndo_set_multicast_list = rhine_set_rx_mode, ++ .ndo_change_mtu = eth_change_mtu, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = eth_mac_addr, + .ndo_do_ioctl = netdev_ioctl, diff --git a/queue-2.6.30/netfilter-nf_conntrack-fix-confirmation-race-condition.patch b/queue-2.6.30/netfilter-nf_conntrack-fix-confirmation-race-condition.patch new file mode 100644 index 00000000000..3c3e109a578 --- /dev/null +++ b/queue-2.6.30/netfilter-nf_conntrack-fix-confirmation-race-condition.patch @@ -0,0 +1,51 @@ +From 5c8ec910e789a92229978d8fd1fce7b62e8ac711 Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Mon, 22 Jun 2009 14:14:16 +0200 +Subject: netfilter: nf_conntrack: fix confirmation race condition + +From: Patrick McHardy + +commit 5c8ec910e789a92229978d8fd1fce7b62e8ac711 upstream. + +New connection tracking entries are inserted into the hash before they +are fully set up, namely the CONFIRMED bit is not set and the timer not +started yet. This can theoretically lead to a race with timer, which +would set the timeout value to a relative value, most likely already in +the past. + +Perform hash insertion as the final step to fix this. + +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_conntrack_core.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -385,7 +385,6 @@ __nf_conntrack_confirm(struct sk_buff *s + /* Remove from unconfirmed list */ + hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); + +- __nf_conntrack_hash_insert(ct, hash, repl_hash); + /* Timer relative to confirmation time, not original + setting time, otherwise we'd get timer wrap in + weird delay cases. */ +@@ -393,8 +392,16 @@ __nf_conntrack_confirm(struct sk_buff *s + add_timer(&ct->timeout); + atomic_inc(&ct->ct_general.use); + set_bit(IPS_CONFIRMED_BIT, &ct->status); ++ ++ /* Since the lookup is lockless, hash insertion must be done after ++ * starting the timer and setting the CONFIRMED bit. The RCU barriers ++ * guarantee that no other CPU can find the conntrack before the above ++ * stores are visible. ++ */ ++ __nf_conntrack_hash_insert(ct, hash, repl_hash); + NF_CT_STAT_INC(net, insert); + spin_unlock_bh(&nf_conntrack_lock); ++ + help = nfct_help(ct); + if (help && help->helper) + nf_conntrack_event_cache(IPCT_HELPER, ct); diff --git a/queue-2.6.30/netfilter-nf_conntrack-fix-conntrack-lookup-race.patch b/queue-2.6.30/netfilter-nf_conntrack-fix-conntrack-lookup-race.patch new file mode 100644 index 00000000000..557766140f2 --- /dev/null +++ b/queue-2.6.30/netfilter-nf_conntrack-fix-conntrack-lookup-race.patch @@ -0,0 +1,44 @@ +From 8d8890b7751387f58ce0a6428773de2fbc0fd596 Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Mon, 22 Jun 2009 14:14:41 +0200 +Subject: netfilter: nf_conntrack: fix conntrack lookup race + +From: Patrick McHardy + +commit 8d8890b7751387f58ce0a6428773de2fbc0fd596 upstream. + +The RCU protected conntrack hash lookup only checks whether the entry +has a refcount of zero to decide whether it is stale. This is not +sufficient, entries are explicitly removed while there is at least +one reference left, possibly more. Explicitly check whether the entry +has been marked as dying to fix this. + +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_conntrack_core.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -295,7 +295,8 @@ begin: + h = __nf_conntrack_find(net, tuple); + if (h) { + ct = nf_ct_tuplehash_to_ctrack(h); +- if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) ++ if (unlikely(nf_ct_is_dying(ct) || ++ !atomic_inc_not_zero(&ct->ct_general.use))) + h = NULL; + else { + if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple))) { +@@ -474,7 +475,8 @@ static noinline int early_drop(struct ne + cnt++; + } + +- if (ct && unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) ++ if (ct && unlikely(nf_ct_is_dying(ct) || ++ !atomic_inc_not_zero(&ct->ct_general.use))) + ct = NULL; + if (ct || cnt >= NF_CT_EVICTION_RANGE) + break; diff --git a/queue-2.6.30/netfilter-nf_log-fix-direct-userspace-memory-access-in-proc-handler.patch b/queue-2.6.30/netfilter-nf_log-fix-direct-userspace-memory-access-in-proc-handler.patch new file mode 100644 index 00000000000..b516050187c --- /dev/null +++ b/queue-2.6.30/netfilter-nf_log-fix-direct-userspace-memory-access-in-proc-handler.patch @@ -0,0 +1,65 @@ +From 249556192859490b6280552d4b877064f9f5ee48 Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Mon, 22 Jun 2009 14:15:30 +0200 +Subject: netfilter: nf_log: fix direct userspace memory access in proc handler + +From: Patrick McHardy + +commit 249556192859490b6280552d4b877064f9f5ee48 upstream. + +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_log.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -47,7 +47,6 @@ int nf_log_register(u_int8_t pf, struct + mutex_lock(&nf_log_mutex); + + if (pf == NFPROTO_UNSPEC) { +- int i; + for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) + list_add_tail(&(logger->list[i]), &(nf_loggers_l[i])); + } else { +@@ -216,7 +215,7 @@ static const struct file_operations nflo + #endif /* PROC_FS */ + + #ifdef CONFIG_SYSCTL +-struct ctl_path nf_log_sysctl_path[] = { ++static struct ctl_path nf_log_sysctl_path[] = { + { .procname = "net", .ctl_name = CTL_NET, }, + { .procname = "netfilter", .ctl_name = NET_NETFILTER, }, + { .procname = "nf_log", .ctl_name = CTL_UNNUMBERED, }, +@@ -228,19 +227,26 @@ static struct ctl_table nf_log_sysctl_ta + static struct ctl_table_header *nf_log_dir_header; + + static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp, +- void *buffer, size_t *lenp, loff_t *ppos) ++ void __user *buffer, size_t *lenp, loff_t *ppos) + { + const struct nf_logger *logger; ++ char buf[NFLOGGER_NAME_LEN]; ++ size_t size = *lenp; + int r = 0; + int tindex = (unsigned long)table->extra1; + + if (write) { +- if (!strcmp(buffer, "NONE")) { ++ if (size > sizeof(buf)) ++ size = sizeof(buf); ++ if (copy_from_user(buf, buffer, size)) ++ return -EFAULT; ++ ++ if (!strcmp(buf, "NONE")) { + nf_log_unbind_pf(tindex); + return 0; + } + mutex_lock(&nf_log_mutex); +- logger = __find_logger(tindex, buffer); ++ logger = __find_logger(tindex, buf); + if (logger == NULL) { + mutex_unlock(&nf_log_mutex); + return -ENOENT; diff --git a/queue-2.6.30/netfilter-nf_log-fix-sleeping-function-called-from-invalid-context.patch b/queue-2.6.30/netfilter-nf_log-fix-sleeping-function-called-from-invalid-context.patch new file mode 100644 index 00000000000..d584de870e6 --- /dev/null +++ b/queue-2.6.30/netfilter-nf_log-fix-sleeping-function-called-from-invalid-context.patch @@ -0,0 +1,65 @@ +From 266d07cb1c9a0c345d7d3aea889f92062894059e Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Sat, 13 Jun 2009 12:21:10 +0200 +Subject: netfilter: nf_log: fix sleeping function called from invalid context +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +From: Patrick McHardy + +commit 266d07cb1c9a0c345d7d3aea889f92062894059e upstream. + +Fix regression introduced by 17625274 "netfilter: sysctl support of +logger choice": + +BUG: sleeping function called from invalid context at /mnt/s390test/linux-2.6-tip/arch/s390/include/asm/uaccess.h:234 +in_atomic(): 1, irqs_disabled(): 0, pid: 3245, name: sysctl +CPU: 1 Not tainted 2.6.30-rc8-tipjun10-02053-g39ae214 #1 +Process sysctl (pid: 3245, task: 000000007f675da0, ksp: 000000007eb17cf0) +0000000000000000 000000007eb17be8 0000000000000002 0000000000000000 + 000000007eb17c88 000000007eb17c00 000000007eb17c00 0000000000048156 + 00000000003e2de8 000000007f676118 000000007eb17f10 0000000000000000 + 0000000000000000 000000007eb17be8 000000000000000d 000000007eb17c58 + 00000000003e2050 000000000001635c 000000007eb17be8 000000007eb17c30 +Call Trace: +(Ý<00000000000162e6>¨ show_trace+0x13a/0x148) + Ý<00000000000349ea>¨ __might_sleep+0x13a/0x164 + Ý<0000000000050300>¨ proc_dostring+0x134/0x22c + Ý<0000000000312b70>¨ nf_log_proc_dostring+0xfc/0x188 + Ý<0000000000136f5e>¨ proc_sys_call_handler+0xf6/0x118 + Ý<0000000000136fda>¨ proc_sys_read+0x26/0x34 + Ý<00000000000d6e9c>¨ vfs_read+0xac/0x158 + Ý<00000000000d703e>¨ SyS_read+0x56/0x88 + Ý<0000000000027f42>¨ sysc_noemu+0x10/0x16 + +Use the nf_log_mutex instead of RCU to fix this. + +Reported-and-tested-by: Maran Pakkirisamy +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_log.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -248,14 +248,14 @@ static int nf_log_proc_dostring(ctl_tabl + rcu_assign_pointer(nf_loggers[tindex], logger); + mutex_unlock(&nf_log_mutex); + } else { +- rcu_read_lock(); +- logger = rcu_dereference(nf_loggers[tindex]); ++ mutex_lock(&nf_log_mutex); ++ logger = nf_loggers[tindex]; + if (!logger) + table->data = "NONE"; + else + table->data = logger->name; + r = proc_dostring(table, write, filp, buffer, lenp, ppos); +- rcu_read_unlock(); ++ mutex_unlock(&nf_log_mutex); + } + + return r; diff --git a/queue-2.6.30/netfilter-tcp-conntrack-fix-unacknowledged-data-detection-with-nat.patch b/queue-2.6.30/netfilter-tcp-conntrack-fix-unacknowledged-data-detection-with-nat.patch new file mode 100644 index 00000000000..14ee9b0b08e --- /dev/null +++ b/queue-2.6.30/netfilter-tcp-conntrack-fix-unacknowledged-data-detection-with-nat.patch @@ -0,0 +1,115 @@ +From a3a9f79e361e864f0e9d75ebe2a0cb43d17c4272 Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Mon, 29 Jun 2009 14:07:56 +0200 +Subject: netfilter: tcp conntrack: fix unacknowledged data detection with NAT + +From: Patrick McHardy + +commit a3a9f79e361e864f0e9d75ebe2a0cb43d17c4272 upstream. + +When NAT helpers change the TCP packet size, the highest seen sequence +number needs to be corrected. This is currently only done upwards, when +the packet size is reduced the sequence number is unchanged. This causes +TCP conntrack to falsely detect unacknowledged data and decrease the +timeout. + +Fix by updating the highest seen sequence number in both directions after +packet mangling. + +Tested-by: Krzysztof Piotr Oledzki +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_conntrack.h | 4 ++-- + net/ipv4/netfilter/nf_nat_helper.c | 17 +++++++++++------ + net/netfilter/nf_conntrack_proto_tcp.c | 6 +++--- + 3 files changed, 16 insertions(+), 11 deletions(-) + +--- a/include/net/netfilter/nf_conntrack.h ++++ b/include/net/netfilter/nf_conntrack.h +@@ -255,8 +255,8 @@ static inline bool nf_ct_kill(struct nf_ + /* Update TCP window tracking data when NAT mangles the packet */ + extern void nf_conntrack_tcp_update(const struct sk_buff *skb, + unsigned int dataoff, +- struct nf_conn *ct, +- int dir); ++ struct nf_conn *ct, int dir, ++ s16 offset); + + /* Fake conntrack entry for untracked connections */ + extern struct nf_conn nf_conntrack_untracked; +--- a/net/ipv4/netfilter/nf_nat_helper.c ++++ b/net/ipv4/netfilter/nf_nat_helper.c +@@ -191,7 +191,8 @@ nf_nat_mangle_tcp_packet(struct sk_buff + ct, ctinfo); + /* Tell TCP window tracking about seq change */ + nf_conntrack_tcp_update(skb, ip_hdrlen(skb), +- ct, CTINFO2DIR(ctinfo)); ++ ct, CTINFO2DIR(ctinfo), ++ (int)rep_len - (int)match_len); + + nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); + } +@@ -377,6 +378,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, + struct tcphdr *tcph; + int dir; + __be32 newseq, newack; ++ s16 seqoff, ackoff; + struct nf_conn_nat *nat = nfct_nat(ct); + struct nf_nat_seq *this_way, *other_way; + +@@ -390,15 +392,18 @@ nf_nat_seq_adjust(struct sk_buff *skb, + + tcph = (void *)skb->data + ip_hdrlen(skb); + if (after(ntohl(tcph->seq), this_way->correction_pos)) +- newseq = htonl(ntohl(tcph->seq) + this_way->offset_after); ++ seqoff = this_way->offset_after; + else +- newseq = htonl(ntohl(tcph->seq) + this_way->offset_before); ++ seqoff = this_way->offset_before; + + if (after(ntohl(tcph->ack_seq) - other_way->offset_before, + other_way->correction_pos)) +- newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after); ++ ackoff = other_way->offset_after; + else +- newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before); ++ ackoff = other_way->offset_before; ++ ++ newseq = htonl(ntohl(tcph->seq) + seqoff); ++ newack = htonl(ntohl(tcph->ack_seq) - ackoff); + + inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0); + inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0); +@@ -413,7 +418,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, + if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) + return 0; + +- nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir); ++ nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff); + + return 1; + } +--- a/net/netfilter/nf_conntrack_proto_tcp.c ++++ b/net/netfilter/nf_conntrack_proto_tcp.c +@@ -706,8 +706,8 @@ static bool tcp_in_window(const struct n + /* Caller must linearize skb at tcp header. */ + void nf_conntrack_tcp_update(const struct sk_buff *skb, + unsigned int dataoff, +- struct nf_conn *ct, +- int dir) ++ struct nf_conn *ct, int dir, ++ s16 offset) + { + const struct tcphdr *tcph = (const void *)skb->data + dataoff; + const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir]; +@@ -720,7 +720,7 @@ void nf_conntrack_tcp_update(const struc + /* + * We have to worry for the ack in the reply packet only... + */ +- if (after(end, ct->proto.tcp.seen[dir].td_end)) ++ if (ct->proto.tcp.seen[dir].td_end + offset == end) + ct->proto.tcp.seen[dir].td_end = end; + ct->proto.tcp.last_end = end; + write_unlock_bh(&tcp_lock); diff --git a/queue-2.6.30/netfilter-xt_quota-fix-incomplete-initialization.patch b/queue-2.6.30/netfilter-xt_quota-fix-incomplete-initialization.patch new file mode 100644 index 00000000000..5ca2a7c6b3a --- /dev/null +++ b/queue-2.6.30/netfilter-xt_quota-fix-incomplete-initialization.patch @@ -0,0 +1,32 @@ +From 6d62182fea6cc6bbc8d82a691ad0608d68a54aeb Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Mon, 22 Jun 2009 14:16:45 +0200 +Subject: netfilter: xt_quota: fix incomplete initialization + +From: Jan Engelhardt + +commit 6d62182fea6cc6bbc8d82a691ad0608d68a54aeb upstream. + +Commit v2.6.29-rc5-872-gacc738f ("xtables: avoid pointer to self") +forgot to copy the initial quota value supplied by iptables into the +private structure, thus counting from whatever was in the memory +kmalloc returned. + +Signed-off-by: Jan Engelhardt +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_quota.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netfilter/xt_quota.c ++++ b/net/netfilter/xt_quota.c +@@ -54,6 +54,7 @@ static bool quota_mt_check(const struct + if (q->master == NULL) + return -ENOMEM; + ++ q->master->quota = q->quota; + return true; + } + diff --git a/queue-2.6.30/netfilter-xt_rateest-fix-comparison-with-self.patch b/queue-2.6.30/netfilter-xt_rateest-fix-comparison-with-self.patch new file mode 100644 index 00000000000..20f3bca0705 --- /dev/null +++ b/queue-2.6.30/netfilter-xt_rateest-fix-comparison-with-self.patch @@ -0,0 +1,49 @@ +From 4d900f9df5f0569c2dc536701e2c11b6d50ebebf Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Mon, 22 Jun 2009 14:17:12 +0200 +Subject: netfilter: xt_rateest: fix comparison with self +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit + +From: Patrick McHardy + +commit 4d900f9df5f0569c2dc536701e2c11b6d50ebebf upstream. + +As noticed by Török Edwin : + +Compiling the kernel with clang has shown this warning: + +net/netfilter/xt_rateest.c:69:16: warning: self-comparison always results in a +constant value + ret &= pps2 == pps2; + ^ +Looking at the code: +if (info->flags & XT_RATEEST_MATCH_BPS) + ret &= bps1 == bps2; + if (info->flags & XT_RATEEST_MATCH_PPS) + ret &= pps2 == pps2; + +Judging from the MATCH_BPS case it seems to be a typo, with the intention of +comparing pps1 with pps2. + +http://bugzilla.kernel.org/show_bug.cgi?id=13535 + +Signed-off-by: Patrick McHardy +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/xt_rateest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/netfilter/xt_rateest.c ++++ b/net/netfilter/xt_rateest.c +@@ -66,7 +66,7 @@ xt_rateest_mt(const struct sk_buff *skb, + if (info->flags & XT_RATEEST_MATCH_BPS) + ret &= bps1 == bps2; + if (info->flags & XT_RATEEST_MATCH_PPS) +- ret &= pps2 == pps2; ++ ret &= pps1 == pps2; + break; + } + diff --git a/queue-2.6.30/nf_conntrack-nf_conntrack_alloc-fixes.patch b/queue-2.6.30/nf_conntrack-nf_conntrack_alloc-fixes.patch new file mode 100644 index 00000000000..5b0c9723699 --- /dev/null +++ b/queue-2.6.30/nf_conntrack-nf_conntrack_alloc-fixes.patch @@ -0,0 +1,109 @@ +From kaber@trash.net Tue Jul 28 12:03:01 2009 +From: Eric Dumazet +Date: Thu, 23 Jul 2009 16:15:34 +0200 (MEST) +Subject: nf_conntrack: nf_conntrack_alloc() fixes +To: stable@kernel.org +Cc: netdev@vger.kernel.org, netfilter-devel@vger.kernel.org, Patrick McHardy +Message-ID: <20090723141533.19029.28754.sendpatchset@x2.localnet> + +From: Eric Dumazet + +commit 941297f443f871b8c3372feccf27a8733f6ce9e9 upstream. + +When a slab cache uses SLAB_DESTROY_BY_RCU, we must be careful when allocating +objects, since slab allocator could give a freed object still used by lockless +readers. + +In particular, nf_conntrack RCU lookups rely on ct->tuplehash[xxx].hnnode.next +being always valid (ie containing a valid 'nulls' value, or a valid pointer to next +object in hash chain.) + +kmem_cache_zalloc() setups object with NULL values, but a NULL value is not valid +for ct->tuplehash[xxx].hnnode.next. + +Fix is to call kmem_cache_alloc() and do the zeroing ourself. + +As spotted by Patrick, we also need to make sure lookup keys are committed to +memory before setting refcount to 1, or a lockless reader could get a reference +on the old version of the object. Its key re-check could then pass the barrier. + +Signed-off-by: Eric Dumazet +Signed-off-by: Patrick McHardy +Acked-by: Paul E. McKenney +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/RCU/rculist_nulls.txt | 7 ++++++- + net/netfilter/nf_conntrack_core.c | 21 ++++++++++++++++++--- + 2 files changed, 24 insertions(+), 4 deletions(-) + +--- a/Documentation/RCU/rculist_nulls.txt ++++ b/Documentation/RCU/rculist_nulls.txt +@@ -83,11 +83,12 @@ not detect it missed following items in + obj = kmem_cache_alloc(...); + lock_chain(); // typically a spin_lock() + obj->key = key; +-atomic_inc(&obj->refcnt); + /* + * we need to make sure obj->key is updated before obj->next ++ * or obj->refcnt + */ + smp_wmb(); ++atomic_set(&obj->refcnt, 1); + hlist_add_head_rcu(&obj->obj_node, list); + unlock_chain(); // typically a spin_unlock() + +@@ -159,6 +160,10 @@ out: + obj = kmem_cache_alloc(cachep); + lock_chain(); // typically a spin_lock() + obj->key = key; ++/* ++ * changes to obj->key must be visible before refcnt one ++ */ ++smp_wmb(); + atomic_set(&obj->refcnt, 1); + /* + * insert obj in RCU way (readers might be traversing chain) +--- a/net/netfilter/nf_conntrack_core.c ++++ b/net/netfilter/nf_conntrack_core.c +@@ -525,22 +525,37 @@ struct nf_conn *nf_conntrack_alloc(struc + } + } + +- ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp); ++ /* ++ * Do not use kmem_cache_zalloc(), as this cache uses ++ * SLAB_DESTROY_BY_RCU. ++ */ ++ ct = kmem_cache_alloc(nf_conntrack_cachep, gfp); + if (ct == NULL) { + pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n"); + atomic_dec(&net->ct.count); + return ERR_PTR(-ENOMEM); + } +- +- atomic_set(&ct->ct_general.use, 1); ++ /* ++ * Let ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.next ++ * and ct->tuplehash[IP_CT_DIR_REPLY].hnnode.next unchanged. ++ */ ++ memset(&ct->tuplehash[IP_CT_DIR_MAX], 0, ++ sizeof(*ct) - offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX])); + ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; ++ ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL; + ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; ++ ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev = NULL; + /* Don't set timer yet: wait for confirmation */ + setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); + #ifdef CONFIG_NET_NS + ct->ct_net = net; + #endif + ++ /* ++ * changes to lookup keys must be done before setting refcnt to 1 ++ */ ++ smp_wmb(); ++ atomic_set(&ct->ct_general.use, 1); + return ct; + } + EXPORT_SYMBOL_GPL(nf_conntrack_alloc); diff --git a/queue-2.6.30/series b/queue-2.6.30/series index db8576a140d..a49bc736e73 100644 --- a/queue-2.6.30/series +++ b/queue-2.6.30/series @@ -54,3 +54,15 @@ mm-mark-page-accessed-before-we-write_end.patch elf-fix-one-check-after-use.patch hwmon-fix-lock-imbalance.patch powerpc-mpic-fix-mapping-of-dcr-based-mpic-variants.patch +netfilter-nf_log-fix-sleeping-function-called-from-invalid-context.patch +netfilter-nf_conntrack-fix-confirmation-race-condition.patch +netfilter-nf_conntrack-fix-conntrack-lookup-race.patch +netfilter-nf_log-fix-direct-userspace-memory-access-in-proc-handler.patch +netfilter-xt_quota-fix-incomplete-initialization.patch +netfilter-xt_rateest-fix-comparison-with-self.patch +netfilter-tcp-conntrack-fix-unacknowledged-data-detection-with-nat.patch +nf_conntrack-nf_conntrack_alloc-fixes.patch +netdev-restore-mac-address-set-and-validate-operations.patch +netdev-restore-mtu-change-operation.patch +input-wistron_btns-recognize-maxdata-pro-7000-notebooks.patch +libata-fix-follow-up-srst-failure-path.patch