]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2013 22:45:24 +0000 (14:45 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Dec 2013 22:45:24 +0000 (14:45 -0800)
added patches:
6lowpan-uncompression-of-traffic-class-field-was-incorrect.patch
af_packet-block-bh-in-prb_shutdown_retire_blk_timer.patch
atm-idt77252-fix-dev-refcnt-leak.patch
bonding-don-t-permit-to-use-arp-monitoring-in-802.3ad.patch
bonding-fix-two-race-conditions-in-bond_store_updelay-downdelay.patch
bridge-flush-br-s-address-entry-in-fdb-when-remove-the-bridge-dev.patch
connector-improved-unaligned-access-error-fix.patch
inet-fix-addr_len-msg-msg_namelen-assignment-in-recv_error-and-rxpmtu-functions.patch
inet-fix-possible-seqlock-deadlocks.patch
inet-prevent-leakage-of-uninitialized-memory-to-user-in-recv-syscalls.patch
ipv4-fix-possible-seqlock-deadlock.patch
ipv6-fix-leaking-uninitialized-port-number-of-offender-sockaddr.patch
ipv6-fix-possible-seqlock-deadlock-in-ip6_finish_output2.patch
ipv6-use-rt6_get_dflt_router-to-get-default-router-in-rt6_route_rcv.patch
isdnloop-use-strlcpy-instead-of-strcpy.patch
net-add-bug_on-if-kernel-advertises-msg_namelen-sizeof-struct-sockaddr_storage.patch
net-clamp-msg_namelen-instead-of-returning-an-error.patch
net-core-always-propagate-flag-changes-to-interfaces.patch
net-fix-ip-rule-delete-table-256.patch
net-rework-recvmsg-handler-msg_name-and-msg_namelen-logic.patch
net-update-consumers-of-msg_more-to-recognize-msg_sendpage_notlast.patch
packet-fix-use-after-free-race-in-send-path-when-dev-is-released.patch
pktgen-xfrm-update-ipv4-header-total-len-and-checksum-after-tranformation.patch
random32-fix-off-by-one-in-seeding-requirement.patch

25 files changed:
queue-3.4/6lowpan-uncompression-of-traffic-class-field-was-incorrect.patch [new file with mode: 0644]
queue-3.4/af_packet-block-bh-in-prb_shutdown_retire_blk_timer.patch [new file with mode: 0644]
queue-3.4/atm-idt77252-fix-dev-refcnt-leak.patch [new file with mode: 0644]
queue-3.4/bonding-don-t-permit-to-use-arp-monitoring-in-802.3ad.patch [new file with mode: 0644]
queue-3.4/bonding-fix-two-race-conditions-in-bond_store_updelay-downdelay.patch [new file with mode: 0644]
queue-3.4/bridge-flush-br-s-address-entry-in-fdb-when-remove-the-bridge-dev.patch [new file with mode: 0644]
queue-3.4/connector-improved-unaligned-access-error-fix.patch [new file with mode: 0644]
queue-3.4/inet-fix-addr_len-msg-msg_namelen-assignment-in-recv_error-and-rxpmtu-functions.patch [new file with mode: 0644]
queue-3.4/inet-fix-possible-seqlock-deadlocks.patch [new file with mode: 0644]
queue-3.4/inet-prevent-leakage-of-uninitialized-memory-to-user-in-recv-syscalls.patch [new file with mode: 0644]
queue-3.4/ipv4-fix-possible-seqlock-deadlock.patch [new file with mode: 0644]
queue-3.4/ipv6-fix-leaking-uninitialized-port-number-of-offender-sockaddr.patch [new file with mode: 0644]
queue-3.4/ipv6-fix-possible-seqlock-deadlock-in-ip6_finish_output2.patch [new file with mode: 0644]
queue-3.4/ipv6-use-rt6_get_dflt_router-to-get-default-router-in-rt6_route_rcv.patch [new file with mode: 0644]
queue-3.4/isdnloop-use-strlcpy-instead-of-strcpy.patch [new file with mode: 0644]
queue-3.4/net-add-bug_on-if-kernel-advertises-msg_namelen-sizeof-struct-sockaddr_storage.patch [new file with mode: 0644]
queue-3.4/net-clamp-msg_namelen-instead-of-returning-an-error.patch [new file with mode: 0644]
queue-3.4/net-core-always-propagate-flag-changes-to-interfaces.patch [new file with mode: 0644]
queue-3.4/net-fix-ip-rule-delete-table-256.patch [new file with mode: 0644]
queue-3.4/net-rework-recvmsg-handler-msg_name-and-msg_namelen-logic.patch [new file with mode: 0644]
queue-3.4/net-update-consumers-of-msg_more-to-recognize-msg_sendpage_notlast.patch [new file with mode: 0644]
queue-3.4/packet-fix-use-after-free-race-in-send-path-when-dev-is-released.patch [new file with mode: 0644]
queue-3.4/pktgen-xfrm-update-ipv4-header-total-len-and-checksum-after-tranformation.patch [new file with mode: 0644]
queue-3.4/random32-fix-off-by-one-in-seeding-requirement.patch [new file with mode: 0644]
queue-3.4/series [new file with mode: 0644]

diff --git a/queue-3.4/6lowpan-uncompression-of-traffic-class-field-was-incorrect.patch b/queue-3.4/6lowpan-uncompression-of-traffic-class-field-was-incorrect.patch
new file mode 100644 (file)
index 0000000..f4fa54d
--- /dev/null
@@ -0,0 +1,66 @@
+From 9166a67ae670706b04669ff50f1dd9964d13609d Mon Sep 17 00:00:00 2001
+From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
+Date: Wed, 13 Nov 2013 11:03:39 +0200
+Subject: 6lowpan: Uncompression of traffic class field was incorrect
+
+From: Jukka Rissanen <jukka.rissanen@linux.intel.com>
+
+[ Upstream commit 1188f05497e7bd2f2614b99c54adfbe7413d5749 ]
+
+If priority/traffic class field in IPv6 header is set (seen when
+using ssh), the uncompression sets the TC and Flow fields incorrectly.
+
+Example:
+
+This is IPv6 header of a sent packet. Note the priority/TC (=1) in
+the first byte.
+
+00000000: 61 00 00 00 00 2c 06 40 fe 80 00 00 00 00 00 00
+00000010: 02 02 72 ff fe c6 42 10 fe 80 00 00 00 00 00 00
+00000020: 02 1e ab ff fe 4c 52 57
+
+This gets compressed like this in the sending side
+
+00000000: 72 31 04 06 02 1e ab ff fe 4c 52 57 ec c2 00 16
+00000010: aa 2d fe 92 86 4e be c6 ....
+
+In the receiving end, the packet gets uncompressed to this
+IPv6 header
+
+00000000: 60 06 06 02 00 2a 1e 40 fe 80 00 00 00 00 00 00
+00000010: 02 02 72 ff fe c6 42 10 fe 80 00 00 00 00 00 00
+00000020: ab ff fe 4c 52 57 ec c2
+
+First four bytes are set incorrectly and we have also lost
+two bytes from destination address.
+
+The fix is to switch the case values in switch statement
+when checking the TC field.
+
+Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ieee802154/6lowpan.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -803,7 +803,7 @@ lowpan_process_data(struct sk_buff *skb)
+        * Traffic class carried in-line
+        * ECN + DSCP (1 byte), Flow Label is elided
+        */
+-      case 1: /* 10b */
++      case 2: /* 10b */
+               if (!skb->len)
+                       goto drop;
+               tmp = lowpan_fetch_skb_u8(skb);
+@@ -816,7 +816,7 @@ lowpan_process_data(struct sk_buff *skb)
+        * Flow Label carried in-line
+        * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided
+        */
+-      case 2: /* 01b */
++      case 1: /* 01b */
+               if (!skb->len)
+                       goto drop;
+               tmp = lowpan_fetch_skb_u8(skb);
diff --git a/queue-3.4/af_packet-block-bh-in-prb_shutdown_retire_blk_timer.patch b/queue-3.4/af_packet-block-bh-in-prb_shutdown_retire_blk_timer.patch
new file mode 100644 (file)
index 0000000..c602c4b
--- /dev/null
@@ -0,0 +1,45 @@
+From 07bf91b33e8ba6a244998e1c71d57cc457976b12 Mon Sep 17 00:00:00 2001
+From: Veaceslav Falico <vfalico@redhat.com>
+Date: Fri, 29 Nov 2013 09:53:23 +0100
+Subject: af_packet: block BH in prb_shutdown_retire_blk_timer()
+
+From: Veaceslav Falico <vfalico@redhat.com>
+
+[ Upstream commit ec6f809ff6f19fafba3212f6aff0dda71dfac8e8 ]
+
+Currently we're using plain spin_lock() in prb_shutdown_retire_blk_timer(),
+however the timer might fire right in the middle and thus try to re-aquire
+the same spinlock, leaving us in a endless loop.
+
+To fix that, use the spin_lock_bh() to block it.
+
+Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
+CC: "David S. Miller" <davem@davemloft.net>
+CC: Daniel Borkmann <dborkman@redhat.com>
+CC: Willem de Bruijn <willemb@google.com>
+CC: Phil Sutter <phil@nwl.cc>
+CC: Eric Dumazet <edumazet@google.com>
+Reported-by: Jan Stancek <jstancek@redhat.com>
+Tested-by: Jan Stancek <jstancek@redhat.com>
+Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
+Acked-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/packet/af_packet.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -504,9 +504,9 @@ static void prb_shutdown_retire_blk_time
+       pkc = tx_ring ? &po->tx_ring.prb_bdqc : &po->rx_ring.prb_bdqc;
+-      spin_lock(&rb_queue->lock);
++      spin_lock_bh(&rb_queue->lock);
+       pkc->delete_blk_timer = 1;
+-      spin_unlock(&rb_queue->lock);
++      spin_unlock_bh(&rb_queue->lock);
+       prb_del_retire_blk_timer(pkc);
+ }
diff --git a/queue-3.4/atm-idt77252-fix-dev-refcnt-leak.patch b/queue-3.4/atm-idt77252-fix-dev-refcnt-leak.patch
new file mode 100644 (file)
index 0000000..8a57085
--- /dev/null
@@ -0,0 +1,31 @@
+From 45ee678a710241649447c04860469c112bb9403b Mon Sep 17 00:00:00 2001
+From: Ying Xue <ying.xue@windriver.com>
+Date: Tue, 19 Nov 2013 18:09:27 +0800
+Subject: atm: idt77252: fix dev refcnt leak
+
+From: Ying Xue <ying.xue@windriver.com>
+
+[ Upstream commit b5de4a22f157ca345cdb3575207bf46402414bc1 ]
+
+init_card() calls dev_get_by_name() to get a network deceive. But it
+doesn't decrease network device reference count after the device is
+used.
+
+Signed-off-by: Ying Xue <ying.xue@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/atm/idt77252.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/atm/idt77252.c
++++ b/drivers/atm/idt77252.c
+@@ -3513,7 +3513,7 @@ init_card(struct atm_dev *dev)
+       tmp = dev_get_by_name(&init_net, tname);        /* jhs: was "tmp = dev_get(tname);" */
+       if (tmp) {
+               memcpy(card->atmdev->esi, tmp->dev_addr, 6);
+-
++              dev_put(tmp);
+               printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
+       }
+       /*
diff --git a/queue-3.4/bonding-don-t-permit-to-use-arp-monitoring-in-802.3ad.patch b/queue-3.4/bonding-don-t-permit-to-use-arp-monitoring-in-802.3ad.patch
new file mode 100644 (file)
index 0000000..d13442f
--- /dev/null
@@ -0,0 +1,41 @@
+From 662e7198d3a32ead59e923430aedfe0bcbaf50fb Mon Sep 17 00:00:00 2001
+From: Veaceslav Falico <vfalico@redhat.com>
+Date: Tue, 12 Nov 2013 15:37:40 +0100
+Subject: bonding: don't permit to use ARP monitoring in 802.3ad
+ mode
+
+From: Veaceslav Falico <vfalico@redhat.com>
+
+[ Upstream commit ec9f1d15db8185f63a2c3143dc1e90ba18541b08 ]
+
+Currently the ARP monitoring is not supported with 802.3ad, and it's
+prohibited to use it via the module params.
+
+However we still can set it afterwards via sysfs, cause we only check for
+*LB modes there.
+
+To fix this - add a check for 802.3ad mode in bonding_store_arp_interval.
+
+Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
+CC: Jay Vosburgh <fubar@us.ibm.com>
+CC: Andy Gospodarek <andy@greyhouse.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_sysfs.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -533,8 +533,9 @@ static ssize_t bonding_store_arp_interva
+               goto out;
+       }
+       if (bond->params.mode == BOND_MODE_ALB ||
+-          bond->params.mode == BOND_MODE_TLB) {
+-              pr_info("%s: ARP monitoring cannot be used with ALB/TLB. Only MII monitoring is supported on %s.\n",
++          bond->params.mode == BOND_MODE_TLB ||
++          bond->params.mode == BOND_MODE_8023AD) {
++              pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
+                       bond->dev->name, bond->dev->name);
+               ret = -EINVAL;
+               goto out;
diff --git a/queue-3.4/bonding-fix-two-race-conditions-in-bond_store_updelay-downdelay.patch b/queue-3.4/bonding-fix-two-race-conditions-in-bond_store_updelay-downdelay.patch
new file mode 100644 (file)
index 0000000..469463c
--- /dev/null
@@ -0,0 +1,63 @@
+From c3c1e8d01623d528a8f912fd846460f788eefaa8 Mon Sep 17 00:00:00 2001
+From: Nikolay Aleksandrov <nikolay@redhat.com>
+Date: Wed, 13 Nov 2013 17:07:46 +0100
+Subject: bonding: fix two race conditions in bond_store_updelay/downdelay
+
+From: Nikolay Aleksandrov <nikolay@redhat.com>
+
+[ Upstream commit b869ccfab1e324507fa3596e3e1308444fb68227 ]
+
+This patch fixes two race conditions between bond_store_updelay/downdelay
+and bond_store_miimon which could lead to division by zero as miimon can
+be set to 0 while either updelay/downdelay are being set and thus miss the
+zero check in the beginning, the zero div happens because updelay/downdelay
+are stored as new_value / bond->params.miimon. Use rtnl to synchronize with
+miimon setting.
+
+Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
+CC: Jay Vosburgh <fubar@us.ibm.com>
+CC: Andy Gospodarek <andy@greyhouse.net>
+CC: Veaceslav Falico <vfalico@redhat.com>
+Acked-by: Veaceslav Falico <vfalico@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_sysfs.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/bonding/bond_sysfs.c
++++ b/drivers/net/bonding/bond_sysfs.c
+@@ -693,6 +693,8 @@ static ssize_t bonding_store_downdelay(s
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(d);
++      if (!rtnl_trylock())
++              return restart_syscall();
+       if (!(bond->params.miimon)) {
+               pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
+                      bond->dev->name);
+@@ -726,6 +728,7 @@ static ssize_t bonding_store_downdelay(s
+       }
+ out:
++      rtnl_unlock();
+       return ret;
+ }
+ static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
+@@ -748,6 +751,8 @@ static ssize_t bonding_store_updelay(str
+       int new_value, ret = count;
+       struct bonding *bond = to_bond(d);
++      if (!rtnl_trylock())
++              return restart_syscall();
+       if (!(bond->params.miimon)) {
+               pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
+                      bond->dev->name);
+@@ -781,6 +786,7 @@ static ssize_t bonding_store_updelay(str
+       }
+ out:
++      rtnl_unlock();
+       return ret;
+ }
+ static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
diff --git a/queue-3.4/bridge-flush-br-s-address-entry-in-fdb-when-remove-the-bridge-dev.patch b/queue-3.4/bridge-flush-br-s-address-entry-in-fdb-when-remove-the-bridge-dev.patch
new file mode 100644 (file)
index 0000000..250a538
--- /dev/null
@@ -0,0 +1,67 @@
+From 93080918b643c0ff849ca0a69bb920ddb07d07dc Mon Sep 17 00:00:00 2001
+From: Ding Tianhong <dingtianhong@huawei.com>
+Date: Sat, 7 Dec 2013 22:12:05 +0800
+Subject: bridge: flush br's address entry in fdb when remove the bridge dev
+
+From: Ding Tianhong <dingtianhong@huawei.com>
+
+[ Upstream commit f873042093c0b418d2351fe142222b625c740149 ]
+
+When the following commands are executed:
+
+brctl addbr br0
+ifconfig br0 hw ether <addr>
+rmmod bridge
+
+The calltrace will occur:
+
+[  563.312114] device eth1 left promiscuous mode
+[  563.312188] br0: port 1(eth1) entered disabled state
+[  563.468190] kmem_cache_destroy bridge_fdb_cache: Slab cache still has objects
+[  563.468197] CPU: 6 PID: 6982 Comm: rmmod Tainted: G           O 3.12.0-0.7-default+ #9
+[  563.468199] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
+[  563.468200]  0000000000000880 ffff88010f111e98 ffffffff814d1c92 ffff88010f111eb8
+[  563.468204]  ffffffff81148efd ffff88010f111eb8 0000000000000000 ffff88010f111ec8
+[  563.468206]  ffffffffa062a270 ffff88010f111ed8 ffffffffa063ac76 ffff88010f111f78
+[  563.468209] Call Trace:
+[  563.468218]  [<ffffffff814d1c92>] dump_stack+0x6a/0x78
+[  563.468234]  [<ffffffff81148efd>] kmem_cache_destroy+0xfd/0x100
+[  563.468242]  [<ffffffffa062a270>] br_fdb_fini+0x10/0x20 [bridge]
+[  563.468247]  [<ffffffffa063ac76>] br_deinit+0x4e/0x50 [bridge]
+[  563.468254]  [<ffffffff810c7dc9>] SyS_delete_module+0x199/0x2b0
+[  563.468259]  [<ffffffff814e0922>] system_call_fastpath+0x16/0x1b
+[  570.377958] Bridge firewalling registered
+
+--------------------------- cut here -------------------------------
+
+The reason is that when the bridge dev's address is changed, the
+br_fdb_change_mac_address() will add new address in fdb, but when
+the bridge was removed, the address entry in the fdb did not free,
+the bridge_fdb_cache still has objects when destroy the cache, Fix
+this by flushing the bridge address entry when removing the bridge.
+
+v2: according to the Toshiaki Makita and Vlad's suggestion, I only
+    delete the vlan0 entry, it still have a leak here if the vlan id
+    is other number, so I need to call fdb_delete_by_port(br, NULL, 1)
+    to flush all entries whose dst is NULL for the bridge.
+
+Suggested-by: Toshiaki Makita <toshiaki.makita1@gmail.com>
+Suggested-by: Vlad Yasevich <vyasevich@gmail.com>
+Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bridge/br_if.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/bridge/br_if.c
++++ b/net/bridge/br_if.c
+@@ -170,6 +170,8 @@ void br_dev_delete(struct net_device *de
+               del_nbp(p);
+       }
++      br_fdb_delete_by_port(br, NULL, 1);
++
+       del_timer_sync(&br->gc_timer);
+       br_sysfs_delbr(br->dev);
diff --git a/queue-3.4/connector-improved-unaligned-access-error-fix.patch b/queue-3.4/connector-improved-unaligned-access-error-fix.patch
new file mode 100644 (file)
index 0000000..e02a378
--- /dev/null
@@ -0,0 +1,238 @@
+From c34f0776fcd67a39a213552ccb885266b1fe958c Mon Sep 17 00:00:00 2001
+From: Chris Metcalf <cmetcalf@tilera.com>
+Date: Thu, 14 Nov 2013 12:09:21 -0500
+Subject: connector: improved unaligned access error fix
+
+From: Chris Metcalf <cmetcalf@tilera.com>
+
+[ Upstream commit 1ca1a4cf59ea343a1a70084fe7cc96f37f3cf5b1 ]
+
+In af3e095a1fb4, Erik Jacobsen fixed one type of unaligned access
+bug for ia64 by converting a 64-bit write to use put_unaligned().
+Unfortunately, since gcc will convert a short memset() to a series
+of appropriately-aligned stores, the problem is now visible again
+on tilegx, where the memset that zeros out proc_event is converted
+to three 64-bit stores, causing an unaligned access panic.
+
+A better fix for the original problem is to ensure that proc_event
+is aligned to 8 bytes here.  We can do that relatively easily by
+arranging to start the struct cn_msg aligned to 8 bytes and then
+offset by 4 bytes.  Doing so means that the immediately following
+proc_event structure is then correctly aligned to 8 bytes.
+
+The result is that the memset() stores are now aligned, and as an
+added benefit, we can remove the put_unaligned() calls in the code.
+
+Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/connector/cn_proc.c |   66 ++++++++++++++++++++++++++------------------
+ 1 file changed, 39 insertions(+), 27 deletions(-)
+
+--- a/drivers/connector/cn_proc.c
++++ b/drivers/connector/cn_proc.c
+@@ -31,11 +31,23 @@
+ #include <linux/ptrace.h>
+ #include <linux/atomic.h>
+-#include <asm/unaligned.h>
+-
+ #include <linux/cn_proc.h>
+-#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
++/*
++ * Size of a cn_msg followed by a proc_event structure.  Since the
++ * sizeof struct cn_msg is a multiple of 4 bytes, but not 8 bytes, we
++ * add one 4-byte word to the size here, and then start the actual
++ * cn_msg structure 4 bytes into the stack buffer.  The result is that
++ * the immediately following proc_event structure is aligned to 8 bytes.
++ */
++#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event) + 4)
++
++/* See comment above; we test our assumption about sizeof struct cn_msg here. */
++static inline struct cn_msg *buffer_to_cn_msg(__u8 *buffer)
++{
++      BUILD_BUG_ON(sizeof(struct cn_msg) != 20);
++      return (struct cn_msg *)(buffer + 4);
++}
+ static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
+ static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
+@@ -55,19 +67,19 @@ void proc_fork_connector(struct task_str
+ {
+       struct cn_msg *msg;
+       struct proc_event *ev;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       struct timespec ts;
+       struct task_struct *parent;
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg*)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event*)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->what = PROC_EVENT_FORK;
+       rcu_read_lock();
+       parent = rcu_dereference(task->real_parent);
+@@ -90,17 +102,17 @@ void proc_exec_connector(struct task_str
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       struct timespec ts;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg*)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event*)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->what = PROC_EVENT_EXEC;
+       ev->event_data.exec.process_pid = task->pid;
+       ev->event_data.exec.process_tgid = task->tgid;
+@@ -116,14 +128,14 @@ void proc_id_connector(struct task_struc
+ {
+       struct cn_msg *msg;
+       struct proc_event *ev;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       struct timespec ts;
+       const struct cred *cred;
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg*)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event*)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       ev->what = which_id;
+@@ -144,7 +156,7 @@ void proc_id_connector(struct task_struc
+       rcu_read_unlock();
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+@@ -158,17 +170,17 @@ void proc_sid_connector(struct task_stru
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       struct timespec ts;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg *)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event *)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->what = PROC_EVENT_SID;
+       ev->event_data.sid.process_pid = task->pid;
+       ev->event_data.sid.process_tgid = task->tgid;
+@@ -185,17 +197,17 @@ void proc_ptrace_connector(struct task_s
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       struct timespec ts;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg *)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event *)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->what = PROC_EVENT_PTRACE;
+       ev->event_data.ptrace.process_pid  = task->pid;
+       ev->event_data.ptrace.process_tgid = task->tgid;
+@@ -220,17 +232,17 @@ void proc_comm_connector(struct task_str
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       struct timespec ts;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg *)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event *)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->what = PROC_EVENT_COMM;
+       ev->event_data.comm.process_pid  = task->pid;
+       ev->event_data.comm.process_tgid = task->tgid;
+@@ -247,18 +259,18 @@ void proc_exit_connector(struct task_str
+ {
+       struct cn_msg *msg;
+       struct proc_event *ev;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       struct timespec ts;
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg*)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event*)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       get_seq(&msg->seq, &ev->cpu);
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->what = PROC_EVENT_EXIT;
+       ev->event_data.exit.process_pid = task->pid;
+       ev->event_data.exit.process_tgid = task->tgid;
+@@ -284,18 +296,18 @@ static void cn_proc_ack(int err, int rcv
+ {
+       struct cn_msg *msg;
+       struct proc_event *ev;
+-      __u8 buffer[CN_PROC_MSG_SIZE];
++      __u8 buffer[CN_PROC_MSG_SIZE] __aligned(8);
+       struct timespec ts;
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+-      msg = (struct cn_msg*)buffer;
++      msg = buffer_to_cn_msg(buffer);
+       ev = (struct proc_event*)msg->data;
+       memset(&ev->event_data, 0, sizeof(ev->event_data));
+       msg->seq = rcvd_seq;
+       ktime_get_ts(&ts); /* get high res monotonic timestamp */
+-      put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
++      ev->timestamp_ns = timespec_to_ns(&ts);
+       ev->cpu = -1;
+       ev->what = PROC_EVENT_NONE;
+       ev->event_data.ack.err = err;
diff --git a/queue-3.4/inet-fix-addr_len-msg-msg_namelen-assignment-in-recv_error-and-rxpmtu-functions.patch b/queue-3.4/inet-fix-addr_len-msg-msg_namelen-assignment-in-recv_error-and-rxpmtu-functions.patch
new file mode 100644 (file)
index 0000000..d3f3dae
--- /dev/null
@@ -0,0 +1,186 @@
+From 33498dfa419c0683dc010d7d6aee79ceac0d2598 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Sat, 23 Nov 2013 00:46:12 +0100
+Subject: inet: fix addr_len/msg->msg_namelen assignment in recv_error and rxpmtu functions
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 85fbaa75037d0b6b786ff18658ddf0b4014ce2a4 ]
+
+Commit bceaa90240b6019ed73b49965eac7d167610be69 ("inet: prevent leakage
+of uninitialized memory to user in recv syscalls") conditionally updated
+addr_len if the msg_name is written to. The recv_error and rxpmtu
+functions relied on the recvmsg functions to set up addr_len before.
+
+As this does not happen any more we have to pass addr_len to those
+functions as well and set it to the size of the corresponding sockaddr
+length.
+
+This broke traceroute and such.
+
+Fixes: bceaa90240b6 ("inet: prevent leakage of uninitialized memory to user in recv syscalls")
+Reported-by: Brad Spengler <spender@grsecurity.net>
+Reported-by: Tom Labanowski
+Cc: mpb <mpb.mail@gmail.com>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/ip.h       |    2 +-
+ include/net/ipv6.h     |    6 ++++--
+ net/ipv4/ip_sockglue.c |    3 ++-
+ net/ipv4/ping.c        |    2 +-
+ net/ipv4/raw.c         |    2 +-
+ net/ipv4/udp.c         |    2 +-
+ net/ipv6/datagram.c    |    7 +++++--
+ net/ipv6/raw.c         |    4 ++--
+ net/ipv6/udp.c         |    4 ++--
+ 9 files changed, 19 insertions(+), 13 deletions(-)
+
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -466,7 +466,7 @@ extern int compat_ip_getsockopt(struct s
+                       int optname, char __user *optval, int __user *optlen);
+ extern int    ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
+-extern int    ip_recv_error(struct sock *sk, struct msghdr *msg, int len);
++extern int    ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len);
+ extern void   ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
+                             __be16 port, u32 info, u8 *payload);
+ extern void   ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -606,8 +606,10 @@ extern int                        compat_ipv6_getsockopt(stru
+ extern int                    ip6_datagram_connect(struct sock *sk, 
+                                                    struct sockaddr *addr, int addr_len);
+-extern int                    ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len);
+-extern int                    ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len);
++extern int                    ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len,
++                                              int *addr_len);
++extern int                    ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
++                                               int *addr_len);
+ extern void                   ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port,
+                                               u32 info, u8 *payload);
+ extern void                   ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info);
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -367,7 +367,7 @@ void ip_local_error(struct sock *sk, int
+ /*
+  *    Handle MSG_ERRQUEUE
+  */
+-int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
++int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
+ {
+       struct sock_exterr_skb *serr;
+       struct sk_buff *skb, *skb2;
+@@ -404,6 +404,7 @@ int ip_recv_error(struct sock *sk, struc
+                                                  serr->addr_offset);
+               sin->sin_port = serr->port;
+               memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
++              *addr_len = sizeof(*sin);
+       }
+       memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -634,7 +634,7 @@ static int ping_recvmsg(struct kiocb *io
+               goto out;
+       if (flags & MSG_ERRQUEUE)
+-              return ip_recv_error(sk, msg, len);
++              return ip_recv_error(sk, msg, len, addr_len);
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       if (!skb)
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -689,7 +689,7 @@ static int raw_recvmsg(struct kiocb *ioc
+               goto out;
+       if (flags & MSG_ERRQUEUE) {
+-              err = ip_recv_error(sk, msg, len);
++              err = ip_recv_error(sk, msg, len, addr_len);
+               goto out;
+       }
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1175,7 +1175,7 @@ int udp_recvmsg(struct kiocb *iocb, stru
+       bool slow;
+       if (flags & MSG_ERRQUEUE)
+-              return ip_recv_error(sk, msg, len);
++              return ip_recv_error(sk, msg, len, addr_len);
+ try_again:
+       skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -315,7 +315,7 @@ void ipv6_local_rxpmtu(struct sock *sk,
+ /*
+  *    Handle MSG_ERRQUEUE
+  */
+-int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
++int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
+ {
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct sock_exterr_skb *serr;
+@@ -366,6 +366,7 @@ int ipv6_recv_error(struct sock *sk, str
+                       ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
+                                              &sin->sin6_addr);
+               }
++              *addr_len = sizeof(*sin);
+       }
+       memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
+@@ -418,7 +419,8 @@ out:
+ /*
+  *    Handle IPV6_RECVPATHMTU
+  */
+-int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len)
++int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
++                   int *addr_len)
+ {
+       struct ipv6_pinfo *np = inet6_sk(sk);
+       struct sk_buff *skb;
+@@ -452,6 +454,7 @@ int ipv6_recv_rxpmtu(struct sock *sk, st
+               sin->sin6_port = 0;
+               sin->sin6_scope_id = mtu_info.ip6m_addr.sin6_scope_id;
+               sin->sin6_addr = mtu_info.ip6m_addr.sin6_addr;
++              *addr_len = sizeof(*sin);
+       }
+       put_cmsg(msg, SOL_IPV6, IPV6_PATHMTU, sizeof(mtu_info), &mtu_info);
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -458,10 +458,10 @@ static int rawv6_recvmsg(struct kiocb *i
+               return -EOPNOTSUPP;
+       if (flags & MSG_ERRQUEUE)
+-              return ipv6_recv_error(sk, msg, len);
++              return ipv6_recv_error(sk, msg, len, addr_len);
+       if (np->rxpmtu && np->rxopt.bits.rxpmtu)
+-              return ipv6_recv_rxpmtu(sk, msg, len);
++              return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       if (!skb)
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -349,10 +349,10 @@ int udpv6_recvmsg(struct kiocb *iocb, st
+       bool slow;
+       if (flags & MSG_ERRQUEUE)
+-              return ipv6_recv_error(sk, msg, len);
++              return ipv6_recv_error(sk, msg, len, addr_len);
+       if (np->rxpmtu && np->rxopt.bits.rxpmtu)
+-              return ipv6_recv_rxpmtu(sk, msg, len);
++              return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
+ try_again:
+       skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
diff --git a/queue-3.4/inet-fix-possible-seqlock-deadlocks.patch b/queue-3.4/inet-fix-possible-seqlock-deadlocks.patch
new file mode 100644 (file)
index 0000000..64224b1
--- /dev/null
@@ -0,0 +1,64 @@
+From 88e4ffcdd0da58eb3da8a71a6d9fd0567c9315e5 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 28 Nov 2013 09:51:22 -0800
+Subject: inet: fix possible seqlock deadlocks
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit f1d8cba61c3c4b1eb88e507249c4cb8d635d9a76 ]
+
+In commit c9e9042994d3 ("ipv4: fix possible seqlock deadlock") I left
+another places where IP_INC_STATS_BH() were improperly used.
+
+udp_sendmsg(), ping_v4_sendmsg() and tcp_v4_connect() are called from
+process context, not from softirq context.
+
+This was detected by lockdep seqlock support.
+
+Reported-by: jongman heo <jongman.heo@samsung.com>
+Fixes: 584bdf8cbdf6 ("[IPV4]: Fix "ipOutNoRoutes" counter error for TCP and UDP")
+Fixes: c319b4d76b9e ("net: ipv4: add IPPROTO_ICMP socket kind")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ping.c     |    2 +-
+ net/ipv4/tcp_ipv4.c |    2 +-
+ net/ipv4/udp.c      |    2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -568,7 +568,7 @@ static int ping_sendmsg(struct kiocb *io
+               err = PTR_ERR(rt);
+               rt = NULL;
+               if (err == -ENETUNREACH)
+-                      IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
++                      IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
+               goto out;
+       }
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -176,7 +176,7 @@ int tcp_v4_connect(struct sock *sk, stru
+       if (IS_ERR(rt)) {
+               err = PTR_ERR(rt);
+               if (err == -ENETUNREACH)
+-                      IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
++                      IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+               return err;
+       }
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -940,7 +940,7 @@ int udp_sendmsg(struct kiocb *iocb, stru
+                       err = PTR_ERR(rt);
+                       rt = NULL;
+                       if (err == -ENETUNREACH)
+-                              IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
++                              IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
+                       goto out;
+               }
diff --git a/queue-3.4/inet-prevent-leakage-of-uninitialized-memory-to-user-in-recv-syscalls.patch b/queue-3.4/inet-prevent-leakage-of-uninitialized-memory-to-user-in-recv-syscalls.patch
new file mode 100644 (file)
index 0000000..532ff3e
--- /dev/null
@@ -0,0 +1,198 @@
+From 61506657b555fcf130f6e474b1c1e88437c398b9 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Mon, 18 Nov 2013 04:20:45 +0100
+Subject: inet: prevent leakage of uninitialized memory to user in recv syscalls
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit bceaa90240b6019ed73b49965eac7d167610be69 ]
+
+Only update *addr_len when we actually fill in sockaddr, otherwise we
+can return uninitialized memory from the stack to the caller in the
+recvfrom, recvmmsg and recvmsg syscalls. Drop the the (addr_len == NULL)
+checks because we only get called with a valid addr_len pointer either
+from sock_common_recvmsg or inet_recvmsg.
+
+If a blocking read waits on a socket which is concurrently shut down we
+now return zero and set msg_msgnamelen to 0.
+
+Reported-by: mpb <mpb.mail@gmail.com>
+Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ping.c       |    9 ++++-----
+ net/ipv4/raw.c        |    4 +---
+ net/ipv4/udp.c        |    7 +------
+ net/ipv6/raw.c        |    4 +---
+ net/ipv6/udp.c        |    5 +----
+ net/l2tp/l2tp_ip.c    |    4 +---
+ net/phonet/datagram.c |    9 ++++-----
+ 7 files changed, 13 insertions(+), 29 deletions(-)
+
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -624,7 +624,6 @@ static int ping_recvmsg(struct kiocb *io
+                       size_t len, int noblock, int flags, int *addr_len)
+ {
+       struct inet_sock *isk = inet_sk(sk);
+-      struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
+       struct sk_buff *skb;
+       int copied, err;
+@@ -634,9 +633,6 @@ static int ping_recvmsg(struct kiocb *io
+       if (flags & MSG_OOB)
+               goto out;
+-      if (addr_len)
+-              *addr_len = sizeof(*sin);
+-
+       if (flags & MSG_ERRQUEUE)
+               return ip_recv_error(sk, msg, len);
+@@ -658,11 +654,14 @@ static int ping_recvmsg(struct kiocb *io
+       sock_recv_timestamp(msg, sk, skb);
+       /* Copy the address. */
+-      if (sin) {
++      if (msg->msg_name) {
++              struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
++
+               sin->sin_family = AF_INET;
+               sin->sin_port = 0 /* skb->h.uh->source */;
+               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+               memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++              *addr_len = sizeof(*sin);
+       }
+       if (isk->cmsg_flags)
+               ip_cmsg_recv(msg, skb);
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -688,9 +688,6 @@ static int raw_recvmsg(struct kiocb *ioc
+       if (flags & MSG_OOB)
+               goto out;
+-      if (addr_len)
+-              *addr_len = sizeof(*sin);
+-
+       if (flags & MSG_ERRQUEUE) {
+               err = ip_recv_error(sk, msg, len);
+               goto out;
+@@ -718,6 +715,7 @@ static int raw_recvmsg(struct kiocb *ioc
+               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+               sin->sin_port = 0;
+               memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
++              *addr_len = sizeof(*sin);
+       }
+       if (inet->cmsg_flags)
+               ip_cmsg_recv(msg, skb);
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1174,12 +1174,6 @@ int udp_recvmsg(struct kiocb *iocb, stru
+       int is_udplite = IS_UDPLITE(sk);
+       bool slow;
+-      /*
+-       *      Check any passed addresses
+-       */
+-      if (addr_len)
+-              *addr_len = sizeof(*sin);
+-
+       if (flags & MSG_ERRQUEUE)
+               return ip_recv_error(sk, msg, len);
+@@ -1234,6 +1228,7 @@ try_again:
+               sin->sin_port = udp_hdr(skb)->source;
+               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+               memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
++              *addr_len = sizeof(*sin);
+       }
+       if (inet->cmsg_flags)
+               ip_cmsg_recv(msg, skb);
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -457,9 +457,6 @@ static int rawv6_recvmsg(struct kiocb *i
+       if (flags & MSG_OOB)
+               return -EOPNOTSUPP;
+-      if (addr_len)
+-              *addr_len=sizeof(*sin6);
+-
+       if (flags & MSG_ERRQUEUE)
+               return ipv6_recv_error(sk, msg, len);
+@@ -499,6 +496,7 @@ static int rawv6_recvmsg(struct kiocb *i
+               sin6->sin6_scope_id = 0;
+               if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                       sin6->sin6_scope_id = IP6CB(skb)->iif;
++              *addr_len = sizeof(*sin6);
+       }
+       sock_recv_ts_and_drops(msg, sk, skb);
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -348,9 +348,6 @@ int udpv6_recvmsg(struct kiocb *iocb, st
+       int is_udp4;
+       bool slow;
+-      if (addr_len)
+-              *addr_len=sizeof(struct sockaddr_in6);
+-
+       if (flags & MSG_ERRQUEUE)
+               return ipv6_recv_error(sk, msg, len);
+@@ -423,7 +420,7 @@ try_again:
+                       if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+                               sin6->sin6_scope_id = IP6CB(skb)->iif;
+               }
+-
++              *addr_len = sizeof(*sin6);
+       }
+       if (is_udp4) {
+               if (inet->cmsg_flags)
+--- a/net/l2tp/l2tp_ip.c
++++ b/net/l2tp/l2tp_ip.c
+@@ -569,9 +569,6 @@ static int l2tp_ip_recvmsg(struct kiocb
+       if (flags & MSG_OOB)
+               goto out;
+-      if (addr_len)
+-              *addr_len = sizeof(*sin);
+-
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       if (!skb)
+               goto out;
+@@ -594,6 +591,7 @@ static int l2tp_ip_recvmsg(struct kiocb
+               sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+               sin->sin_port = 0;
+               memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
++              *addr_len = sizeof(*sin);
+       }
+       if (inet->cmsg_flags)
+               ip_cmsg_recv(msg, skb);
+--- a/net/phonet/datagram.c
++++ b/net/phonet/datagram.c
+@@ -139,9 +139,6 @@ static int pn_recvmsg(struct kiocb *iocb
+                       MSG_CMSG_COMPAT))
+               goto out_nofree;
+-      if (addr_len)
+-              *addr_len = sizeof(sa);
+-
+       skb = skb_recv_datagram(sk, flags, noblock, &rval);
+       if (skb == NULL)
+               goto out_nofree;
+@@ -162,8 +159,10 @@ static int pn_recvmsg(struct kiocb *iocb
+       rval = (flags & MSG_TRUNC) ? skb->len : copylen;
+-      if (msg->msg_name != NULL)
+-              memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
++      if (msg->msg_name != NULL) {
++              memcpy(msg->msg_name, &sa, sizeof(sa));
++              *addr_len = sizeof(sa);
++      }
+ out:
+       skb_free_datagram(sk, skb);
diff --git a/queue-3.4/ipv4-fix-possible-seqlock-deadlock.patch b/queue-3.4/ipv4-fix-possible-seqlock-deadlock.patch
new file mode 100644 (file)
index 0000000..fc5657d
--- /dev/null
@@ -0,0 +1,34 @@
+From c78b16fc2fef309fc0b3f814d6b221baf0685c69 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 14 Nov 2013 13:37:54 -0800
+Subject: ipv4: fix possible seqlock deadlock
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit c9e9042994d37cbc1ee538c500e9da1bb9d1bcdf ]
+
+ip4_datagram_connect() being called from process context,
+it should use IP_INC_STATS() instead of IP_INC_STATS_BH()
+otherwise we can deadlock on 32bit arches, or get corruptions of
+SNMP counters.
+
+Fixes: 584bdf8cbdf6 ("[IPV4]: Fix "ipOutNoRoutes" counter error for TCP and UDP")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Dave Jones <davej@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/datagram.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/datagram.c
++++ b/net/ipv4/datagram.c
+@@ -57,7 +57,7 @@ int ip4_datagram_connect(struct sock *sk
+       if (IS_ERR(rt)) {
+               err = PTR_ERR(rt);
+               if (err == -ENETUNREACH)
+-                      IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
++                      IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
+               goto out;
+       }
diff --git a/queue-3.4/ipv6-fix-leaking-uninitialized-port-number-of-offender-sockaddr.patch b/queue-3.4/ipv6-fix-leaking-uninitialized-port-number-of-offender-sockaddr.patch
new file mode 100644 (file)
index 0000000..bae725c
--- /dev/null
@@ -0,0 +1,28 @@
+From 49376c90b2f7fe89a0b07b029c397c958bd1c8dc Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Sat, 23 Nov 2013 07:22:33 +0100
+Subject: ipv6: fix leaking uninitialized port number of offender sockaddr
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 1fa4c710b6fe7b0aac9907240291b6fe6aafc3b8 ]
+
+Offenders don't have port numbers, so set it to 0.
+
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/datagram.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -375,6 +375,7 @@ int ipv6_recv_error(struct sock *sk, str
+       if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL) {
+               sin->sin6_family = AF_INET6;
+               sin->sin6_flowinfo = 0;
++              sin->sin6_port = 0;
+               sin->sin6_scope_id = 0;
+               if (skb->protocol == htons(ETH_P_IPV6)) {
+                       sin->sin6_addr = ipv6_hdr(skb)->saddr;
diff --git a/queue-3.4/ipv6-fix-possible-seqlock-deadlock-in-ip6_finish_output2.patch b/queue-3.4/ipv6-fix-possible-seqlock-deadlock-in-ip6_finish_output2.patch
new file mode 100644 (file)
index 0000000..9fa3cfd
--- /dev/null
@@ -0,0 +1,35 @@
+From 6fa73581e6b77e1a5aa8f433db9c0333282bfaed Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Fri, 29 Nov 2013 06:39:44 +0100
+Subject: ipv6: fix possible seqlock deadlock in ip6_finish_output2
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 7f88c6b23afbd31545c676dea77ba9593a1a14bf ]
+
+IPv6 stats are 64 bits and thus are protected with a seqlock. By not
+disabling bottom-half we could deadlock here if we don't disable bh and
+a softirq reentrantly updates the same mib.
+
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ip6_output.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -144,8 +144,8 @@ static int ip6_finish_output2(struct sk_
+               return res;
+       }
+       rcu_read_unlock();
+-      IP6_INC_STATS_BH(dev_net(dst->dev),
+-                       ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
++      IP6_INC_STATS(dev_net(dst->dev),
++                    ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
+       kfree_skb(skb);
+       return -EINVAL;
+ }
diff --git a/queue-3.4/ipv6-use-rt6_get_dflt_router-to-get-default-router-in-rt6_route_rcv.patch b/queue-3.4/ipv6-use-rt6_get_dflt_router-to-get-default-router-in-rt6_route_rcv.patch
new file mode 100644 (file)
index 0000000..a152acb
--- /dev/null
@@ -0,0 +1,43 @@
+From fd70e6c7a132571d378dba0bd4addea348d00317 Mon Sep 17 00:00:00 2001
+From: Duan Jiong <duanj.fnst@cn.fujitsu.com>
+Date: Fri, 8 Nov 2013 09:56:53 +0800
+Subject: ipv6: use rt6_get_dflt_router to get default router in rt6_route_rcv
+
+From: Duan Jiong <duanj.fnst@cn.fujitsu.com>
+
+[ Upstream commit f104a567e673f382b09542a8dc3500aa689957b4 ]
+
+As the rfc 4191 said, the Router Preference and Lifetime values in a
+::/0 Route Information Option should override the preference and lifetime
+values in the Router Advertisement header. But when the kernel deals with
+a ::/0 Route Information Option, the rt6_get_route_info() always return
+NULL, that means that overriding will not happen, because those default
+routers were added without flag RTF_ROUTEINFO in rt6_add_dflt_router().
+
+In order to deal with that condition, we should call rt6_get_dflt_router
+when the prefix length is 0.
+
+Signed-off-by: Duan Jiong <duanj.fnst@cn.fujitsu.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/route.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -617,8 +617,11 @@ int rt6_route_rcv(struct net_device *dev
+               prefix = &prefix_buf;
+       }
+-      rt = rt6_get_route_info(net, prefix, rinfo->prefix_len, gwaddr,
+-                              dev->ifindex);
++      if (rinfo->prefix_len == 0)
++              rt = rt6_get_dflt_router(gwaddr, dev);
++      else
++              rt = rt6_get_route_info(net, prefix, rinfo->prefix_len,
++                                      gwaddr, dev->ifindex);
+       if (rt && !lifetime) {
+               ip6_del_rt(rt);
diff --git a/queue-3.4/isdnloop-use-strlcpy-instead-of-strcpy.patch b/queue-3.4/isdnloop-use-strlcpy-instead-of-strcpy.patch
new file mode 100644 (file)
index 0000000..c2e23b7
--- /dev/null
@@ -0,0 +1,43 @@
+From 21a51586ad8d6665fde3b8250b3b517bf6440ea3 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 14 Nov 2013 11:21:10 +0300
+Subject: isdnloop: use strlcpy() instead of strcpy()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit f9a23c84486ed350cce7bb1b2828abd1f6658796 ]
+
+These strings come from a copy_from_user() and there is no way to be
+sure they are NUL terminated.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/isdn/isdnloop/isdnloop.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/isdn/isdnloop/isdnloop.c
++++ b/drivers/isdn/isdnloop/isdnloop.c
+@@ -1083,8 +1083,10 @@ isdnloop_start(isdnloop_card *card, isdn
+                       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+                       return -ENOMEM;
+               }
+-              for (i = 0; i < 3; i++)
+-                      strcpy(card->s0num[i], sdef.num[i]);
++              for (i = 0; i < 3; i++) {
++                      strlcpy(card->s0num[i], sdef.num[i],
++                              sizeof(card->s0num[0]));
++              }
+               break;
+       case ISDN_PTYPE_1TR6:
+               if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95",
+@@ -1097,7 +1099,7 @@ isdnloop_start(isdnloop_card *card, isdn
+                       spin_unlock_irqrestore(&card->isdnloop_lock, flags);
+                       return -ENOMEM;
+               }
+-              strcpy(card->s0num[0], sdef.num[0]);
++              strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0]));
+               card->s0num[1][0] = '\0';
+               card->s0num[2][0] = '\0';
+               break;
diff --git a/queue-3.4/net-add-bug_on-if-kernel-advertises-msg_namelen-sizeof-struct-sockaddr_storage.patch b/queue-3.4/net-add-bug_on-if-kernel-advertises-msg_namelen-sizeof-struct-sockaddr_storage.patch
new file mode 100644 (file)
index 0000000..1403a6c
--- /dev/null
@@ -0,0 +1,40 @@
+From 763799b13192e076a22f19ac4cdeb50ab1e3e3b9 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 21 Nov 2013 03:14:34 +0100
+Subject: net: add BUG_ON if kernel advertises msg_namelen > sizeof(struct sockaddr_storage)
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit 68c6beb373955da0886d8f4f5995b3922ceda4be ]
+
+In that case it is probable that kernel code overwrote part of the
+stack. So we should bail out loudly here.
+
+The BUG_ON may be removed in future if we are sure all protocols are
+conformant.
+
+Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/socket.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -215,12 +215,13 @@ static int move_addr_to_user(struct sock
+       int err;
+       int len;
++      BUG_ON(klen > sizeof(struct sockaddr_storage));
+       err = get_user(len, ulen);
+       if (err)
+               return err;
+       if (len > klen)
+               len = klen;
+-      if (len < 0 || len > sizeof(struct sockaddr_storage))
++      if (len < 0)
+               return -EINVAL;
+       if (len) {
+               if (audit_sockaddr(klen, kaddr))
diff --git a/queue-3.4/net-clamp-msg_namelen-instead-of-returning-an-error.patch b/queue-3.4/net-clamp-msg_namelen-instead-of-returning-an-error.patch
new file mode 100644 (file)
index 0000000..141b5f8
--- /dev/null
@@ -0,0 +1,52 @@
+From 0cd7168f61e9fca226bcc1052463995348ff4e3d Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 27 Nov 2013 15:40:21 +0300
+Subject: net: clamp ->msg_namelen instead of returning an error
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit db31c55a6fb245fdbb752a2ca4aefec89afabb06 ]
+
+If kmsg->msg_namelen > sizeof(struct sockaddr_storage) then in the
+original code that would lead to memory corruption in the kernel if you
+had audit configured.  If you didn't have audit configured it was
+harmless.
+
+There are some programs such as beta versions of Ruby which use too
+large of a buffer and returning an error code breaks them.  We should
+clamp the ->msg_namelen value instead.
+
+Fixes: 1661bf364ae9 ("net: heap overflow in __audit_sockaddr()")
+Reported-by: Eric Wong <normalperson@yhbt.net>
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Tested-by: Eric Wong <normalperson@yhbt.net>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/compat.c |    2 +-
+ net/socket.c |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/compat.c
++++ b/net/compat.c
+@@ -72,7 +72,7 @@ int get_compat_msghdr(struct msghdr *kms
+           __get_user(kmsg->msg_flags, &umsg->msg_flags))
+               return -EFAULT;
+       if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+-              return -EINVAL;
++              kmsg->msg_namelen = sizeof(struct sockaddr_storage);
+       kmsg->msg_name = compat_ptr(tmp1);
+       kmsg->msg_iov = compat_ptr(tmp2);
+       kmsg->msg_control = compat_ptr(tmp3);
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -1908,7 +1908,7 @@ static int copy_msghdr_from_user(struct
+       if (copy_from_user(kmsg, umsg, sizeof(struct msghdr)))
+               return -EFAULT;
+       if (kmsg->msg_namelen > sizeof(struct sockaddr_storage))
+-              return -EINVAL;
++              kmsg->msg_namelen = sizeof(struct sockaddr_storage);
+       return 0;
+ }
diff --git a/queue-3.4/net-core-always-propagate-flag-changes-to-interfaces.patch b/queue-3.4/net-core-always-propagate-flag-changes-to-interfaces.patch
new file mode 100644 (file)
index 0000000..3ce72bb
--- /dev/null
@@ -0,0 +1,66 @@
+From b25ff8eccf41750a86dd50e108db225944ae8149 Mon Sep 17 00:00:00 2001
+From: Vlad Yasevich <vyasevic@redhat.com>
+Date: Tue, 19 Nov 2013 20:47:15 -0500
+Subject: net: core: Always propagate flag changes to interfaces
+
+From: Vlad Yasevich <vyasevic@redhat.com>
+
+[ Upstream commit d2615bf450694c1302d86b9cc8a8958edfe4c3a4 ]
+
+The following commit:
+    b6c40d68ff6498b7f63ddf97cf0aa818d748dee7
+    net: only invoke dev->change_rx_flags when device is UP
+
+tried to fix a problem with VLAN devices and promiscuouse flag setting.
+The issue was that VLAN device was setting a flag on an interface that
+was down, thus resulting in bad promiscuity count.
+This commit blocked flag propagation to any device that is currently
+down.
+
+A later commit:
+    deede2fabe24e00bd7e246eb81cd5767dc6fcfc7
+    vlan: Don't propagate flag changes on down interfaces
+
+fixed VLAN code to only propagate flags when the VLAN interface is up,
+thus fixing the same issue as above, only localized to VLAN.
+
+The problem we have now is that if we have create a complex stack
+involving multiple software devices like bridges, bonds, and vlans,
+then it is possible that the flags would not propagate properly to
+the physical devices.  A simple examle of the scenario is the
+following:
+
+  eth0----> bond0 ----> bridge0 ---> vlan50
+
+If bond0 or eth0 happen to be down at the time bond0 is added to
+the bridge, then eth0 will never have promisc mode set which is
+currently required for operation as part of the bridge.  As a
+result, packets with vlan50 will be dropped by the interface.
+
+The only 2 devices that implement the special flag handling are
+VLAN and DSA and they both have required code to prevent incorrect
+flag propagation.  As a result we can remove the generic solution
+introduced in b6c40d68ff6498b7f63ddf97cf0aa818d748dee7 and leave
+it to the individual devices to decide whether they will block
+flag propagation or not.
+
+Reported-by: Stefan Priebe <s.priebe@profihost.ag>
+Suggested-by: Veaceslav Falico <vfalico@redhat.com>
+Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -4443,7 +4443,7 @@ static void dev_change_rx_flags(struct n
+ {
+       const struct net_device_ops *ops = dev->netdev_ops;
+-      if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
++      if (ops->ndo_change_rx_flags)
+               ops->ndo_change_rx_flags(dev, flags);
+ }
diff --git a/queue-3.4/net-fix-ip-rule-delete-table-256.patch b/queue-3.4/net-fix-ip-rule-delete-table-256.patch
new file mode 100644 (file)
index 0000000..ec47ef3
--- /dev/null
@@ -0,0 +1,41 @@
+From dc15739b011195bd7b778f0b93ad22598538a2ac Mon Sep 17 00:00:00 2001
+From: Andreas Henriksson <andreas@fatal.se>
+Date: Thu, 7 Nov 2013 18:26:38 +0100
+Subject: net: Fix "ip rule delete table 256"
+
+From: Andreas Henriksson <andreas@fatal.se>
+
+[ Upstream commit 13eb2ab2d33c57ebddc57437a7d341995fc9138c ]
+
+When trying to delete a table >= 256 using iproute2 the local table
+will be deleted.
+The table id is specified as a netlink attribute when it needs more then
+8 bits and iproute2 then sets the table field to RT_TABLE_UNSPEC (0).
+Preconditions to matching the table id in the rule delete code
+doesn't seem to take the "table id in netlink attribute" into condition
+so the frh_get_table helper function never gets to do its job when
+matching against current rule.
+Use the helper function twice instead of peaking at the table value directly.
+
+Originally reported at: http://bugs.debian.org/724783
+
+Reported-by: Nicolas HICHER <nhicher@avencall.com>
+Signed-off-by: Andreas Henriksson <andreas@fatal.se>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/fib_rules.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/core/fib_rules.c
++++ b/net/core/fib_rules.c
+@@ -443,7 +443,8 @@ static int fib_nl_delrule(struct sk_buff
+               if (frh->action && (frh->action != rule->action))
+                       continue;
+-              if (frh->table && (frh_get_table(frh, tb) != rule->table))
++              if (frh_get_table(frh, tb) &&
++                  (frh_get_table(frh, tb) != rule->table))
+                       continue;
+               if (tb[FRA_PRIORITY] &&
diff --git a/queue-3.4/net-rework-recvmsg-handler-msg_name-and-msg_namelen-logic.patch b/queue-3.4/net-rework-recvmsg-handler-msg_name-and-msg_namelen-logic.patch
new file mode 100644 (file)
index 0000000..5f3ddc6
--- /dev/null
@@ -0,0 +1,653 @@
+From fc14c68c76c0265cb1c8e1a945923241bebe7b24 Mon Sep 17 00:00:00 2001
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Date: Thu, 21 Nov 2013 03:14:22 +0100
+Subject: net: rework recvmsg handler msg_name and msg_namelen logic
+
+From: Hannes Frederic Sowa <hannes@stressinduktion.org>
+
+[ Upstream commit f3d3342602f8bcbf37d7c46641cb9bca7618eb1c ]
+
+This patch now always passes msg->msg_namelen as 0. recvmsg handlers must
+set msg_namelen to the proper size <= sizeof(struct sockaddr_storage)
+to return msg_name to the user.
+
+This prevents numerous uninitialized memory leaks we had in the
+recvmsg handlers and makes it harder for new code to accidentally leak
+uninitialized memory.
+
+Optimize for the case recvfrom is called with NULL as address. We don't
+need to copy the address at all, so set it to NULL before invoking the
+recvmsg handler. We can do so, because all the recvmsg handlers must
+cope with the case a plain read() is called on them. read() also sets
+msg_name to NULL.
+
+Also document these changes in include/linux/net.h as suggested by David
+Miller.
+
+Changes since RFC:
+
+Set msg->msg_name = NULL if user specified a NULL in msg_name but had a
+non-null msg_namelen in verify_iovec/verify_compat_iovec. This doesn't
+affect sendto as it would bail out earlier while trying to copy-in the
+address. It also more naturally reflects the logic by the callers of
+verify_iovec.
+
+With this change in place I could remove "
+if (!uaddr || msg_sys->msg_namelen == 0)
+       msg->msg_name = NULL
+".
+
+This change does not alter the user visible error logic as we ignore
+msg_namelen as long as msg_name is NULL.
+
+Also remove two unnecessary curly brackets in ___sys_recvmsg and change
+comments to netdev style.
+
+Cc: David Miller <davem@davemloft.net>
+Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/algif_hash.c          |    2 --
+ crypto/algif_skcipher.c      |    1 -
+ drivers/isdn/mISDN/socket.c  |   13 ++++---------
+ drivers/net/ppp/pppoe.c      |    2 --
+ include/linux/net.h          |    8 ++++++++
+ net/appletalk/ddp.c          |   16 +++++++---------
+ net/atm/common.c             |    2 --
+ net/ax25/af_ax25.c           |    4 ++--
+ net/bluetooth/af_bluetooth.c |    4 ----
+ net/bluetooth/hci_sock.c     |    2 --
+ net/bluetooth/rfcomm/sock.c  |    1 -
+ net/caif/caif_socket.c       |    4 ----
+ net/compat.c                 |    3 ++-
+ net/core/iovec.c             |    3 ++-
+ net/ipx/af_ipx.c             |    3 +--
+ net/irda/af_irda.c           |    4 ----
+ net/iucv/af_iucv.c           |    2 --
+ net/key/af_key.c             |    1 -
+ net/l2tp/l2tp_ppp.c          |    2 --
+ net/llc/af_llc.c             |    2 --
+ net/netlink/af_netlink.c     |    2 --
+ net/netrom/af_netrom.c       |    3 +--
+ net/nfc/rawsock.c            |    2 --
+ net/packet/af_packet.c       |   32 +++++++++++++++-----------------
+ net/rds/recv.c               |    2 --
+ net/rose/af_rose.c           |    8 +++++---
+ net/rxrpc/ar-recvmsg.c       |    9 ++++++---
+ net/socket.c                 |   19 +++++++++++--------
+ net/tipc/socket.c            |    6 ------
+ net/unix/af_unix.c           |    5 -----
+ net/x25/af_x25.c             |    3 +--
+ 31 files changed, 65 insertions(+), 105 deletions(-)
+
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -161,8 +161,6 @@ static int hash_recvmsg(struct kiocb *un
+       else if (len < ds)
+               msg->msg_flags |= MSG_TRUNC;
+-      msg->msg_namelen = 0;
+-
+       lock_sock(sk);
+       if (ctx->more) {
+               ctx->more = 0;
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -432,7 +432,6 @@ static int skcipher_recvmsg(struct kiocb
+       long copied = 0;
+       lock_sock(sk);
+-      msg->msg_namelen = 0;
+       for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
+            iovlen--, iov++) {
+               unsigned long seglen = iov->iov_len;
+--- a/drivers/isdn/mISDN/socket.c
++++ b/drivers/isdn/mISDN/socket.c
+@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, s
+ {
+       struct sk_buff          *skb;
+       struct sock             *sk = sock->sk;
+-      struct sockaddr_mISDN   *maddr;
+       int             copied, err;
+@@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, s
+       if (!skb)
+               return err;
+-      if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
+-              msg->msg_namelen = sizeof(struct sockaddr_mISDN);
+-              maddr = (struct sockaddr_mISDN *)msg->msg_name;
++      if (msg->msg_name) {
++              struct sockaddr_mISDN *maddr = msg->msg_name;
++
+               maddr->family = AF_ISDN;
+               maddr->dev = _pms(sk)->dev->id;
+               if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
+@@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, s
+                       maddr->sapi = _pms(sk)->ch.addr & 0xFF;
+                       maddr->tei =  (_pms(sk)->ch.addr >> 8) & 0xFF;
+               }
+-      } else {
+-              if (msg->msg_namelen)
+-                      printk(KERN_WARNING "%s: too small namelen %d\n",
+-                             __func__, msg->msg_namelen);
+-              msg->msg_namelen = 0;
++              msg->msg_namelen = sizeof(*maddr);
+       }
+       copied = skb->len + MISDN_HEADER_LEN;
+--- a/drivers/net/ppp/pppoe.c
++++ b/drivers/net/ppp/pppoe.c
+@@ -985,8 +985,6 @@ static int pppoe_recvmsg(struct kiocb *i
+       if (error < 0)
+               goto end;
+-      m->msg_namelen = 0;
+-
+       if (skb) {
+               total_len = min_t(size_t, total_len, skb->len);
+               error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -198,6 +198,14 @@ struct proto_ops {
+ #endif
+       int             (*sendmsg)   (struct kiocb *iocb, struct socket *sock,
+                                     struct msghdr *m, size_t total_len);
++      /* Notes for implementing recvmsg:
++       * ===============================
++       * msg->msg_namelen should get updated by the recvmsg handlers
++       * iff msg_name != NULL. It is by default 0 to prevent
++       * returning uninitialized memory to user space.  The recvfrom
++       * handlers can assume that msg.msg_name is either NULL or has
++       * a minimum size of sizeof(struct sockaddr_storage).
++       */
+       int             (*recvmsg)   (struct kiocb *iocb, struct socket *sock,
+                                     struct msghdr *m, size_t total_len,
+                                     int flags);
+--- a/net/appletalk/ddp.c
++++ b/net/appletalk/ddp.c
+@@ -1740,7 +1740,6 @@ static int atalk_recvmsg(struct kiocb *i
+                        size_t size, int flags)
+ {
+       struct sock *sk = sock->sk;
+-      struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
+       struct ddpehdr *ddp;
+       int copied = 0;
+       int offset = 0;
+@@ -1769,14 +1768,13 @@ static int atalk_recvmsg(struct kiocb *i
+       }
+       err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
+-      if (!err) {
+-              if (sat) {
+-                      sat->sat_family      = AF_APPLETALK;
+-                      sat->sat_port        = ddp->deh_sport;
+-                      sat->sat_addr.s_node = ddp->deh_snode;
+-                      sat->sat_addr.s_net  = ddp->deh_snet;
+-              }
+-              msg->msg_namelen = sizeof(*sat);
++      if (!err && msg->msg_name) {
++              struct sockaddr_at *sat = msg->msg_name;
++              sat->sat_family      = AF_APPLETALK;
++              sat->sat_port        = ddp->deh_sport;
++              sat->sat_addr.s_node = ddp->deh_snode;
++              sat->sat_addr.s_net  = ddp->deh_snet;
++              msg->msg_namelen     = sizeof(*sat);
+       }
+       skb_free_datagram(sk, skb);     /* Free the datagram. */
+--- a/net/atm/common.c
++++ b/net/atm/common.c
+@@ -520,8 +520,6 @@ 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;
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -1640,11 +1640,11 @@ static int ax25_recvmsg(struct kiocb *io
+       skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+-      if (msg->msg_namelen != 0) {
+-              struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
++      if (msg->msg_name) {
+               ax25_digi digi;
+               ax25_address src;
+               const unsigned char *mac = skb_mac_header(skb);
++              struct sockaddr_ax25 *sax = msg->msg_name;
+               memset(sax, 0, sizeof(struct full_sockaddr_ax25));
+               ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -240,8 +240,6 @@ 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)
+@@ -306,8 +304,6 @@ int bt_sock_stream_recvmsg(struct kiocb
+       if (flags & MSG_OOB)
+               return -EOPNOTSUPP;
+-      msg->msg_namelen = 0;
+-
+       BT_DBG("sk %p size %zu", sk, size);
+       lock_sock(sk);
+--- a/net/bluetooth/hci_sock.c
++++ b/net/bluetooth/hci_sock.c
+@@ -767,8 +767,6 @@ static int hci_sock_recvmsg(struct kiocb
+       if (!skb)
+               return err;
+-      msg->msg_namelen = 0;
+-
+       copied = skb->len;
+       if (len < copied) {
+               msg->msg_flags |= MSG_TRUNC;
+--- a/net/bluetooth/rfcomm/sock.c
++++ b/net/bluetooth/rfcomm/sock.c
+@@ -628,7 +628,6 @@ 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;
+       }
+--- a/net/caif/caif_socket.c
++++ b/net/caif/caif_socket.c
+@@ -287,8 +287,6 @@ 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;
+@@ -362,8 +360,6 @@ static int caif_stream_recvmsg(struct ki
+       if (flags&MSG_OOB)
+               goto out;
+-      msg->msg_namelen = 0;
+-
+       /*
+        * Lock the socket to prevent queue disordering
+        * while sleeps in memcpy_tomsg
+--- a/net/compat.c
++++ b/net/compat.c
+@@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *k
+                       if (err < 0)
+                               return err;
+               }
+-              kern_msg->msg_name = kern_address;
++              if (kern_msg->msg_name)
++                      kern_msg->msg_name = kern_address;
+       } else
+               kern_msg->msg_name = NULL;
+--- a/net/core/iovec.c
++++ b/net/core/iovec.c
+@@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struc
+                       if (err < 0)
+                               return err;
+               }
+-              m->msg_name = address;
++              if (m->msg_name)
++                      m->msg_name = address;
+       } else {
+               m->msg_name = NULL;
+       }
+--- a/net/ipx/af_ipx.c
++++ b/net/ipx/af_ipx.c
+@@ -1835,8 +1835,6 @@ static int ipx_recvmsg(struct kiocb *ioc
+       if (skb->tstamp.tv64)
+               sk->sk_stamp = skb->tstamp;
+-      msg->msg_namelen = sizeof(*sipx);
+-
+       if (sipx) {
+               sipx->sipx_family       = AF_IPX;
+               sipx->sipx_port         = ipx->ipx_source.sock;
+@@ -1844,6 +1842,7 @@ static int ipx_recvmsg(struct kiocb *ioc
+               sipx->sipx_network      = IPX_SKB_CB(skb)->ipx_source_net;
+               sipx->sipx_type         = ipx->ipx_type;
+               sipx->sipx_zero         = 0;
++              msg->msg_namelen        = sizeof(*sipx);
+       }
+       rc = copied;
+--- a/net/irda/af_irda.c
++++ b/net/irda/af_irda.c
+@@ -1386,8 +1386,6 @@ 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)
+@@ -1452,8 +1450,6 @@ static int irda_recvmsg_stream(struct ki
+       target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+       timeo = sock_rcvtimeo(sk, noblock);
+-      msg->msg_namelen = 0;
+-
+       do {
+               int chunk;
+               struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -1331,8 +1331,6 @@ 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) &&
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -3595,7 +3595,6 @@ static int pfkey_recvmsg(struct kiocb *k
+       if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
+               goto out;
+-      msg->msg_namelen = 0;
+       skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
+       if (skb == NULL)
+               goto out;
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -200,8 +200,6 @@ static int pppol2tp_recvmsg(struct kiocb
+       if (sk->sk_state & PPPOX_BOUND)
+               goto end;
+-      msg->msg_namelen = 0;
+-
+       err = 0;
+       skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+                               flags & MSG_DONTWAIT, &err);
+--- a/net/llc/af_llc.c
++++ b/net/llc/af_llc.c
+@@ -721,8 +721,6 @@ 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))
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1443,8 +1443,6 @@ static int netlink_recvmsg(struct kiocb
+       }
+ #endif
+-      msg->msg_namelen = 0;
+-
+       copied = data_skb->len;
+       if (len < copied) {
+               msg->msg_flags |= MSG_TRUNC;
+--- a/net/netrom/af_netrom.c
++++ b/net/netrom/af_netrom.c
+@@ -1181,10 +1181,9 @@ static int nr_recvmsg(struct kiocb *iocb
+               sax->sax25_family = AF_NETROM;
+               skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
+                             AX25_ADDR_LEN);
++              msg->msg_namelen = sizeof(*sax);
+       }
+-      msg->msg_namelen = sizeof(*sax);
+-
+       skb_free_datagram(sk, skb);
+       release_sock(sk);
+--- a/net/nfc/rawsock.c
++++ b/net/nfc/rawsock.c
+@@ -235,8 +235,6 @@ static int rawsock_recvmsg(struct kiocb
+       if (!skb)
+               return rc;
+-      msg->msg_namelen = 0;
+-
+       copied = skb->len;
+       if (len < copied) {
+               msg->msg_flags |= MSG_TRUNC;
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -2691,7 +2691,6 @@ static int packet_recvmsg(struct kiocb *
+       struct sock *sk = sock->sk;
+       struct sk_buff *skb;
+       int copied, err;
+-      struct sockaddr_ll *sll;
+       int vnet_hdr_len = 0;
+       err = -EINVAL;
+@@ -2774,22 +2773,10 @@ static int packet_recvmsg(struct kiocb *
+                       goto out_free;
+       }
+-      /*
+-       *      If the address length field is there to be filled in, we fill
+-       *      it in now.
++      /* You lose any data beyond the buffer you gave. If it worries
++       * a user program they can ask the device for its MTU
++       * anyway.
+        */
+-
+-      sll = &PACKET_SKB_CB(skb)->sa.ll;
+-      if (sock->type == SOCK_PACKET)
+-              msg->msg_namelen = sizeof(struct sockaddr_pkt);
+-      else
+-              msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
+-
+-      /*
+-       *      You lose any data beyond the buffer you gave. If it worries a
+-       *      user program they can ask the device for its MTU anyway.
+-       */
+-
+       copied = skb->len;
+       if (copied > len) {
+               copied = len;
+@@ -2802,9 +2789,20 @@ static int packet_recvmsg(struct kiocb *
+       sock_recv_ts_and_drops(msg, sk, skb);
+-      if (msg->msg_name)
++      if (msg->msg_name) {
++              /* If the address length field is there to be filled
++               * in, we fill it in now.
++               */
++              if (sock->type == SOCK_PACKET) {
++                      msg->msg_namelen = sizeof(struct sockaddr_pkt);
++              } else {
++                      struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
++                      msg->msg_namelen = sll->sll_halen +
++                              offsetof(struct sockaddr_ll, sll_addr);
++              }
+               memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
+                      msg->msg_namelen);
++      }
+       if (pkt_sk(sk)->auxdata) {
+               struct tpacket_auxdata aux;
+--- a/net/rds/recv.c
++++ b/net/rds/recv.c
+@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, stru
+       rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
+-      msg->msg_namelen = 0;
+-
+       if (msg_flags & MSG_OOB)
+               goto out;
+--- a/net/rose/af_rose.c
++++ b/net/rose/af_rose.c
+@@ -1220,7 +1220,6 @@ static int rose_recvmsg(struct kiocb *io
+ {
+       struct sock *sk = sock->sk;
+       struct rose_sock *rose = rose_sk(sk);
+-      struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
+       size_t copied;
+       unsigned char *asmptr;
+       struct sk_buff *skb;
+@@ -1256,8 +1255,11 @@ 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);
++      if (msg->msg_name) {
++              struct sockaddr_rose *srose;
++
++              memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
++              srose = msg->msg_name;
+               srose->srose_family = AF_ROSE;
+               srose->srose_addr   = rose->dest_addr;
+               srose->srose_call   = rose->dest_call;
+--- a/net/rxrpc/ar-recvmsg.c
++++ b/net/rxrpc/ar-recvmsg.c
+@@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, st
+               /* copy the peer address and timestamp */
+               if (!continue_call) {
+-                      if (msg->msg_name && msg->msg_namelen > 0)
++                      if (msg->msg_name) {
++                              size_t len =
++                                      sizeof(call->conn->trans->peer->srx);
+                               memcpy(msg->msg_name,
+-                                     &call->conn->trans->peer->srx,
+-                                     sizeof(call->conn->trans->peer->srx));
++                                     &call->conn->trans->peer->srx, len);
++                              msg->msg_namelen = len;
++                      }
+                       sock_recv_ts_and_drops(msg, &rx->sk, skb);
+               }
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -1775,8 +1775,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void
+       msg.msg_iov = &iov;
+       iov.iov_len = size;
+       iov.iov_base = ubuf;
+-      msg.msg_name = (struct sockaddr *)&address;
+-      msg.msg_namelen = sizeof(address);
++      /* Save some cycles and don't copy the address if not needed */
++      msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
++      /* We assume all kernel code knows the size of sockaddr_storage */
++      msg.msg_namelen = 0;
+       if (sock->file->f_flags & O_NONBLOCK)
+               flags |= MSG_DONTWAIT;
+       err = sock_recvmsg(sock, &msg, size, flags);
+@@ -2161,16 +2163,14 @@ static int ___sys_recvmsg(struct socket
+                       goto out;
+       }
+-      /*
+-       *      Save the user-mode address (verify_iovec will change the
+-       *      kernel msghdr to use the kernel address space)
++      /* Save the user-mode address (verify_iovec will change the
++       * kernel msghdr to use the kernel address space)
+        */
+-
+       uaddr = (__force void __user *)msg_sys->msg_name;
+       uaddr_len = COMPAT_NAMELEN(msg);
+-      if (MSG_CMSG_COMPAT & flags) {
++      if (MSG_CMSG_COMPAT & flags)
+               err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
+-      } else
++      else
+               err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
+       if (err < 0)
+               goto out_freeiov;
+@@ -2179,6 +2179,9 @@ static int ___sys_recvmsg(struct socket
+       cmsg_ptr = (unsigned long)msg_sys->msg_control;
+       msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
++      /* We assume all kernel code knows the size of sockaddr_storage */
++      msg_sys->msg_namelen = 0;
++
+       if (sock->file->f_flags & O_NONBLOCK)
+               flags |= MSG_DONTWAIT;
+       err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -949,9 +949,6 @@ 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:
+@@ -1078,9 +1075,6 @@ 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);
+ restart:
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1755,7 +1755,6 @@ static void unix_copy_addr(struct msghdr
+ {
+       struct unix_sock *u = unix_sk(sk);
+-      msg->msg_namelen = 0;
+       if (u->addr) {
+               msg->msg_namelen = u->addr->len;
+               memcpy(msg->msg_name, u->addr->name, u->addr->len);
+@@ -1779,8 +1778,6 @@ static int unix_dgram_recvmsg(struct kio
+       if (flags&MSG_OOB)
+               goto out;
+-      msg->msg_namelen = 0;
+-
+       err = mutex_lock_interruptible(&u->readlock);
+       if (err) {
+               err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
+@@ -1922,8 +1919,6 @@ static int unix_stream_recvmsg(struct ki
+       target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
+       timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
+-      msg->msg_namelen = 0;
+-
+       /* Lock the socket to prevent queue disordering
+        * while sleeps in memcpy_tomsg
+        */
+--- a/net/x25/af_x25.c
++++ b/net/x25/af_x25.c
+@@ -1343,10 +1343,9 @@ static int x25_recvmsg(struct kiocb *ioc
+       if (sx25) {
+               sx25->sx25_family = AF_X25;
+               sx25->sx25_addr   = x25->dest_addr;
++              msg->msg_namelen = sizeof(*sx25);
+       }
+-      msg->msg_namelen = sizeof(struct sockaddr_x25);
+-
+       x25_check_rbuf(sk);
+       rc = copied;
+ out_free_dgram:
diff --git a/queue-3.4/net-update-consumers-of-msg_more-to-recognize-msg_sendpage_notlast.patch b/queue-3.4/net-update-consumers-of-msg_more-to-recognize-msg_sendpage_notlast.patch
new file mode 100644 (file)
index 0000000..b46fc85
--- /dev/null
@@ -0,0 +1,70 @@
+From 91cd85f44fa67f075bf729dd4a8e7e3260760c9f Mon Sep 17 00:00:00 2001
+From: Shawn Landden <shawn@churchofgit.com>
+Date: Sun, 24 Nov 2013 22:36:28 -0800
+Subject: net: update consumers of MSG_MORE to recognize MSG_SENDPAGE_NOTLAST
+
+From: Shawn Landden <shawn@churchofgit.com>
+
+[ Upstream commit d3f7d56a7a4671d395e8af87071068a195257bf6 ]
+
+Commit 35f9c09fe (tcp: tcp_sendpages() should call tcp_push() once)
+added an internal flag MSG_SENDPAGE_NOTLAST, similar to
+MSG_MORE.
+
+algif_hash, algif_skcipher, and udp used MSG_MORE from tcp_sendpages()
+and need to see the new flag as identical to MSG_MORE.
+
+This fixes sendfile() on AF_ALG.
+
+v3: also fix udp
+
+Reported-and-tested-by: Shawn Landden <shawnlandden@gmail.com>
+Cc: Tom Herbert <therbert@google.com>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: David S. Miller <davem@davemloft.net>
+Original-patch: Richard Weinberger <richard@nod.at>
+Signed-off-by: Shawn Landden <shawn@churchofgit.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/algif_hash.c     |    3 +++
+ crypto/algif_skcipher.c |    3 +++
+ net/ipv4/udp.c          |    3 +++
+ 3 files changed, 9 insertions(+)
+
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -114,6 +114,9 @@ static ssize_t hash_sendpage(struct sock
+       struct hash_ctx *ctx = ask->private;
+       int err;
++      if (flags & MSG_SENDPAGE_NOTLAST)
++              flags |= MSG_MORE;
++
+       lock_sock(sk);
+       sg_init_table(ctx->sgl.sg, 1);
+       sg_set_page(ctx->sgl.sg, page, size, offset);
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -378,6 +378,9 @@ static ssize_t skcipher_sendpage(struct
+       struct skcipher_sg_list *sgl;
+       int err = -EINVAL;
++      if (flags & MSG_SENDPAGE_NOTLAST)
++              flags |= MSG_MORE;
++
+       lock_sock(sk);
+       if (!ctx->more && ctx->used)
+               goto unlock;
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1039,6 +1039,9 @@ int udp_sendpage(struct sock *sk, struct
+       struct udp_sock *up = udp_sk(sk);
+       int ret;
++      if (flags & MSG_SENDPAGE_NOTLAST)
++              flags |= MSG_MORE;
++
+       if (!up->pending) {
+               struct msghdr msg = {   .msg_flags = flags|MSG_MORE };
diff --git a/queue-3.4/packet-fix-use-after-free-race-in-send-path-when-dev-is-released.patch b/queue-3.4/packet-fix-use-after-free-race-in-send-path-when-dev-is-released.patch
new file mode 100644 (file)
index 0000000..ed1344f
--- /dev/null
@@ -0,0 +1,220 @@
+From 747110f5834376c6e616a40167da6b7f2efbb976 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Thu, 21 Nov 2013 16:50:58 +0100
+Subject: packet: fix use after free race in send path when dev is released
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit e40526cb20b5ee53419452e1f03d97092f144418 ]
+
+Salam reported a use after free bug in PF_PACKET that occurs when
+we're sending out frames on a socket bound device and suddenly the
+net device is being unregistered. It appears that commit 827d9780
+introduced a possible race condition between {t,}packet_snd() and
+packet_notifier(). In the case of a bound socket, packet_notifier()
+can drop the last reference to the net_device and {t,}packet_snd()
+might end up suddenly sending a packet over a freed net_device.
+
+To avoid reverting 827d9780 and thus introducing a performance
+regression compared to the current state of things, we decided to
+hold a cached RCU protected pointer to the net device and maintain
+it on write side via bind spin_lock protected register_prot_hook()
+and __unregister_prot_hook() calls.
+
+In {t,}packet_snd() path, we access this pointer under rcu_read_lock
+through packet_cached_dev_get() that holds reference to the device
+to prevent it from being freed through packet_notifier() while
+we're in send path. This is okay to do as dev_put()/dev_hold() are
+per-cpu counters, so this should not be a performance issue. Also,
+the code simplifies a bit as we don't need need_rls_dev anymore.
+
+Fixes: 827d978037d7 ("af-packet: Use existing netdev reference for bound sockets.")
+Reported-by: Salam Noureddine <noureddine@aristanetworks.com>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: Salam Noureddine <noureddine@aristanetworks.com>
+Cc: Ben Greear <greearb@candelatech.com>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/packet/af_packet.c |   60 ++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 37 insertions(+), 23 deletions(-)
+
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -294,6 +294,7 @@ struct packet_sock {
+       unsigned int            tp_reserve;
+       unsigned int            tp_loss:1;
+       unsigned int            tp_tstamp;
++      struct net_device __rcu *cached_dev;
+       struct packet_type      prot_hook ____cacheline_aligned_in_smp;
+ };
+@@ -349,11 +350,15 @@ static void __fanout_link(struct sock *s
+ static void register_prot_hook(struct sock *sk)
+ {
+       struct packet_sock *po = pkt_sk(sk);
++
+       if (!po->running) {
+-              if (po->fanout)
++              if (po->fanout) {
+                       __fanout_link(sk, po);
+-              else
++              } else {
+                       dev_add_pack(&po->prot_hook);
++                      rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
++              }
++
+               sock_hold(sk);
+               po->running = 1;
+       }
+@@ -371,10 +376,13 @@ static void __unregister_prot_hook(struc
+       struct packet_sock *po = pkt_sk(sk);
+       po->running = 0;
+-      if (po->fanout)
++      if (po->fanout) {
+               __fanout_unlink(sk, po);
+-      else
++      } else {
+               __dev_remove_pack(&po->prot_hook);
++              RCU_INIT_POINTER(po->cached_dev, NULL);
++      }
++
+       __sock_put(sk);
+       if (sync) {
+@@ -2044,12 +2052,24 @@ static int tpacket_fill_skb(struct packe
+       return tp_len;
+ }
++static struct net_device *packet_cached_dev_get(struct packet_sock *po)
++{
++      struct net_device *dev;
++
++      rcu_read_lock();
++      dev = rcu_dereference(po->cached_dev);
++      if (dev)
++              dev_hold(dev);
++      rcu_read_unlock();
++
++      return dev;
++}
++
+ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ {
+       struct sk_buff *skb;
+       struct net_device *dev;
+       __be16 proto;
+-      bool need_rls_dev = false;
+       int err, reserve = 0;
+       void *ph;
+       struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
+@@ -2063,7 +2083,7 @@ static int tpacket_snd(struct packet_soc
+       err = -EBUSY;
+       if (saddr == NULL) {
+-              dev = po->prot_hook.dev;
++              dev     = packet_cached_dev_get(po);
+               proto   = po->num;
+               addr    = NULL;
+       } else {
+@@ -2077,19 +2097,17 @@ static int tpacket_snd(struct packet_soc
+               proto   = saddr->sll_protocol;
+               addr    = saddr->sll_addr;
+               dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
+-              need_rls_dev = true;
+       }
+       err = -ENXIO;
+       if (unlikely(dev == NULL))
+               goto out;
+-
+-      reserve = dev->hard_header_len;
+-
+       err = -ENETDOWN;
+       if (unlikely(!(dev->flags & IFF_UP)))
+               goto out_put;
++      reserve = dev->hard_header_len;
++
+       size_max = po->tx_ring.frame_size
+               - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
+@@ -2166,8 +2184,7 @@ out_status:
+       __packet_set_status(po, ph, status);
+       kfree_skb(skb);
+ out_put:
+-      if (need_rls_dev)
+-              dev_put(dev);
++      dev_put(dev);
+ out:
+       mutex_unlock(&po->pg_vec_lock);
+       return err;
+@@ -2205,7 +2222,6 @@ static int packet_snd(struct socket *soc
+       struct sk_buff *skb;
+       struct net_device *dev;
+       __be16 proto;
+-      bool need_rls_dev = false;
+       unsigned char *addr;
+       int err, reserve = 0;
+       struct virtio_net_hdr vnet_hdr = { 0 };
+@@ -2221,7 +2237,7 @@ static int packet_snd(struct socket *soc
+        */
+       if (saddr == NULL) {
+-              dev = po->prot_hook.dev;
++              dev     = packet_cached_dev_get(po);
+               proto   = po->num;
+               addr    = NULL;
+       } else {
+@@ -2233,19 +2249,17 @@ static int packet_snd(struct socket *soc
+               proto   = saddr->sll_protocol;
+               addr    = saddr->sll_addr;
+               dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
+-              need_rls_dev = true;
+       }
+       err = -ENXIO;
+-      if (dev == NULL)
++      if (unlikely(dev == NULL))
+               goto out_unlock;
+-      if (sock->type == SOCK_RAW)
+-              reserve = dev->hard_header_len;
+-
+       err = -ENETDOWN;
+-      if (!(dev->flags & IFF_UP))
++      if (unlikely(!(dev->flags & IFF_UP)))
+               goto out_unlock;
++      if (sock->type == SOCK_RAW)
++              reserve = dev->hard_header_len;
+       if (po->has_vnet_hdr) {
+               vnet_hdr_len = sizeof(vnet_hdr);
+@@ -2378,15 +2392,14 @@ static int packet_snd(struct socket *soc
+       if (err > 0 && (err = net_xmit_errno(err)) != 0)
+               goto out_unlock;
+-      if (need_rls_dev)
+-              dev_put(dev);
++      dev_put(dev);
+       return len;
+ out_free:
+       kfree_skb(skb);
+ out_unlock:
+-      if (dev && need_rls_dev)
++      if (dev)
+               dev_put(dev);
+ out:
+       return err;
+@@ -2603,6 +2616,7 @@ static int packet_create(struct net *net
+       po = pkt_sk(sk);
+       sk->sk_family = PF_PACKET;
+       po->num = proto;
++      RCU_INIT_POINTER(po->cached_dev, NULL);
+       sk->sk_destruct = packet_sock_destruct;
+       sk_refcnt_debug_inc(sk);
diff --git a/queue-3.4/pktgen-xfrm-update-ipv4-header-total-len-and-checksum-after-tranformation.patch b/queue-3.4/pktgen-xfrm-update-ipv4-header-total-len-and-checksum-after-tranformation.patch
new file mode 100644 (file)
index 0000000..8a5e060
--- /dev/null
@@ -0,0 +1,57 @@
+From 81925fd57f0ec863230e1b3247f6f193ce2953ac Mon Sep 17 00:00:00 2001
+From: "fan.du" <fan.du@windriver.com>
+Date: Sun, 1 Dec 2013 16:28:48 +0800
+Subject: {pktgen, xfrm} Update IPv4 header total len and checksum after tranformation
+
+From: "fan.du" <fan.du@windriver.com>
+
+[ Upstream commit 3868204d6b89ea373a273e760609cb08020beb1a ]
+
+commit a553e4a6317b2cfc7659542c10fe43184ffe53da ("[PKTGEN]: IPSEC support")
+tried to support IPsec ESP transport transformation for pktgen, but acctually
+this doesn't work at all for two reasons(The orignal transformed packet has
+bad IPv4 checksum value, as well as wrong auth value, reported by wireshark)
+
+- After transpormation, IPv4 header total length needs update,
+  because encrypted payload's length is NOT same as that of plain text.
+
+- After transformation, IPv4 checksum needs re-caculate because of payload
+  has been changed.
+
+With this patch, armmed pktgen with below cofiguration, Wireshark is able to
+decrypted ESP packet generated by pktgen without any IPv4 checksum error or
+auth value error.
+
+pgset "flag IPSEC"
+pgset "flows 1"
+
+Signed-off-by: Fan Du <fan.du@windriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/pktgen.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -2521,6 +2521,8 @@ static int process_ipsec(struct pktgen_d
+               if (x) {
+                       int ret;
+                       __u8 *eth;
++                      struct iphdr *iph;
++
+                       nhead = x->props.header_len - skb_headroom(skb);
+                       if (nhead > 0) {
+                               ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
+@@ -2542,6 +2544,11 @@ static int process_ipsec(struct pktgen_d
+                       eth = (__u8 *) skb_push(skb, ETH_HLEN);
+                       memcpy(eth, pkt_dev->hh, 12);
+                       *(u16 *) &eth[12] = protocol;
++
++                      /* Update IPv4 header len as well as checksum value */
++                      iph = ip_hdr(skb);
++                      iph->tot_len = htons(skb->len - ETH_HLEN);
++                      ip_send_check(iph);
+               }
+       }
+       return 1;
diff --git a/queue-3.4/random32-fix-off-by-one-in-seeding-requirement.patch b/queue-3.4/random32-fix-off-by-one-in-seeding-requirement.patch
new file mode 100644 (file)
index 0000000..87ab0e4
--- /dev/null
@@ -0,0 +1,96 @@
+From 02638b50e8249d902d2ac84477e80e501c7c31cc Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <dborkman@redhat.com>
+Date: Mon, 11 Nov 2013 12:20:32 +0100
+Subject: random32: fix off-by-one in seeding requirement
+
+From: Daniel Borkmann <dborkman@redhat.com>
+
+[ Upstream commit 51c37a70aaa3f95773af560e6db3073520513912 ]
+
+For properly initialising the Tausworthe generator [1], we have
+a strict seeding requirement, that is, s1 > 1, s2 > 7, s3 > 15.
+
+Commit 697f8d0348 ("random32: seeding improvement") introduced
+a __seed() function that imposes boundary checks proposed by the
+errata paper [2] to properly ensure above conditions.
+
+However, we're off by one, as the function is implemented as:
+"return (x < m) ? x + m : x;", and called with __seed(X, 1),
+__seed(X, 7), __seed(X, 15). Thus, an unwanted seed of 1, 7, 15
+would be possible, whereas the lower boundary should actually
+be of at least 2, 8, 16, just as GSL does. Fix this, as otherwise
+an initialization with an unwanted seed could have the effect
+that Tausworthe's PRNG properties cannot not be ensured.
+
+Note that this PRNG is *not* used for cryptography in the kernel.
+
+ [1] http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps
+ [2] http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps
+
+Joint work with Hannes Frederic Sowa.
+
+Fixes: 697f8d0348a6 ("random32: seeding improvement")
+Cc: Stephen Hemminger <stephen@networkplumber.org>
+Cc: Florian Weimer <fweimer@redhat.com>
+Cc: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
+Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/random.h |    6 +++---
+ lib/random32.c         |   14 +++++++-------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -87,9 +87,9 @@ static inline void prandom32_seed(struct
+ {
+       u32 i = (seed >> 32) ^ (seed << 10) ^ seed;
+-      state->s1 = __seed(i, 1);
+-      state->s2 = __seed(i, 7);
+-      state->s3 = __seed(i, 15);
++      state->s1 = __seed(i, 2);
++      state->s2 = __seed(i, 8);
++      state->s3 = __seed(i, 16);
+ }
+ #ifdef CONFIG_ARCH_RANDOM
+--- a/lib/random32.c
++++ b/lib/random32.c
+@@ -92,7 +92,7 @@ void srandom32(u32 entropy)
+        */
+       for_each_possible_cpu (i) {
+               struct rnd_state *state = &per_cpu(net_rand_state, i);
+-              state->s1 = __seed(state->s1 ^ entropy, 1);
++              state->s1 = __seed(state->s1 ^ entropy, 2);
+       }
+ }
+ EXPORT_SYMBOL(srandom32);
+@@ -109,9 +109,9 @@ static int __init random32_init(void)
+               struct rnd_state *state = &per_cpu(net_rand_state,i);
+ #define LCG(x)        ((x) * 69069)   /* super-duper LCG */
+-              state->s1 = __seed(LCG(i + jiffies), 1);
+-              state->s2 = __seed(LCG(state->s1), 7);
+-              state->s3 = __seed(LCG(state->s2), 15);
++              state->s1 = __seed(LCG(i + jiffies), 2);
++              state->s2 = __seed(LCG(state->s1), 8);
++              state->s3 = __seed(LCG(state->s2), 16);
+               /* "warm it up" */
+               prandom32(state);
+@@ -138,9 +138,9 @@ static int __init random32_reseed(void)
+               u32 seeds[3];
+               get_random_bytes(&seeds, sizeof(seeds));
+-              state->s1 = __seed(seeds[0], 1);
+-              state->s2 = __seed(seeds[1], 7);
+-              state->s3 = __seed(seeds[2], 15);
++              state->s1 = __seed(seeds[0], 2);
++              state->s2 = __seed(seeds[1], 8);
++              state->s3 = __seed(seeds[2], 16);
+               /* mix it in */
+               prandom32(state);
diff --git a/queue-3.4/series b/queue-3.4/series
new file mode 100644 (file)
index 0000000..b0365b6
--- /dev/null
@@ -0,0 +1,24 @@
+net-fix-ip-rule-delete-table-256.patch
+ipv6-use-rt6_get_dflt_router-to-get-default-router-in-rt6_route_rcv.patch
+random32-fix-off-by-one-in-seeding-requirement.patch
+bonding-don-t-permit-to-use-arp-monitoring-in-802.3ad.patch
+6lowpan-uncompression-of-traffic-class-field-was-incorrect.patch
+bonding-fix-two-race-conditions-in-bond_store_updelay-downdelay.patch
+isdnloop-use-strlcpy-instead-of-strcpy.patch
+connector-improved-unaligned-access-error-fix.patch
+ipv4-fix-possible-seqlock-deadlock.patch
+inet-prevent-leakage-of-uninitialized-memory-to-user-in-recv-syscalls.patch
+net-rework-recvmsg-handler-msg_name-and-msg_namelen-logic.patch
+net-add-bug_on-if-kernel-advertises-msg_namelen-sizeof-struct-sockaddr_storage.patch
+inet-fix-addr_len-msg-msg_namelen-assignment-in-recv_error-and-rxpmtu-functions.patch
+net-clamp-msg_namelen-instead-of-returning-an-error.patch
+ipv6-fix-leaking-uninitialized-port-number-of-offender-sockaddr.patch
+atm-idt77252-fix-dev-refcnt-leak.patch
+net-core-always-propagate-flag-changes-to-interfaces.patch
+bridge-flush-br-s-address-entry-in-fdb-when-remove-the-bridge-dev.patch
+packet-fix-use-after-free-race-in-send-path-when-dev-is-released.patch
+af_packet-block-bh-in-prb_shutdown_retire_blk_timer.patch
+net-update-consumers-of-msg_more-to-recognize-msg_sendpage_notlast.patch
+inet-fix-possible-seqlock-deadlocks.patch
+ipv6-fix-possible-seqlock-deadlock-in-ip6_finish_output2.patch
+pktgen-xfrm-update-ipv4-header-total-len-and-checksum-after-tranformation.patch