From: Greg Kroah-Hartman Date: Mon, 29 Apr 2013 17:16:03 +0000 (-0700) Subject: 3.8-stable patches X-Git-Tag: v3.0.76~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=edbd96edbcd782665c6e1913d9b50190f2020173;p=thirdparty%2Fkernel%2Fstable-queue.git 3.8-stable patches added patches: af_unix-if-we-don-t-care-about-credentials-coallesce-all-messages.patch atl1e-limit-gso-segment-size-to-prevent-generation-of-wrong-ip-length-fields.patch atm-update-msg_namelen-in-vcc_recvmsg.patch ax25-fix-info-leak-via-msg_name-in-ax25_recvmsg.patch bluetooth-fix-possible-info-leak-in-bt_sock_recvmsg.patch bluetooth-rfcomm-fix-missing-msg_namelen-update-in-rfcomm_sock_recvmsg.patch bluetooth-sco-fix-missing-msg_namelen-update-in-sco_sock_recvmsg.patch bonding-fix-bonding_masters-race-condition-in-bond-unloading.patch bonding-fix-l23-and-l34-load-balancing-in-forwarding-path.patch bonding-iff_bonding-is-not-stripped-on-enslave-failure.patch caif-fix-missing-msg_namelen-update-in-caif_seqpkt_recvmsg.patch cbq-incorrect-processing-of-high-limits.patch esp4-fix-error-return-code-in-esp_output.patch ipv6-tcp-stop-processing-icmpv6-redirect-messages.patch irda-fix-missing-msg_namelen-update-in-irda_recvmsg_dgram.patch iucv-fix-missing-msg_namelen-update-in-iucv_sock_recvmsg.patch l2tp-fix-info-leak-in-l2tp_ip6_recvmsg.patch llc-fix-missing-msg_namelen-update-in-llc_ui_recvmsg.patch net-cdc_mbim-remove-bogus-sizeof.patch net-count-hw_addr-syncs-so-that-unsync-works-properly.patch net-drop-dst-before-queueing-fragments.patch netfilter-don-t-reset-nf_trace-in-nf_reset.patch net-fix-incorrect-credentials-passing.patch net-ipv6-fix-broken-ipv6-routing-table-after-loopback-down-up.patch net-mvmdio-add-select-phylib.patch net-mvneta-fix-improper-tx-queue-usage-in-mvneta_tx.patch net-rate-limit-warn-bad-offload-splats.patch netrom-fix-info-leak-via-msg_name-in-nr_recvmsg.patch nfc-llcp-fix-info-leaks-via-msg_name-in-llcp_sock_recvmsg.patch rose-fix-info-leak-via-msg_name-in-rose_recvmsg.patch rtnetlink-call-nlmsg_parse-with-correct-header-length.patch tcp-call-tcp_replace_ts_recent-from-tcp_ack.patch tcp-incoming-connections-might-use-wrong-route-under-synflood.patch tcp-reallocate-headroom-if-it-would-overflow-csum_start.patch tipc-fix-info-leaks-via-msg_name-in-recv_msg-recv_stream.patch --- diff --git a/queue-3.8/af_unix-if-we-don-t-care-about-credentials-coallesce-all-messages.patch b/queue-3.8/af_unix-if-we-don-t-care-about-credentials-coallesce-all-messages.patch new file mode 100644 index 00000000000..90dd9b6edc8 --- /dev/null +++ b/queue-3.8/af_unix-if-we-don-t-care-about-credentials-coallesce-all-messages.patch @@ -0,0 +1,55 @@ +From 716368a09e4d1459ef246a976f20b2d1299738b3 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Wed, 3 Apr 2013 16:14:47 +0000 +Subject: af_unix: If we don't care about credentials coallesce all messages + + +From: "Eric W. Biederman" + +[ Upstream commit 0e82e7f6dfeec1013339612f74abc2cdd29d43d2 ] + +It was reported that the following LSB test case failed +https://lsbbugs.linuxfoundation.org/attachment.cgi?id=2144 because we +were not coallescing unix stream messages when the application was +expecting us to. + +The problem was that the first send was before the socket was accepted +and thus sock->sk_socket was NULL in maybe_add_creds, and the second +send after the socket was accepted had a non-NULL value for sk->socket +and thus we could tell the credentials were not needed so we did not +bother. + +The unnecessary credentials on the first message cause +unix_stream_recvmsg to start verifying that all messages had the same +credentials before coallescing and then the coallescing failed because +the second message had no credentials. + +Ignoring credentials when we don't care in unix_stream_recvmsg fixes a +long standing pessimization which would fail to coallesce messages when +reading from a unix stream socket if the senders were different even if +we did not care about their credentials. + +I have tested this and verified that the in the LSB test case mentioned +above that the messages do coallesce now, while the were failing to +coallesce without this change. + +Reported-by: Karel Srot +Reported-by: Ding Tianhong +Signed-off-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/unix/af_unix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1995,7 +1995,7 @@ again: + if ((UNIXCB(skb).pid != siocb->scm->pid) || + (UNIXCB(skb).cred != siocb->scm->cred)) + break; +- } else { ++ } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { + /* Copy credentials */ + scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); + check_creds = 1; diff --git a/queue-3.8/atl1e-limit-gso-segment-size-to-prevent-generation-of-wrong-ip-length-fields.patch b/queue-3.8/atl1e-limit-gso-segment-size-to-prevent-generation-of-wrong-ip-length-fields.patch new file mode 100644 index 00000000000..573c74818a9 --- /dev/null +++ b/queue-3.8/atl1e-limit-gso-segment-size-to-prevent-generation-of-wrong-ip-length-fields.patch @@ -0,0 +1,44 @@ +From 1c5532454988586b7609e4ccba4f08dc4445d9a5 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Tue, 2 Apr 2013 14:36:46 +0000 +Subject: atl1e: limit gso segment size to prevent generation of wrong ip length fields + + +From: Hannes Frederic Sowa + +[ Upstream commit 31d1670e73f4911fe401273a8f576edc9c2b5fea ] + +The limit of 0x3c00 is taken from the windows driver. + +Suggested-by: Huang, Xiong +Cc: Huang, Xiong +Cc: Eric Dumazet +Signed-off-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/atheros/atl1e/atl1e.h | 2 +- + drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/atheros/atl1e/atl1e.h ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h +@@ -186,7 +186,7 @@ struct atl1e_tpd_desc { + /* how about 0x2000 */ + #define MAX_TX_BUF_LEN 0x2000 + #define MAX_TX_BUF_SHIFT 13 +-/*#define MAX_TX_BUF_LEN 0x3000 */ ++#define MAX_TSO_SEG_SIZE 0x3c00 + + /* rrs word 1 bit 0:31 */ + #define RRS_RX_CSUM_MASK 0xFFFF +--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c ++++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +@@ -2332,6 +2332,7 @@ static int atl1e_probe(struct pci_dev *p + + INIT_WORK(&adapter->reset_task, atl1e_reset_task); + INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task); ++ netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE); + err = register_netdev(netdev); + if (err) { + netdev_err(netdev, "register netdevice failed\n"); diff --git a/queue-3.8/atm-update-msg_namelen-in-vcc_recvmsg.patch b/queue-3.8/atm-update-msg_namelen-in-vcc_recvmsg.patch new file mode 100644 index 00000000000..5f436071990 --- /dev/null +++ b/queue-3.8/atm-update-msg_namelen-in-vcc_recvmsg.patch @@ -0,0 +1,36 @@ +From 1687955b3f4a29bb040b3075b541e440f9fd9e1f Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:47 +0000 +Subject: atm: update msg_namelen in vcc_recvmsg() + + +From: Mathias Krause + +[ Upstream commit 9b3e617f3df53822345a8573b6d358f6b9e5ed87 ] + +The current code does not fill the msg_name member in case it is set. +It also does not set the msg_namelen member to 0 and therefore makes +net/socket.c leak the local, uninitialized sockaddr_storage variable +to userland -- 128 bytes of kernel stack memory. + +Fix that by simply setting msg_namelen to 0 as obviously nobody cared +about vcc_recvmsg() not filling the msg_name in case it was set. + +Signed-off-by: Mathias Krause +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/atm/common.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/atm/common.c ++++ b/net/atm/common.c +@@ -532,6 +532,8 @@ int vcc_recvmsg(struct kiocb *iocb, stru + struct sk_buff *skb; + int copied, error = -EINVAL; + ++ msg->msg_namelen = 0; ++ + if (sock->state != SS_CONNECTED) + return -ENOTCONN; + diff --git a/queue-3.8/ax25-fix-info-leak-via-msg_name-in-ax25_recvmsg.patch b/queue-3.8/ax25-fix-info-leak-via-msg_name-in-ax25_recvmsg.patch new file mode 100644 index 00000000000..49f7f3ec88e --- /dev/null +++ b/queue-3.8/ax25-fix-info-leak-via-msg_name-in-ax25_recvmsg.patch @@ -0,0 +1,39 @@ +From 8c6a036edfa2f60b12b06b9f27ff0c8919691e00 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:48 +0000 +Subject: ax25: fix info leak via msg_name in ax25_recvmsg() + + +From: Mathias Krause + +[ Upstream commit ef3313e84acbf349caecae942ab3ab731471f1a1 ] + +When msg_namelen is non-zero the sockaddr info gets filled out, as +requested, but the code fails to initialize the padding bytes of struct +sockaddr_ax25 inserted by the compiler for alignment. Additionally the +msg_namelen value is updated to sizeof(struct full_sockaddr_ax25) but is +not always filled up to this size. + +Both issues lead to the fact that the code will leak uninitialized +kernel stack bytes in net/socket.c. + +Fix both issues by initializing the memory with memset(0). + +Signed-off-by: Mathias Krause +Cc: Ralf Baechle +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ax25/af_ax25.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1647,6 +1647,7 @@ static int ax25_recvmsg(struct kiocb *io + ax25_address src; + const unsigned char *mac = skb_mac_header(skb); + ++ memset(sax, 0, sizeof(struct full_sockaddr_ax25)); + ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, + &digi, NULL, NULL); + sax->sax25_family = AF_AX25; diff --git a/queue-3.8/bluetooth-fix-possible-info-leak-in-bt_sock_recvmsg.patch b/queue-3.8/bluetooth-fix-possible-info-leak-in-bt_sock_recvmsg.patch new file mode 100644 index 00000000000..7a667e5b4be --- /dev/null +++ b/queue-3.8/bluetooth-fix-possible-info-leak-in-bt_sock_recvmsg.patch @@ -0,0 +1,48 @@ +From 0f4a045ebac203fbd0e7553995301988e4890922 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:49 +0000 +Subject: Bluetooth: fix possible info leak in bt_sock_recvmsg() + + +From: Mathias Krause + +[ Upstream commit 4683f42fde3977bdb4e8a09622788cc8b5313778 ] + +In case the socket is already shutting down, bt_sock_recvmsg() returns +with 0 without updating msg_namelen leading to net/socket.c leaking the +local, uninitialized sockaddr_storage variable to userland -- 128 bytes +of kernel stack memory. + +Fix this by moving the msg_namelen assignment in front of the shutdown +test. + +Signed-off-by: Mathias Krause +Cc: Marcel Holtmann +Cc: Gustavo Padovan +Cc: Johan Hedberg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/af_bluetooth.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/bluetooth/af_bluetooth.c ++++ b/net/bluetooth/af_bluetooth.c +@@ -230,6 +230,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, + if (flags & (MSG_OOB)) + return -EOPNOTSUPP; + ++ msg->msg_namelen = 0; ++ + skb = skb_recv_datagram(sk, flags, noblock, &err); + if (!skb) { + if (sk->sk_shutdown & RCV_SHUTDOWN) +@@ -237,8 +239,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, + return err; + } + +- msg->msg_namelen = 0; +- + copied = skb->len; + if (len < copied) { + msg->msg_flags |= MSG_TRUNC; diff --git a/queue-3.8/bluetooth-rfcomm-fix-missing-msg_namelen-update-in-rfcomm_sock_recvmsg.patch b/queue-3.8/bluetooth-rfcomm-fix-missing-msg_namelen-update-in-rfcomm_sock_recvmsg.patch new file mode 100644 index 00000000000..a9872343f22 --- /dev/null +++ b/queue-3.8/bluetooth-rfcomm-fix-missing-msg_namelen-update-in-rfcomm_sock_recvmsg.patch @@ -0,0 +1,37 @@ +From daecaa6c1a244f29fb6e4df3e0bdba54dedfa6b6 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:50 +0000 +Subject: Bluetooth: RFCOMM - Fix missing msg_namelen update in rfcomm_sock_recvmsg() + + +From: Mathias Krause + +[ Upstream commit e11e0455c0d7d3d62276a0c55d9dfbc16779d691 ] + +If RFCOMM_DEFER_SETUP is set in the flags, rfcomm_sock_recvmsg() returns +early with 0 without updating the possibly set msg_namelen member. This, +in turn, leads to a 128 byte kernel stack leak in net/socket.c. + +Fix this by updating msg_namelen in this case. For all other cases it +will be handled in bt_sock_stream_recvmsg(). + +Signed-off-by: Mathias Krause +Cc: Marcel Holtmann +Cc: Gustavo Padovan +Cc: Johan Hedberg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/rfcomm/sock.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/bluetooth/rfcomm/sock.c ++++ b/net/bluetooth/rfcomm/sock.c +@@ -610,6 +610,7 @@ static int rfcomm_sock_recvmsg(struct ki + + if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { + rfcomm_dlc_accept(d); ++ msg->msg_namelen = 0; + return 0; + } + diff --git a/queue-3.8/bluetooth-sco-fix-missing-msg_namelen-update-in-sco_sock_recvmsg.patch b/queue-3.8/bluetooth-sco-fix-missing-msg_namelen-update-in-sco_sock_recvmsg.patch new file mode 100644 index 00000000000..187d7e26bea --- /dev/null +++ b/queue-3.8/bluetooth-sco-fix-missing-msg_namelen-update-in-sco_sock_recvmsg.patch @@ -0,0 +1,38 @@ +From c4f7dec1cade767bc4f32a23dd32a3a99d6cafea Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:51 +0000 +Subject: Bluetooth: SCO - Fix missing msg_namelen update in sco_sock_recvmsg() + + +From: Mathias Krause + +[ Upstream commit c8c499175f7d295ef867335bceb9a76a2c3cdc38 ] + +If the socket is in state BT_CONNECT2 and BT_SK_DEFER_SETUP is set in +the flags, sco_sock_recvmsg() returns early with 0 without updating the +possibly set msg_namelen member. This, in turn, leads to a 128 byte +kernel stack leak in net/socket.c. + +Fix this by updating msg_namelen in this case. For all other cases it +will be handled in bt_sock_recvmsg(). + +Signed-off-by: Mathias Krause +Cc: Marcel Holtmann +Cc: Gustavo Padovan +Cc: Johan Hedberg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bluetooth/sco.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -667,6 +667,7 @@ static int sco_sock_recvmsg(struct kiocb + test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { + hci_conn_accept(pi->conn->hcon, 0); + sk->sk_state = BT_CONFIG; ++ msg->msg_namelen = 0; + + release_sock(sk); + return 0; diff --git a/queue-3.8/bonding-fix-bonding_masters-race-condition-in-bond-unloading.patch b/queue-3.8/bonding-fix-bonding_masters-race-condition-in-bond-unloading.patch new file mode 100644 index 00000000000..42f14051ad0 --- /dev/null +++ b/queue-3.8/bonding-fix-bonding_masters-race-condition-in-bond-unloading.patch @@ -0,0 +1,49 @@ +From 9afba96b56620cbf9621a47b8ddfdef0e8d14b1b Mon Sep 17 00:00:00 2001 +From: "nikolay@redhat.com" +Date: Sat, 6 Apr 2013 00:54:38 +0000 +Subject: bonding: fix bonding_masters race condition in bond unloading + + +From: "nikolay@redhat.com" + +[ Upstream commit 69b0216ac255f523556fa3d4ff030d857eaaa37f ] + +While the bonding module is unloading, it is considered that after +rtnl_link_unregister all bond devices are destroyed but since no +synchronization mechanism exists, a new bond device can be created +via bonding_masters before unregister_pernet_subsys which would +lead to multiple problems (e.g. NULL pointer dereference, wrong RIP, +list corruption). + +This patch fixes the issue by removing any bond devices left in the +netns after bonding_masters is removed from sysfs. + +Signed-off-by: Nikolay Aleksandrov +Acked-by: Veaceslav Falico +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_main.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4919,9 +4919,18 @@ static int __net_init bond_net_init(stru + static void __net_exit bond_net_exit(struct net *net) + { + struct bond_net *bn = net_generic(net, bond_net_id); ++ struct bonding *bond, *tmp_bond; ++ LIST_HEAD(list); + + bond_destroy_sysfs(bn); + bond_destroy_proc_dir(bn); ++ ++ /* Kill off any bonds created after unregistering bond rtnl ops */ ++ rtnl_lock(); ++ list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list) ++ unregister_netdevice_queue(bond->dev, &list); ++ unregister_netdevice_many(&list); ++ rtnl_unlock(); + } + + static struct pernet_operations bond_net_ops = { diff --git a/queue-3.8/bonding-fix-l23-and-l34-load-balancing-in-forwarding-path.patch b/queue-3.8/bonding-fix-l23-and-l34-load-balancing-in-forwarding-path.patch new file mode 100644 index 00000000000..4312095725b --- /dev/null +++ b/queue-3.8/bonding-fix-l23-and-l34-load-balancing-in-forwarding-path.patch @@ -0,0 +1,121 @@ +From 0829aedd0d4542e51664ac0f8748abd2cb0ba3f5 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 15 Apr 2013 17:03:24 +0000 +Subject: bonding: fix l23 and l34 load balancing in forwarding path + + +From: Eric Dumazet + +[ Upstream commit 4394542ca4ec9f28c3c8405063d200b1e7c347d7 ] + +Since commit 6b923cb7188d46 (bonding: support for IPv6 transmit hashing) +bonding doesn't properly hash traffic in forwarding setups. + +Vitaly V. Bursov diagnosed that skb_network_header_len() returned 0 in +this case. + +More generally, the transport header might not be in the skb head. + +Use pskb_may_pull() & skb_header_pointer() to get it right, and use +proto_ports_offset() in bond_xmit_hash_policy_l34() to get support for +more protocols than TCP and UDP. + +Reported-by: Vitaly V. Bursov +Signed-off-by: Eric Dumazet +Cc: Jay Vosburgh +Cc: Andy Gospodarek +Cc: John Eaglesham +Tested-by: Vitaly V. Bursov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_main.c | 55 +++++++++++++++++++++------------------- + 1 file changed, 30 insertions(+), 25 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -3380,20 +3380,22 @@ static int bond_xmit_hash_policy_l2(stru + */ + static int bond_xmit_hash_policy_l23(struct sk_buff *skb, int count) + { +- struct ethhdr *data = (struct ethhdr *)skb->data; +- struct iphdr *iph; +- struct ipv6hdr *ipv6h; ++ const struct ethhdr *data; ++ const struct iphdr *iph; ++ const struct ipv6hdr *ipv6h; + u32 v6hash; +- __be32 *s, *d; ++ const __be32 *s, *d; + + if (skb->protocol == htons(ETH_P_IP) && +- skb_network_header_len(skb) >= sizeof(*iph)) { ++ pskb_network_may_pull(skb, sizeof(*iph))) { + iph = ip_hdr(skb); ++ data = (struct ethhdr *)skb->data; + return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ + (data->h_dest[5] ^ data->h_source[5])) % count; + } else if (skb->protocol == htons(ETH_P_IPV6) && +- skb_network_header_len(skb) >= sizeof(*ipv6h)) { ++ pskb_network_may_pull(skb, sizeof(*ipv6h))) { + ipv6h = ipv6_hdr(skb); ++ data = (struct ethhdr *)skb->data; + s = &ipv6h->saddr.s6_addr32[0]; + d = &ipv6h->daddr.s6_addr32[0]; + v6hash = (s[1] ^ d[1]) ^ (s[2] ^ d[2]) ^ (s[3] ^ d[3]); +@@ -3412,33 +3414,36 @@ static int bond_xmit_hash_policy_l23(str + static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) + { + u32 layer4_xor = 0; +- struct iphdr *iph; +- struct ipv6hdr *ipv6h; +- __be32 *s, *d; +- __be16 *layer4hdr; ++ const struct iphdr *iph; ++ const struct ipv6hdr *ipv6h; ++ const __be32 *s, *d; ++ const __be16 *l4 = NULL; ++ __be16 _l4[2]; ++ int noff = skb_network_offset(skb); ++ int poff; + + if (skb->protocol == htons(ETH_P_IP) && +- skb_network_header_len(skb) >= sizeof(*iph)) { ++ pskb_may_pull(skb, noff + sizeof(*iph))) { + iph = ip_hdr(skb); +- if (!ip_is_fragment(iph) && +- (iph->protocol == IPPROTO_TCP || +- iph->protocol == IPPROTO_UDP) && +- (skb_headlen(skb) - skb_network_offset(skb) >= +- iph->ihl * sizeof(u32) + sizeof(*layer4hdr) * 2)) { +- layer4hdr = (__be16 *)((u32 *)iph + iph->ihl); +- layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); ++ poff = proto_ports_offset(iph->protocol); ++ ++ if (!ip_is_fragment(iph) && poff >= 0) { ++ l4 = skb_header_pointer(skb, noff + (iph->ihl << 2) + poff, ++ sizeof(_l4), &_l4); ++ if (l4) ++ layer4_xor = ntohs(l4[0] ^ l4[1]); + } + return (layer4_xor ^ + ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; + } else if (skb->protocol == htons(ETH_P_IPV6) && +- skb_network_header_len(skb) >= sizeof(*ipv6h)) { ++ pskb_may_pull(skb, noff + sizeof(*ipv6h))) { + ipv6h = ipv6_hdr(skb); +- if ((ipv6h->nexthdr == IPPROTO_TCP || +- ipv6h->nexthdr == IPPROTO_UDP) && +- (skb_headlen(skb) - skb_network_offset(skb) >= +- sizeof(*ipv6h) + sizeof(*layer4hdr) * 2)) { +- layer4hdr = (__be16 *)(ipv6h + 1); +- layer4_xor = ntohs(*layer4hdr ^ *(layer4hdr + 1)); ++ poff = proto_ports_offset(ipv6h->nexthdr); ++ if (poff >= 0) { ++ l4 = skb_header_pointer(skb, noff + sizeof(*ipv6h) + poff, ++ sizeof(_l4), &_l4); ++ if (l4) ++ layer4_xor = ntohs(l4[0] ^ l4[1]); + } + s = &ipv6h->saddr.s6_addr32[0]; + d = &ipv6h->daddr.s6_addr32[0]; diff --git a/queue-3.8/bonding-iff_bonding-is-not-stripped-on-enslave-failure.patch b/queue-3.8/bonding-iff_bonding-is-not-stripped-on-enslave-failure.patch new file mode 100644 index 00000000000..5a744fe6ba2 --- /dev/null +++ b/queue-3.8/bonding-iff_bonding-is-not-stripped-on-enslave-failure.patch @@ -0,0 +1,34 @@ +From 9f255ad7609e3663e9327019f2807bdff878bd1b Mon Sep 17 00:00:00 2001 +From: "nikolay@redhat.com" +Date: Thu, 11 Apr 2013 09:18:56 +0000 +Subject: bonding: IFF_BONDING is not stripped on enslave failure + + +From: "nikolay@redhat.com" + +[ Upstream commit b6a5a7b9a528a8b4c8bec940b607c5dd9102b8cc ] + +While enslaving a new device and after IFF_BONDING flag is set, in case +of failure it is not stripped from the device's priv_flags while +cleaning up, which could lead to other problems. +Cleaning at err_close because the flag is set after dev_open(). + +v2: no change + +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1888,6 +1888,7 @@ err_detach: + write_unlock_bh(&bond->lock); + + err_close: ++ slave_dev->priv_flags &= ~IFF_BONDING; + dev_close(slave_dev); + + err_unset_master: diff --git a/queue-3.8/caif-fix-missing-msg_namelen-update-in-caif_seqpkt_recvmsg.patch b/queue-3.8/caif-fix-missing-msg_namelen-update-in-caif_seqpkt_recvmsg.patch new file mode 100644 index 00000000000..47524fb6d25 --- /dev/null +++ b/queue-3.8/caif-fix-missing-msg_namelen-update-in-caif_seqpkt_recvmsg.patch @@ -0,0 +1,38 @@ +From b25e7b323a3d756ac63a422a54f26a3f28dfcb80 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:52 +0000 +Subject: caif: Fix missing msg_namelen update in caif_seqpkt_recvmsg() + + +From: Mathias Krause + +[ Upstream commit 2d6fbfe733f35c6b355c216644e08e149c61b271 ] + +The current code does not fill the msg_name member in case it is set. +It also does not set the msg_namelen member to 0 and therefore makes +net/socket.c leak the local, uninitialized sockaddr_storage variable +to userland -- 128 bytes of kernel stack memory. + +Fix that by simply setting msg_namelen to 0 as obviously nobody cared +about caif_seqpkt_recvmsg() not filling the msg_name in case it was +set. + +Signed-off-by: Mathias Krause +Cc: Sjur Braendeland +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/caif/caif_socket.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/caif/caif_socket.c ++++ b/net/caif/caif_socket.c +@@ -286,6 +286,8 @@ static int caif_seqpkt_recvmsg(struct ki + if (m->msg_flags&MSG_OOB) + goto read_error; + ++ m->msg_namelen = 0; ++ + skb = skb_recv_datagram(sk, flags, 0 , &ret); + if (!skb) + goto read_error; diff --git a/queue-3.8/cbq-incorrect-processing-of-high-limits.patch b/queue-3.8/cbq-incorrect-processing-of-high-limits.patch new file mode 100644 index 00000000000..7f8de5f1c1c --- /dev/null +++ b/queue-3.8/cbq-incorrect-processing-of-high-limits.patch @@ -0,0 +1,53 @@ +From ba1cbc6d7aed436c0f79065cef7c62171f66f81e Mon Sep 17 00:00:00 2001 +From: Vasily Averin +Date: Mon, 1 Apr 2013 03:01:32 +0000 +Subject: cbq: incorrect processing of high limits + + +From: Vasily Averin + +[ Upstream commit f0f6ee1f70c4eaab9d52cf7d255df4bd89f8d1c2 ] + +currently cbq works incorrectly for limits > 10% real link bandwidth, +and practically does not work for limits > 50% real link bandwidth. +Below are results of experiments taken on 1 Gbit link + + In shaper | Actual Result +-----------+--------------- + 100M | 108 Mbps + 200M | 244 Mbps + 300M | 412 Mbps + 500M | 893 Mbps + +This happen because of q->now changes incorrectly in cbq_dequeue(): +when it is called before real end of packet transmitting, +L2T is greater than real time delay, q_now gets an extra boost +but never compensate it. + +To fix this problem we prevent change of q->now until its synchronization +with real time. + +Signed-off-by: Vasily Averin +Reviewed-by: Alexey Kuznetsov +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_cbq.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/sched/sch_cbq.c ++++ b/net/sched/sch_cbq.c +@@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch) + cbq_update(q); + if ((incr -= incr2) < 0) + incr = 0; ++ q->now += incr; ++ } else { ++ if (now > q->now) ++ q->now = now; + } +- q->now += incr; + q->now_rt = now; + + for (;;) { diff --git a/queue-3.8/esp4-fix-error-return-code-in-esp_output.patch b/queue-3.8/esp4-fix-error-return-code-in-esp_output.patch new file mode 100644 index 00000000000..77a327ad0de --- /dev/null +++ b/queue-3.8/esp4-fix-error-return-code-in-esp_output.patch @@ -0,0 +1,44 @@ +From 8fda48dd4d43ab3a90d29c43f4902d7225aacbae Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Sat, 13 Apr 2013 15:49:03 +0000 +Subject: esp4: fix error return code in esp_output() + + +From: Wei Yongjun + +[ Upstream commit 06848c10f720cbc20e3b784c0df24930b7304b93 ] + +Fix to return a negative error code from the error handling +case instead of 0, as returned elsewhere in this function. + +Signed-off-by: Wei Yongjun +Acked-by: Steffen Klassert +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/esp4.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -139,8 +139,6 @@ static int esp_output(struct xfrm_state + + /* skb is pure payload to encrypt */ + +- err = -ENOMEM; +- + esp = x->data; + aead = esp->aead; + alen = crypto_aead_authsize(aead); +@@ -176,8 +174,10 @@ static int esp_output(struct xfrm_state + } + + tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); +- if (!tmp) ++ if (!tmp) { ++ err = -ENOMEM; + goto error; ++ } + + seqhi = esp_tmp_seqhi(tmp); + iv = esp_tmp_iv(aead, tmp, seqhilen); diff --git a/queue-3.8/ipv6-tcp-stop-processing-icmpv6-redirect-messages.patch b/queue-3.8/ipv6-tcp-stop-processing-icmpv6-redirect-messages.patch new file mode 100644 index 00000000000..9d3846d4d80 --- /dev/null +++ b/queue-3.8/ipv6-tcp-stop-processing-icmpv6-redirect-messages.patch @@ -0,0 +1,44 @@ +From 1dbb428feb7eb340bd16cb06b90d218a4cf13e62 Mon Sep 17 00:00:00 2001 +From: Christoph Paasch +Date: Sun, 7 Apr 2013 04:53:15 +0000 +Subject: ipv6/tcp: Stop processing ICMPv6 redirect messages + + +From: Christoph Paasch + +[ Upstream commit 50a75a8914539c5dcd441c5f54d237a666a426fd ] + +Tetja Rediske found that if the host receives an ICMPv6 redirect message +after sending a SYN+ACK, the connection will be reset. + +He bisected it down to 093d04d (ipv6: Change skb->data before using +icmpv6_notify() to propagate redirect), but the origin of the bug comes +from ec18d9a26 (ipv6: Add redirect support to all protocol icmp error +handlers.). The bug simply did not trigger prior to 093d04d, because +skb->data did not point to the inner IP header and thus icmpv6_notify +did not call the correct err_handler. + +This patch adds the missing "goto out;" in tcp_v6_err. After receiving +an ICMPv6 Redirect, we should not continue processing the ICMP in +tcp_v6_err, as this may trigger the removal of request-socks or setting +sk_err(_soft). + +Reported-by: Tetja Rediske +Signed-off-by: Christoph Paasch +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/tcp_ipv6.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -386,6 +386,7 @@ static void tcp_v6_err(struct sk_buff *s + + if (dst) + dst->ops->redirect(dst, sk, skb); ++ goto out; + } + + if (type == ICMPV6_PKT_TOOBIG) { diff --git a/queue-3.8/irda-fix-missing-msg_namelen-update-in-irda_recvmsg_dgram.patch b/queue-3.8/irda-fix-missing-msg_namelen-update-in-irda_recvmsg_dgram.patch new file mode 100644 index 00000000000..3e50d56f615 --- /dev/null +++ b/queue-3.8/irda-fix-missing-msg_namelen-update-in-irda_recvmsg_dgram.patch @@ -0,0 +1,38 @@ +From cb16330582275171956014a0d17878f86ebe00ca Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:53 +0000 +Subject: irda: Fix missing msg_namelen update in irda_recvmsg_dgram() + + +From: Mathias Krause + +[ Upstream commit 5ae94c0d2f0bed41d6718be743985d61b7f5c47d ] + +The current code does not fill the msg_name member in case it is set. +It also does not set the msg_namelen member to 0 and therefore makes +net/socket.c leak the local, uninitialized sockaddr_storage variable +to userland -- 128 bytes of kernel stack memory. + +Fix that by simply setting msg_namelen to 0 as obviously nobody cared +about irda_recvmsg_dgram() not filling the msg_name in case it was +set. + +Signed-off-by: Mathias Krause +Cc: Samuel Ortiz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/irda/af_irda.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/irda/af_irda.c ++++ b/net/irda/af_irda.c +@@ -1386,6 +1386,8 @@ static int irda_recvmsg_dgram(struct kio + + IRDA_DEBUG(4, "%s()\n", __func__); + ++ msg->msg_namelen = 0; ++ + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); + if (!skb) diff --git a/queue-3.8/iucv-fix-missing-msg_namelen-update-in-iucv_sock_recvmsg.patch b/queue-3.8/iucv-fix-missing-msg_namelen-update-in-iucv_sock_recvmsg.patch new file mode 100644 index 00000000000..793aa424777 --- /dev/null +++ b/queue-3.8/iucv-fix-missing-msg_namelen-update-in-iucv_sock_recvmsg.patch @@ -0,0 +1,37 @@ +From ce54b2c8e2d39d06f18098d42ebe8f404c45f531 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:54 +0000 +Subject: iucv: Fix missing msg_namelen update in iucv_sock_recvmsg() + + +From: Mathias Krause + +[ Upstream commit a5598bd9c087dc0efc250a5221e5d0e6f584ee88 ] + +The current code does not fill the msg_name member in case it is set. +It also does not set the msg_namelen member to 0 and therefore makes +net/socket.c leak the local, uninitialized sockaddr_storage variable +to userland -- 128 bytes of kernel stack memory. + +Fix that by simply setting msg_namelen to 0 as obviously nobody cared +about iucv_sock_recvmsg() not filling the msg_name in case it was set. + +Signed-off-by: Mathias Krause +Cc: Ursula Braun +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/iucv/af_iucv.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/iucv/af_iucv.c ++++ b/net/iucv/af_iucv.c +@@ -1331,6 +1331,8 @@ static int iucv_sock_recvmsg(struct kioc + struct sk_buff *skb, *rskb, *cskb; + int err = 0; + ++ msg->msg_namelen = 0; ++ + if ((sk->sk_state == IUCV_DISCONN) && + skb_queue_empty(&iucv->backlog_skb_q) && + skb_queue_empty(&sk->sk_receive_queue) && diff --git a/queue-3.8/l2tp-fix-info-leak-in-l2tp_ip6_recvmsg.patch b/queue-3.8/l2tp-fix-info-leak-in-l2tp_ip6_recvmsg.patch new file mode 100644 index 00000000000..a12d7663aea --- /dev/null +++ b/queue-3.8/l2tp-fix-info-leak-in-l2tp_ip6_recvmsg.patch @@ -0,0 +1,33 @@ +From 6671ade6feb2e93861cb30cce6933b6ce7684791 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:55 +0000 +Subject: l2tp: fix info leak in l2tp_ip6_recvmsg() + + +From: Mathias Krause + +[ Upstream commit b860d3cc62877fad02863e2a08efff69a19382d2 ] + +The L2TP code for IPv6 fails to initialize the l2tp_conn_id member of +struct sockaddr_l2tpip6 and therefore leaks four bytes kernel stack +in l2tp_ip6_recvmsg() in case msg_name is set. + +Initialize l2tp_conn_id with 0 to avoid the info leak. + +Signed-off-by: Mathias Krause +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ip6.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -684,6 +684,7 @@ static int l2tp_ip6_recvmsg(struct kiocb + lsa->l2tp_addr = ipv6_hdr(skb)->saddr; + lsa->l2tp_flowinfo = 0; + lsa->l2tp_scope_id = 0; ++ lsa->l2tp_conn_id = 0; + if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) + lsa->l2tp_scope_id = IP6CB(skb)->iif; + } diff --git a/queue-3.8/llc-fix-missing-msg_namelen-update-in-llc_ui_recvmsg.patch b/queue-3.8/llc-fix-missing-msg_namelen-update-in-llc_ui_recvmsg.patch new file mode 100644 index 00000000000..57e9b7eb077 --- /dev/null +++ b/queue-3.8/llc-fix-missing-msg_namelen-update-in-llc_ui_recvmsg.patch @@ -0,0 +1,38 @@ +From 706733f490e5f0cb2cfce7897dfea19facf663a2 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:56 +0000 +Subject: llc: Fix missing msg_namelen update in llc_ui_recvmsg() + + +From: Mathias Krause + +[ Upstream commit c77a4b9cffb6215a15196ec499490d116dfad181 ] + +For stream sockets the code misses to update the msg_namelen member +to 0 and therefore makes net/socket.c leak the local, uninitialized +sockaddr_storage variable to userland -- 128 bytes of kernel stack +memory. The msg_namelen update is also missing for datagram sockets +in case the socket is shutting down during receive. + +Fix both issues by setting msg_namelen to 0 early. It will be +updated later if we're going to fill the msg_name member. + +Signed-off-by: Mathias Krause +Cc: Arnaldo Carvalho de Melo +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/llc/af_llc.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/llc/af_llc.c ++++ b/net/llc/af_llc.c +@@ -720,6 +720,8 @@ static int llc_ui_recvmsg(struct kiocb * + int target; /* Read at least this many bytes */ + long timeo; + ++ msg->msg_namelen = 0; ++ + lock_sock(sk); + copied = -ENOTCONN; + if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) diff --git a/queue-3.8/net-cdc_mbim-remove-bogus-sizeof.patch b/queue-3.8/net-cdc_mbim-remove-bogus-sizeof.patch new file mode 100644 index 00000000000..c6871706b11 --- /dev/null +++ b/queue-3.8/net-cdc_mbim-remove-bogus-sizeof.patch @@ -0,0 +1,31 @@ +From 39cf0635dc641cf46f6b37592cc22faff98e7a40 Mon Sep 17 00:00:00 2001 +From: Bjørn Mork +Date: Tue, 16 Apr 2013 00:17:07 +0000 +Subject: net: cdc_mbim: remove bogus sizeof() + + +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= + +[ Upstream commit 32b161aa88aa40a83888a995c6e2ef81140219b1 ] + +The intention was to test against the constant, not the size of +the constant. + +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_mbim.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/cdc_mbim.c ++++ b/drivers/net/usb/cdc_mbim.c +@@ -134,7 +134,7 @@ static struct sk_buff *cdc_mbim_tx_fixup + goto error; + + if (skb) { +- if (skb->len <= sizeof(ETH_HLEN)) ++ if (skb->len <= ETH_HLEN) + goto error; + + /* mapping VLANs to MBIM sessions: diff --git a/queue-3.8/net-count-hw_addr-syncs-so-that-unsync-works-properly.patch b/queue-3.8/net-count-hw_addr-syncs-so-that-unsync-works-properly.patch new file mode 100644 index 00000000000..66f549a799f --- /dev/null +++ b/queue-3.8/net-count-hw_addr-syncs-so-that-unsync-works-properly.patch @@ -0,0 +1,71 @@ +From 5c2f9f9cb418db7d27cd630bf6ae37e651bf892a Mon Sep 17 00:00:00 2001 +From: Vlad Yasevich +Date: Tue, 2 Apr 2013 17:10:07 -0400 +Subject: net: count hw_addr syncs so that unsync works properly. + + +From: Vlad Yasevich + +[ Upstream commit 4543fbefe6e06a9e40d9f2b28d688393a299f079 ] + +A few drivers use dev_uc_sync/unsync to synchronize the +address lists from master down to slave/lower devices. In +some cases (bond/team) a single address list is synched down +to multiple devices. At the time of unsync, we have a leak +in these lower devices, because "synced" is treated as a +boolean and the address will not be unsynced for anything after +the first device/call. + +Treat "synced" as a count (same as refcount) and allow all +unsync calls to work. + +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/netdevice.h | 2 +- + net/core/dev_addr_lists.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -208,9 +208,9 @@ struct netdev_hw_addr { + #define NETDEV_HW_ADDR_T_SLAVE 3 + #define NETDEV_HW_ADDR_T_UNICAST 4 + #define NETDEV_HW_ADDR_T_MULTICAST 5 +- bool synced; + bool global_use; + int refcount; ++ int synced; + struct rcu_head rcu_head; + }; + +--- a/net/core/dev_addr_lists.c ++++ b/net/core/dev_addr_lists.c +@@ -38,7 +38,7 @@ static int __hw_addr_create_ex(struct ne + ha->type = addr_type; + ha->refcount = 1; + ha->global_use = global; +- ha->synced = false; ++ ha->synced = 0; + list_add_tail_rcu(&ha->list, &list->list); + list->count++; + +@@ -166,7 +166,7 @@ int __hw_addr_sync(struct netdev_hw_addr + addr_len, ha->type); + if (err) + break; +- ha->synced = true; ++ ha->synced++; + ha->refcount++; + } else if (ha->refcount == 1) { + __hw_addr_del(to_list, ha->addr, addr_len, ha->type); +@@ -187,7 +187,7 @@ void __hw_addr_unsync(struct netdev_hw_a + if (ha->synced) { + __hw_addr_del(to_list, ha->addr, + addr_len, ha->type); +- ha->synced = false; ++ ha->synced--; + __hw_addr_del(from_list, ha->addr, + addr_len, ha->type); + } diff --git a/queue-3.8/net-drop-dst-before-queueing-fragments.patch b/queue-3.8/net-drop-dst-before-queueing-fragments.patch new file mode 100644 index 00000000000..07e7947a59b --- /dev/null +++ b/queue-3.8/net-drop-dst-before-queueing-fragments.patch @@ -0,0 +1,92 @@ +From 9aa364036ffffae67a7543c7403aa290a94f1419 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 16 Apr 2013 12:55:41 +0000 +Subject: net: drop dst before queueing fragments + + +From: Eric Dumazet + +[ Upstream commit 97599dc792b45b1669c3cdb9a4b365aad0232f65 ] + +Commit 4a94445c9a5c (net: Use ip_route_input_noref() in input path) +added a bug in IP defragmentation handling, as non refcounted +dst could escape an RCU protected section. + +Commit 64f3b9e203bd068 (net: ip_expire() must revalidate route) fixed +the case of timeouts, but not the general problem. + +Tom Parkin noticed crashes in UDP stack and provided a patch, +but further analysis permitted us to pinpoint the root cause. + +Before queueing a packet into a frag list, we must drop its dst, +as this dst has limited lifetime (RCU protected) + +When/if a packet is finally reassembled, we use the dst of the very +last skb, still protected by RCU and valid, as the dst of the +reassembled packet. + +Use same logic in IPv6, as there is no need to hold dst references. + +Reported-by: Tom Parkin +Tested-by: Tom Parkin +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_fragment.c | 15 +++++++++++---- + net/ipv6/reassembly.c | 13 +++++++++++-- + 2 files changed, 22 insertions(+), 6 deletions(-) + +--- a/net/ipv4/ip_fragment.c ++++ b/net/ipv4/ip_fragment.c +@@ -255,8 +255,7 @@ static void ip_expire(unsigned long arg) + if (!head->dev) + goto out_rcu_unlock; + +- /* skb dst is stale, drop it, and perform route lookup again */ +- skb_dst_drop(head); ++ /* skb has no dst, perform route lookup again */ + iph = ip_hdr(head); + err = ip_route_input_noref(head, iph->daddr, iph->saddr, + iph->tos, head->dev); +@@ -525,8 +524,16 @@ found: + qp->q.max_size = skb->len + ihl; + + if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && +- qp->q.meat == qp->q.len) +- return ip_frag_reasm(qp, prev, dev); ++ qp->q.meat == qp->q.len) { ++ unsigned long orefdst = skb->_skb_refdst; ++ ++ skb->_skb_refdst = 0UL; ++ err = ip_frag_reasm(qp, prev, dev); ++ skb->_skb_refdst = orefdst; ++ return err; ++ } ++ ++ skb_dst_drop(skb); + + write_lock(&ip4_frags.lock); + list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list); +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -342,8 +342,17 @@ found: + } + + if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && +- fq->q.meat == fq->q.len) +- return ip6_frag_reasm(fq, prev, dev); ++ fq->q.meat == fq->q.len) { ++ int res; ++ unsigned long orefdst = skb->_skb_refdst; ++ ++ skb->_skb_refdst = 0UL; ++ res = ip6_frag_reasm(fq, prev, dev); ++ skb->_skb_refdst = orefdst; ++ return res; ++ } ++ ++ skb_dst_drop(skb); + + write_lock(&ip6_frags.lock); + list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list); diff --git a/queue-3.8/net-fix-incorrect-credentials-passing.patch b/queue-3.8/net-fix-incorrect-credentials-passing.patch new file mode 100644 index 00000000000..e3bc8808421 --- /dev/null +++ b/queue-3.8/net-fix-incorrect-credentials-passing.patch @@ -0,0 +1,45 @@ +From 8c8baec451a04075610fa5a654e08e7c731e6dc9 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 19 Apr 2013 15:32:32 +0000 +Subject: net: fix incorrect credentials passing + + +From: Linus Torvalds + +[ Upstream commit 83f1b4ba917db5dc5a061a44b3403ddb6e783494 ] + +Commit 257b5358b32f ("scm: Capture the full credentials of the scm +sender") changed the credentials passing code to pass in the effective +uid/gid instead of the real uid/gid. + +Obviously this doesn't matter most of the time (since normally they are +the same), but it results in differences for suid binaries when the wrong +uid/gid ends up being used. + +This just undoes that (presumably unintentional) part of the commit. + +Reported-by: Andy Lutomirski +Cc: Eric W. Biederman +Cc: Serge E. Hallyn +Cc: David S. Miller +Signed-off-by: Linus Torvalds +Acked-by: "Eric W. Biederman" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/scm.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/net/scm.h ++++ b/include/net/scm.h +@@ -56,8 +56,8 @@ static __inline__ void scm_set_cred(stru + scm->pid = get_pid(pid); + scm->cred = cred ? get_cred(cred) : NULL; + scm->creds.pid = pid_vnr(pid); +- scm->creds.uid = cred ? cred->euid : INVALID_UID; +- scm->creds.gid = cred ? cred->egid : INVALID_GID; ++ scm->creds.uid = cred ? cred->uid : INVALID_UID; ++ scm->creds.gid = cred ? cred->gid : INVALID_GID; + } + + static __inline__ void scm_destroy_cred(struct scm_cookie *scm) diff --git a/queue-3.8/net-ipv6-fix-broken-ipv6-routing-table-after-loopback-down-up.patch b/queue-3.8/net-ipv6-fix-broken-ipv6-routing-table-after-loopback-down-up.patch new file mode 100644 index 00000000000..f265bbf782d --- /dev/null +++ b/queue-3.8/net-ipv6-fix-broken-ipv6-routing-table-after-loopback-down-up.patch @@ -0,0 +1,129 @@ +From 64d10a99b29b2aecaec4339cdb31a86b1a5c73ff Mon Sep 17 00:00:00 2001 +From: Balakumaran Kannan +Date: Tue, 2 Apr 2013 16:15:05 +0530 +Subject: net IPv6 : Fix broken IPv6 routing table after loopback down-up + + +From: Balakumaran Kannan + +[ Upstream commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f ] + +IPv6 Routing table becomes broken once we do ifdown, ifup of the loopback(lo) +interface. After down-up, routes of other interface's IPv6 addresses through +'lo' are lost. + +IPv6 addresses assigned to all interfaces are routed through 'lo' for internal +communication. Once 'lo' is down, those routing entries are removed from routing +table. But those removed entries are not being re-created properly when 'lo' is +brought up. So IPv6 addresses of other interfaces becomes unreachable from the +same machine. Also this breaks communication with other machines because of +NDISC packet processing failure. + +This patch fixes this issue by reading all interface's IPv6 addresses and adding +them to IPv6 routing table while bringing up 'lo'. + +==Testing== +Before applying the patch: +$ route -A inet6 +Kernel IPv6 routing table +Destination Next Hop Flag Met Ref Use If +2000::20/128 :: U 256 0 0 eth0 +fe80::/64 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +::1/128 :: Un 0 1 0 lo +2000::20/128 :: Un 0 1 0 lo +fe80::xxxx:xxxx:xxxx:xxxx/128 :: Un 0 1 0 lo +ff00::/8 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +$ sudo ifdown lo +$ sudo ifup lo +$ route -A inet6 +Kernel IPv6 routing table +Destination Next Hop Flag Met Ref Use If +2000::20/128 :: U 256 0 0 eth0 +fe80::/64 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +::1/128 :: Un 0 1 0 lo +ff00::/8 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +$ + +After applying the patch: +$ route -A inet6 +Kernel IPv6 routing +table +Destination Next Hop Flag Met Ref Use If +2000::20/128 :: U 256 0 0 eth0 +fe80::/64 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +::1/128 :: Un 0 1 0 lo +2000::20/128 :: Un 0 1 0 lo +fe80::xxxx:xxxx:xxxx:xxxx/128 :: Un 0 1 0 lo +ff00::/8 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +$ sudo ifdown lo +$ sudo ifup lo +$ route -A inet6 +Kernel IPv6 routing table +Destination Next Hop Flag Met Ref Use If +2000::20/128 :: U 256 0 0 eth0 +fe80::/64 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +::1/128 :: Un 0 1 0 lo +2000::20/128 :: Un 0 1 0 lo +fe80::xxxx:xxxx:xxxx:xxxx/128 :: Un 0 1 0 lo +ff00::/8 :: U 256 0 0 eth0 +::/0 :: !n -1 1 1 lo +$ + +Signed-off-by: Balakumaran Kannan +Signed-off-by: Maruthi Thotad +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2525,6 +2525,9 @@ static void sit_add_v4_addrs(struct inet + static void init_loopback(struct net_device *dev) + { + struct inet6_dev *idev; ++ struct net_device *sp_dev; ++ struct inet6_ifaddr *sp_ifa; ++ struct rt6_info *sp_rt; + + /* ::1 */ + +@@ -2536,6 +2539,30 @@ static void init_loopback(struct net_dev + } + + add_addr(idev, &in6addr_loopback, 128, IFA_HOST); ++ ++ /* Add routes to other interface's IPv6 addresses */ ++ for_each_netdev(dev_net(dev), sp_dev) { ++ if (!strcmp(sp_dev->name, dev->name)) ++ continue; ++ ++ idev = __in6_dev_get(sp_dev); ++ if (!idev) ++ continue; ++ ++ read_lock_bh(&idev->lock); ++ list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { ++ ++ if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) ++ continue; ++ ++ sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); ++ ++ /* Failure cases are ignored */ ++ if (!IS_ERR(sp_rt)) ++ ip6_ins_rt(sp_rt); ++ } ++ read_unlock_bh(&idev->lock); ++ } + } + + static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) diff --git a/queue-3.8/net-mvmdio-add-select-phylib.patch b/queue-3.8/net-mvmdio-add-select-phylib.patch new file mode 100644 index 00000000000..a537d304b59 --- /dev/null +++ b/queue-3.8/net-mvmdio-add-select-phylib.patch @@ -0,0 +1,50 @@ +From 474555434b7b6d8af925a7b3f757d67868ac523a Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Sat, 13 Apr 2013 06:18:56 +0000 +Subject: net: mvmdio: add select PHYLIB + + +From: Thomas Petazzoni + +[ Upstream commit 2e0cbf2cc2c9371f0aa198857d799175ffe231a6 ] + +The mvmdio driver uses the phylib API, so it should select the PHYLIB +symbol, otherwise, a build with mvmdio (but without mvneta) fails to +build with undefined symbols such as mdiobus_unregister, mdiobus_free, +etc. + +The mvneta driver does not use the phylib API directly, so it does not +need to select PHYLIB. It already selects the mvmdio driver anyway. + +Historically, this problem is due to the fact that the PHY handling +was originally part of mvneta, and was later moved to a separate +driver, without updating the Kconfig select statements +accordingly. And since there was no functional reason to use mvmdio +without mvneta, this case was not tested. + +Signed-off-by: Thomas Petazzoni +Reported-by: Fengguang Wu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/marvell/Kconfig ++++ b/drivers/net/ethernet/marvell/Kconfig +@@ -33,6 +33,7 @@ config MV643XX_ETH + + config MVMDIO + tristate "Marvell MDIO interface support" ++ select PHYLIB + ---help--- + This driver supports the MDIO interface found in the network + interface units of the Marvell EBU SoCs (Kirkwood, Orion5x, +@@ -45,7 +46,6 @@ config MVMDIO + config MVNETA + tristate "Marvell Armada 370/XP network interface support" + depends on MACH_ARMADA_370_XP +- select PHYLIB + select MVMDIO + ---help--- + This driver supports the network interface units in the diff --git a/queue-3.8/net-mvneta-fix-improper-tx-queue-usage-in-mvneta_tx.patch b/queue-3.8/net-mvneta-fix-improper-tx-queue-usage-in-mvneta_tx.patch new file mode 100644 index 00000000000..385a2be7fde --- /dev/null +++ b/queue-3.8/net-mvneta-fix-improper-tx-queue-usage-in-mvneta_tx.patch @@ -0,0 +1,81 @@ +From 16de7d010ca855f01e129ce7e1e12e19522a24c5 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Thu, 11 Apr 2013 23:00:37 +0200 +Subject: net: mvneta: fix improper tx queue usage in mvneta_tx() + + +From: Willy Tarreau + +[ Upstream commit ee40a116ebf139f900c3d2e6febb8388738e96d0 ] + +mvneta_tx() was using a static tx queue number causing crashes as +soon as a little bit of traffic was sent via the interface, because +it is normally expected that the same queue should be used as in +dev_queue_xmit(). + +As suggested by Ben Hutchings, let's use skb_get_queue_mapping() to +get the proper Tx queue number, and use alloc_etherdev_mqs() instead +of alloc_etherdev_mq() to create the queues. + +Both my Mirabox and my OpenBlocks AX3 used to crash without this patch +and don't anymore with it. The issue appeared in 3.8 but became more +visible after the fix allowing GSO to be enabled. + +Original work was done by Dmitri Epshtein and Thomas Petazzoni. I +just adapted it to take care of Ben's comments. + +Signed-off-by: Willy Tarreau +Cc: Dmitri Epshtein +Cc: Thomas Petazzoni +Cc: Gregory CLEMENT +Cc: Ben Hutchings +Tested-by: Gregory CLEMENT +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/mvneta.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -375,7 +375,6 @@ static int rxq_number = 8; + static int txq_number = 8; + + static int rxq_def; +-static int txq_def; + + #define MVNETA_DRIVER_NAME "mvneta" + #define MVNETA_DRIVER_VERSION "1.0" +@@ -1476,7 +1475,8 @@ error: + static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + { + struct mvneta_port *pp = netdev_priv(dev); +- struct mvneta_tx_queue *txq = &pp->txqs[txq_def]; ++ u16 txq_id = skb_get_queue_mapping(skb); ++ struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_desc *tx_desc; + struct netdev_queue *nq; + int frags = 0; +@@ -1486,7 +1486,7 @@ static int mvneta_tx(struct sk_buff *skb + goto out; + + frags = skb_shinfo(skb)->nr_frags + 1; +- nq = netdev_get_tx_queue(dev, txq_def); ++ nq = netdev_get_tx_queue(dev, txq_id); + + /* Get a descriptor for the first part of the packet */ + tx_desc = mvneta_txq_next_desc_get(txq); +@@ -2690,7 +2690,7 @@ static int mvneta_probe(struct platform_ + return -EINVAL; + } + +- dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8); ++ dev = alloc_etherdev_mqs(sizeof(struct mvneta_port), txq_number, rxq_number); + if (!dev) + return -ENOMEM; + +@@ -2844,4 +2844,3 @@ module_param(rxq_number, int, S_IRUGO); + module_param(txq_number, int, S_IRUGO); + + module_param(rxq_def, int, S_IRUGO); +-module_param(txq_def, int, S_IRUGO); diff --git a/queue-3.8/net-rate-limit-warn-bad-offload-splats.patch b/queue-3.8/net-rate-limit-warn-bad-offload-splats.patch new file mode 100644 index 00000000000..8db83a10f45 --- /dev/null +++ b/queue-3.8/net-rate-limit-warn-bad-offload-splats.patch @@ -0,0 +1,38 @@ +From ce1d4361516a5a20c4035a90d3741e4f30c35132 Mon Sep 17 00:00:00 2001 +From: Ben Greear +Date: Fri, 19 Apr 2013 10:45:52 +0000 +Subject: net: rate-limit warn-bad-offload splats. + + +From: Ben Greear + +[ Upstream commit c846ad9b880ece01bb4d8d07ba917734edf0324f ] + +If one does do something unfortunate and allow a +bad offload bug into the kernel, this the +skb_warn_bad_offload can effectively live-lock the +system, filling the logs with the same error over +and over. + +Add rate limitation to this so that box remains otherwise +functional in this case. + +Signed-off-by: Ben Greear +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2018,6 +2018,9 @@ static void skb_warn_bad_offload(const s + struct net_device *dev = skb->dev; + const char *driver = ""; + ++ if (!net_ratelimit()) ++ return; ++ + if (dev && dev->dev.parent) + driver = dev_driver_string(dev->dev.parent); + diff --git a/queue-3.8/netfilter-don-t-reset-nf_trace-in-nf_reset.patch b/queue-3.8/netfilter-don-t-reset-nf_trace-in-nf_reset.patch new file mode 100644 index 00000000000..224397fa758 --- /dev/null +++ b/queue-3.8/netfilter-don-t-reset-nf_trace-in-nf_reset.patch @@ -0,0 +1,69 @@ +From ac766bed56a80da9e9a88c1178810f0206c438ef Mon Sep 17 00:00:00 2001 +From: Patrick McHardy +Date: Fri, 5 Apr 2013 20:42:05 +0200 +Subject: netfilter: don't reset nf_trace in nf_reset() + + +From: Patrick McHardy + +[ Upstream commit 124dff01afbdbff251f0385beca84ba1b9adda68 ] + +Commit 130549fe ("netfilter: reset nf_trace in nf_reset") added code +to reset nf_trace in nf_reset(). This is wrong and unnecessary. + +nf_reset() is used in the following cases: + +- when passing packets up the the socket layer, at which point we want to + release all netfilter references that might keep modules pinned while + the packet is queued. nf_trace doesn't matter anymore at this point. + +- when encapsulating or decapsulating IPsec packets. We want to continue + tracing these packets after IPsec processing. + +- when passing packets through virtual network devices. Only devices on + that encapsulate in IPv4/v6 matter since otherwise nf_trace is not + used anymore. Its not entirely clear whether those packets should + be traced after that, however we've always done that. + +- when passing packets through virtual network devices that make the + packet cross network namespace boundaries. This is the only cases + where we clearly want to reset nf_trace and is also what the + original patch intended to fix. + +Add a new function nf_reset_trace() and use it in dev_forward_skb() to +fix this properly. + +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skbuff.h | 7 +++++++ + net/core/dev.c | 1 + + 2 files changed, 8 insertions(+) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2597,6 +2597,13 @@ static inline void nf_reset(struct sk_bu + #endif + } + ++static inline void nf_reset_trace(struct sk_buff *skb) ++{ ++#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) ++ skb->nf_trace = 0; ++#endif ++} ++ + /* Note: This doesn't put any conntrack and bridge info in dst. */ + static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src) + { +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1737,6 +1737,7 @@ int dev_forward_skb(struct net_device *d + skb->mark = 0; + secpath_reset(skb); + nf_reset(skb); ++ nf_reset_trace(skb); + return netif_rx(skb); + } + EXPORT_SYMBOL_GPL(dev_forward_skb); diff --git a/queue-3.8/netrom-fix-info-leak-via-msg_name-in-nr_recvmsg.patch b/queue-3.8/netrom-fix-info-leak-via-msg_name-in-nr_recvmsg.patch new file mode 100644 index 00000000000..205f7b8dec6 --- /dev/null +++ b/queue-3.8/netrom-fix-info-leak-via-msg_name-in-nr_recvmsg.patch @@ -0,0 +1,40 @@ +From f33c0b61452922ebdef9c48a00c62b3f0795bf6b Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:57 +0000 +Subject: netrom: fix info leak via msg_name in nr_recvmsg() + + +From: Mathias Krause + +[ Upstream commits 3ce5efad47b62c57a4f5c54248347085a750ce0e and + c802d759623acbd6e1ee9fbdabae89159a513913 ] + +In case msg_name is set the sockaddr info gets filled out, as +requested, but the code fails to initialize the padding bytes of +struct sockaddr_ax25 inserted by the compiler for alignment. Also +the sax25_ndigis member does not get assigned, leaking four more +bytes. + +Both issues lead to the fact that the code will leak uninitialized +kernel stack bytes in net/socket.c. + +Fix both issues by initializing the memory with memset(0). + +Signed-off-by: Mathias Krause +Cc: Ralf Baechle +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netrom/af_netrom.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -1177,6 +1177,7 @@ static int nr_recvmsg(struct kiocb *iocb + } + + if (sax != NULL) { ++ memset(sax, 0, sizeof(sax)); + sax->sax25_family = AF_NETROM; + skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, + AX25_ADDR_LEN); diff --git a/queue-3.8/nfc-llcp-fix-info-leaks-via-msg_name-in-llcp_sock_recvmsg.patch b/queue-3.8/nfc-llcp-fix-info-leaks-via-msg_name-in-llcp_sock_recvmsg.patch new file mode 100644 index 00000000000..bff66f8cb68 --- /dev/null +++ b/queue-3.8/nfc-llcp-fix-info-leaks-via-msg_name-in-llcp_sock_recvmsg.patch @@ -0,0 +1,57 @@ +From ce595833d47a3c40c292d044b7f4fc555b129787 Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:58 +0000 +Subject: NFC: llcp: fix info leaks via msg_name in llcp_sock_recvmsg() + + +From: Mathias Krause + +[ Upstream commit d26d6504f23e803824e8ebd14e52d4fc0a0b09cb ] + +The code in llcp_sock_recvmsg() does not initialize all the members of +struct sockaddr_nfc_llcp when filling the sockaddr info. Nor does it +initialize the padding bytes of the structure inserted by the compiler +for alignment. + +Also, if the socket is in state LLCP_CLOSED or is shutting down during +receive the msg_namelen member is not updated to 0 while otherwise +returning with 0, i.e. "success". The msg_namelen update is also +missing for stream and seqpacket sockets which don't fill the sockaddr +info. + +Both issues lead to the fact that the code will leak uninitialized +kernel stack bytes in net/socket.c. + +Fix the first issue by initializing the memory used for sockaddr info +with memset(0). Fix the second one by setting msg_namelen to 0 early. +It will be updated later if we're going to fill the msg_name member. + +Signed-off-by: Mathias Krause +Cc: Lauro Ramos Venancio +Cc: Aloisio Almeida Jr +Cc: Samuel Ortiz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/nfc/llcp/sock.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/nfc/llcp/sock.c ++++ b/net/nfc/llcp/sock.c +@@ -644,6 +644,8 @@ static int llcp_sock_recvmsg(struct kioc + + pr_debug("%p %zu\n", sk, len); + ++ msg->msg_namelen = 0; ++ + lock_sock(sk); + + if (sk->sk_state == LLCP_CLOSED && +@@ -684,6 +686,7 @@ static int llcp_sock_recvmsg(struct kioc + + pr_debug("Datagram socket %d %d\n", ui_cb->dsap, ui_cb->ssap); + ++ memset(&sockaddr, 0, sizeof(sockaddr)); + sockaddr.sa_family = AF_NFC; + sockaddr.nfc_protocol = NFC_PROTO_NFC_DEP; + sockaddr.dsap = ui_cb->dsap; diff --git a/queue-3.8/rose-fix-info-leak-via-msg_name-in-rose_recvmsg.patch b/queue-3.8/rose-fix-info-leak-via-msg_name-in-rose_recvmsg.patch new file mode 100644 index 00000000000..a7978e84339 --- /dev/null +++ b/queue-3.8/rose-fix-info-leak-via-msg_name-in-rose_recvmsg.patch @@ -0,0 +1,37 @@ +From b259b6c2209ae3bbcba64224689e58211af35a0a Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:51:59 +0000 +Subject: rose: fix info leak via msg_name in rose_recvmsg() + + +From: Mathias Krause + +[ Upstream commit 4a184233f21645cf0b719366210ed445d1024d72 ] + +The code in rose_recvmsg() does not initialize all of the members of +struct sockaddr_rose/full_sockaddr_rose when filling the sockaddr info. +Nor does it initialize the padding bytes of the structure inserted by +the compiler for alignment. This will lead to leaking uninitialized +kernel stack bytes in net/socket.c. + +Fix the issue by initializing the memory used for sockaddr info with +memset(0). + +Signed-off-by: Mathias Krause +Cc: Ralf Baechle +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rose/af_rose.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -1257,6 +1257,7 @@ static int rose_recvmsg(struct kiocb *io + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + + if (srose != NULL) { ++ memset(srose, 0, msg->msg_namelen); + srose->srose_family = AF_ROSE; + srose->srose_addr = rose->dest_addr; + srose->srose_call = rose->dest_call; diff --git a/queue-3.8/rtnetlink-call-nlmsg_parse-with-correct-header-length.patch b/queue-3.8/rtnetlink-call-nlmsg_parse-with-correct-header-length.patch new file mode 100644 index 00000000000..7aa028512ff --- /dev/null +++ b/queue-3.8/rtnetlink-call-nlmsg_parse-with-correct-header-length.patch @@ -0,0 +1,40 @@ +From 6237a0fded494a3703238c6c60348b08ab0cb502 Mon Sep 17 00:00:00 2001 +From: Michael Riesch +Date: Mon, 8 Apr 2013 05:45:26 +0000 +Subject: rtnetlink: Call nlmsg_parse() with correct header length + + +From: Michael Riesch + +[ Upstream commit 88c5b5ce5cb57af6ca2a7cf4d5715fa320448ff9 ] + +Signed-off-by: Michael Riesch +Cc: Jiri Benc +Cc: "Theodore Ts'o" +Acked-by: Mark Rustad +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/rtnetlink.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1068,7 +1068,7 @@ static int rtnl_dump_ifinfo(struct sk_bu + rcu_read_lock(); + cb->seq = net->dev_base_seq; + +- if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ++ if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, + ifla_policy) >= 0) { + + if (tb[IFLA_EXT_MASK]) +@@ -1924,7 +1924,7 @@ static u16 rtnl_calcit(struct sk_buff *s + u32 ext_filter_mask = 0; + u16 min_ifinfo_dump_size = 0; + +- if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ++ if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, + ifla_policy) >= 0) { + if (tb[IFLA_EXT_MASK]) + ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); diff --git a/queue-3.8/series b/queue-3.8/series index 13f62c41371..0863574085b 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -2,3 +2,38 @@ aio-fix-possible-invalid-memory-access-when-debug-is-enabled.patch tty-do-not-update-atime-mtime-on-read-write.patch tty-fix-atime-mtime-regression.patch sparc64-fix-race-in-tlb-batch-processing.patch +atm-update-msg_namelen-in-vcc_recvmsg.patch +ax25-fix-info-leak-via-msg_name-in-ax25_recvmsg.patch +bluetooth-fix-possible-info-leak-in-bt_sock_recvmsg.patch +bluetooth-rfcomm-fix-missing-msg_namelen-update-in-rfcomm_sock_recvmsg.patch +bluetooth-sco-fix-missing-msg_namelen-update-in-sco_sock_recvmsg.patch +caif-fix-missing-msg_namelen-update-in-caif_seqpkt_recvmsg.patch +irda-fix-missing-msg_namelen-update-in-irda_recvmsg_dgram.patch +iucv-fix-missing-msg_namelen-update-in-iucv_sock_recvmsg.patch +l2tp-fix-info-leak-in-l2tp_ip6_recvmsg.patch +llc-fix-missing-msg_namelen-update-in-llc_ui_recvmsg.patch +netrom-fix-info-leak-via-msg_name-in-nr_recvmsg.patch +nfc-llcp-fix-info-leaks-via-msg_name-in-llcp_sock_recvmsg.patch +rose-fix-info-leak-via-msg_name-in-rose_recvmsg.patch +tipc-fix-info-leaks-via-msg_name-in-recv_msg-recv_stream.patch +cbq-incorrect-processing-of-high-limits.patch +net-ipv6-fix-broken-ipv6-routing-table-after-loopback-down-up.patch +net-count-hw_addr-syncs-so-that-unsync-works-properly.patch +atl1e-limit-gso-segment-size-to-prevent-generation-of-wrong-ip-length-fields.patch +bonding-fix-bonding_masters-race-condition-in-bond-unloading.patch +bonding-iff_bonding-is-not-stripped-on-enslave-failure.patch +bonding-fix-l23-and-l34-load-balancing-in-forwarding-path.patch +af_unix-if-we-don-t-care-about-credentials-coallesce-all-messages.patch +netfilter-don-t-reset-nf_trace-in-nf_reset.patch +ipv6-tcp-stop-processing-icmpv6-redirect-messages.patch +rtnetlink-call-nlmsg_parse-with-correct-header-length.patch +tcp-incoming-connections-might-use-wrong-route-under-synflood.patch +tcp-reallocate-headroom-if-it-would-overflow-csum_start.patch +net-mvmdio-add-select-phylib.patch +esp4-fix-error-return-code-in-esp_output.patch +net-mvneta-fix-improper-tx-queue-usage-in-mvneta_tx.patch +net-cdc_mbim-remove-bogus-sizeof.patch +tcp-call-tcp_replace_ts_recent-from-tcp_ack.patch +net-rate-limit-warn-bad-offload-splats.patch +net-fix-incorrect-credentials-passing.patch +net-drop-dst-before-queueing-fragments.patch diff --git a/queue-3.8/tcp-call-tcp_replace_ts_recent-from-tcp_ack.patch b/queue-3.8/tcp-call-tcp_replace_ts_recent-from-tcp_ack.patch new file mode 100644 index 00000000000..97ce52f8593 --- /dev/null +++ b/queue-3.8/tcp-call-tcp_replace_ts_recent-from-tcp_ack.patch @@ -0,0 +1,155 @@ +From 32383565042edd5790a8351425c7b1c5303cf78b Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 19 Apr 2013 07:19:48 +0000 +Subject: tcp: call tcp_replace_ts_recent() from tcp_ack() + + +From: Eric Dumazet + +[ Upstream commit 12fb3dd9dc3c64ba7d64cec977cca9b5fb7b1d4e ] + +commit bd090dfc634d (tcp: tcp_replace_ts_recent() should not be called +from tcp_validate_incoming()) introduced a TS ecr bug in slow path +processing. + +1 A > B P. 1:10001(10000) ack 1 +2 B < A . 1:1(0) ack 1 win 257 +3 A > B . 1:1001(1000) ack 1 win 227 +4 A > B . 1001:2001(1000) ack 1 win 227 + +(ecr 200 should be ecr 300 in packets 3 & 4) + +Problem is tcp_ack() can trigger send of new packets (retransmits), +reflecting the prior TSval, instead of the TSval contained in the +currently processed incoming packet. + +Fix this by calling tcp_replace_ts_recent() from tcp_ack() after the +checks, but before the actions. + +Reported-by: Yuchung Cheng +Signed-off-by: Eric Dumazet +Cc: Neal Cardwell +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 64 ++++++++++++++++++++++++--------------------------- + 1 file changed, 31 insertions(+), 33 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -116,6 +116,7 @@ int sysctl_tcp_early_retrans __read_most + #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ + #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ + #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ ++#define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ + + #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) + #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) +@@ -3572,6 +3573,27 @@ static void tcp_send_challenge_ack(struc + } + } + ++static void tcp_store_ts_recent(struct tcp_sock *tp) ++{ ++ tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; ++ tp->rx_opt.ts_recent_stamp = get_seconds(); ++} ++ ++static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) ++{ ++ if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { ++ /* PAWS bug workaround wrt. ACK frames, the PAWS discard ++ * extra check below makes sure this can only happen ++ * for pure ACK frames. -DaveM ++ * ++ * Not only, also it occurs for expired timestamps. ++ */ ++ ++ if (tcp_paws_check(&tp->rx_opt, 0)) ++ tcp_store_ts_recent(tp); ++ } ++} ++ + /* This routine deals with incoming acks, but not outgoing ones. */ + static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) + { +@@ -3624,6 +3646,12 @@ static int tcp_ack(struct sock *sk, cons + prior_fackets = tp->fackets_out; + prior_in_flight = tcp_packets_in_flight(tp); + ++ /* ts_recent update must be made after we are sure that the packet ++ * is in window. ++ */ ++ if (flag & FLAG_UPDATE_TS_RECENT) ++ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); ++ + if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) { + /* Window is constant, pure forward advance. + * No more checks are required. +@@ -3940,27 +3968,6 @@ const u8 *tcp_parse_md5sig_option(const + EXPORT_SYMBOL(tcp_parse_md5sig_option); + #endif + +-static inline void tcp_store_ts_recent(struct tcp_sock *tp) +-{ +- tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; +- tp->rx_opt.ts_recent_stamp = get_seconds(); +-} +- +-static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) +-{ +- if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { +- /* PAWS bug workaround wrt. ACK frames, the PAWS discard +- * extra check below makes sure this can only happen +- * for pure ACK frames. -DaveM +- * +- * Not only, also it occurs for expired timestamps. +- */ +- +- if (tcp_paws_check(&tp->rx_opt, 0)) +- tcp_store_ts_recent(tp); +- } +-} +- + /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM + * + * It is not fatal. If this ACK does _not_ change critical state (seqs, window) +@@ -5556,14 +5563,9 @@ slow_path: + return 0; + + step5: +- if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) ++ if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0) + goto discard; + +- /* ts_recent update must be made after we are sure that the packet +- * is in window. +- */ +- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); +- + tcp_rcv_rtt_measure_ts(sk, skb); + + /* Process urgent data. */ +@@ -5997,7 +5999,8 @@ int tcp_rcv_state_process(struct sock *s + + /* step 5: check the ACK field */ + if (true) { +- int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0; ++ int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH | ++ FLAG_UPDATE_TS_RECENT) > 0; + + switch (sk->sk_state) { + case TCP_SYN_RECV: +@@ -6148,11 +6151,6 @@ int tcp_rcv_state_process(struct sock *s + } + } + +- /* ts_recent update must be made after we are sure that the packet +- * is in window. +- */ +- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); +- + /* step 6: check the URG bit */ + tcp_urg(sk, skb, th); + diff --git a/queue-3.8/tcp-incoming-connections-might-use-wrong-route-under-synflood.patch b/queue-3.8/tcp-incoming-connections-might-use-wrong-route-under-synflood.patch new file mode 100644 index 00000000000..2a46235bbd9 --- /dev/null +++ b/queue-3.8/tcp-incoming-connections-might-use-wrong-route-under-synflood.patch @@ -0,0 +1,41 @@ +From 1a2ed859f731eb053efa44dc25ba6fead4a50ea4 Mon Sep 17 00:00:00 2001 +From: Dmitry Popov +Date: Thu, 11 Apr 2013 08:55:07 +0000 +Subject: tcp: incoming connections might use wrong route under synflood + + +From: Dmitry Popov + +[ Upstream commit d66954a066158781ccf9c13c91d0316970fe57b6 ] + +There is a bug in cookie_v4_check (net/ipv4/syncookies.c): + flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), + RT_SCOPE_UNIVERSE, IPPROTO_TCP, + inet_sk_flowi_flags(sk), + (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, + ireq->loc_addr, th->source, th->dest); + +Here we do not respect sk->sk_bound_dev_if, therefore wrong dst_entry may be +taken. This dst_entry is used by new socket (get_cookie_sock -> +tcp_v4_syn_recv_sock), so its packets may take the wrong path. + +Signed-off-by: Dmitry Popov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/syncookies.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/syncookies.c ++++ b/net/ipv4/syncookies.c +@@ -348,8 +348,8 @@ struct sock *cookie_v4_check(struct sock + * hasn't changed since we received the original syn, but I see + * no easy way to do this. + */ +- flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), +- RT_SCOPE_UNIVERSE, IPPROTO_TCP, ++ flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark, ++ RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP, + inet_sk_flowi_flags(sk), + (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, + ireq->loc_addr, th->source, th->dest); diff --git a/queue-3.8/tcp-reallocate-headroom-if-it-would-overflow-csum_start.patch b/queue-3.8/tcp-reallocate-headroom-if-it-would-overflow-csum_start.patch new file mode 100644 index 00000000000..1fff676a854 --- /dev/null +++ b/queue-3.8/tcp-reallocate-headroom-if-it-would-overflow-csum_start.patch @@ -0,0 +1,48 @@ +From 9bb1ad12f097c85897acdff4f8b226c7f92fd52f Mon Sep 17 00:00:00 2001 +From: Thomas Graf +Date: Thu, 11 Apr 2013 10:57:18 +0000 +Subject: tcp: Reallocate headroom if it would overflow csum_start + + +From: Thomas Graf + +[ Upstream commit 50bceae9bd3569d56744882f3012734d48a1d413 ] + +If a TCP retransmission gets partially ACKed and collapsed multiple +times it is possible for the headroom to grow beyond 64K which will +overflow the 16bit skb->csum_start which is based on the start of +the headroom. It has been observed rarely in the wild with IPoIB due +to the 64K MTU. + +Verify if the acking and collapsing resulted in a headroom exceeding +what csum_start can cover and reallocate the headroom if so. + +A big thank you to Jim Foraker and the team at +LLNL for helping out with the investigation and testing. + +Reported-by: Jim Foraker +Signed-off-by: Thomas Graf +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_output.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2388,8 +2388,12 @@ int __tcp_retransmit_skb(struct sock *sk + */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + +- /* make sure skb->data is aligned on arches that require it */ +- if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { ++ /* make sure skb->data is aligned on arches that require it ++ * and check if ack-trimming & collapsing extended the headroom ++ * beyond what csum_start can cover. ++ */ ++ if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) || ++ skb_headroom(skb) >= 0xFFFF)) { + struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, + GFP_ATOMIC); + return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : diff --git a/queue-3.8/tipc-fix-info-leaks-via-msg_name-in-recv_msg-recv_stream.patch b/queue-3.8/tipc-fix-info-leaks-via-msg_name-in-recv_msg-recv_stream.patch new file mode 100644 index 00000000000..485ffb2a56e --- /dev/null +++ b/queue-3.8/tipc-fix-info-leaks-via-msg_name-in-recv_msg-recv_stream.patch @@ -0,0 +1,64 @@ +From d58e6639a0cf7fce85ad69a0906938f3754ccede Mon Sep 17 00:00:00 2001 +From: Mathias Krause +Date: Sun, 7 Apr 2013 01:52:00 +0000 +Subject: tipc: fix info leaks via msg_name in recv_msg/recv_stream + + +From: Mathias Krause + +[ Upstream commit 60085c3d009b0df252547adb336d1ccca5ce52ec ] + +The code in set_orig_addr() does not initialize all of the members of +struct sockaddr_tipc when filling the sockaddr info -- namely the union +is only partly filled. This will make recv_msg() and recv_stream() -- +the only users of this function -- leak kernel stack memory as the +msg_name member is a local variable in net/socket.c. + +Additionally to that both recv_msg() and recv_stream() fail to update +the msg_namelen member to 0 while otherwise returning with 0, i.e. +"success". This is the case for, e.g., non-blocking sockets. This will +lead to a 128 byte kernel stack leak in net/socket.c. + +Fix the first issue by initializing the memory of the union with +memset(0). Fix the second one by setting msg_namelen to 0 early as it +will be updated later if we're going to fill the msg_name member. + +Signed-off-by: Mathias Krause +Cc: Jon Maloy +Cc: Allan Stephens +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/socket.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/net/tipc/socket.c ++++ b/net/tipc/socket.c +@@ -806,6 +806,7 @@ static void set_orig_addr(struct msghdr + if (addr) { + addr->family = AF_TIPC; + addr->addrtype = TIPC_ADDR_ID; ++ memset(&addr->addr, 0, sizeof(addr->addr)); + addr->addr.id.ref = msg_origport(msg); + addr->addr.id.node = msg_orignode(msg); + addr->addr.name.domain = 0; /* could leave uninitialized */ +@@ -920,6 +921,9 @@ static int recv_msg(struct kiocb *iocb, + goto exit; + } + ++ /* will be updated in set_orig_addr() if needed */ ++ m->msg_namelen = 0; ++ + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + restart: + +@@ -1029,6 +1033,9 @@ static int recv_stream(struct kiocb *ioc + goto exit; + } + ++ /* will be updated in set_orig_addr() if needed */ ++ m->msg_namelen = 0; ++ + target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); + timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); +