Skip to contentSkip to conversation

3.0.76-stable review

PATCH In review Greg Kroah-Hartman 2 participants 32 messages Apr 29, 2013 – Apr 30, 2013

Subsystems (19)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 3.0.76-stable review

This is the start of the stable review cycle for the 3.0.76 release. There are 30 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed May 1 18:42:50 UTC 2013. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.0.76-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 3.0.76-rc1

Sam Ravnborg <[email protected]>
sparc32: support atomic64_t

Eric Dumazet <[email protected]>
net: drop dst before queueing fragments

Wei Yongjun <[email protected]>
netrom: fix invalid use of sizeof in nr_recvmsg()

Mathias Krause <[email protected]>
tipc: fix info leaks via msg_name in recv_msg/recv_stream

Mathias Krause <[email protected]>
rose: fix info leak via msg_name in rose_recvmsg()

Mathias Krause <[email protected]>
netrom: fix info leak via msg_name in nr_recvmsg()

Mathias Krause <[email protected]>
llc: Fix missing msg_namelen update in llc_ui_recvmsg()

Mathias Krause <[email protected]>
iucv: Fix missing msg_namelen update in iucv_sock_recvmsg()

Mathias Krause <[email protected]>
irda: Fix missing msg_namelen update in irda_recvmsg_dgram()

Mathias Krause <[email protected]>
caif: Fix missing msg_namelen update in caif_seqpkt_recvmsg()

Mathias Krause <[email protected]>
Bluetooth: RFCOMM - Fix missing msg_namelen update in rfcomm_sock_recvmsg()

Mathias Krause <[email protected]>
Bluetooth: fix possible info leak in bt_sock_recvmsg()

Mathias Krause <[email protected]>
ax25: fix info leak via msg_name in ax25_recvmsg()

Mathias Krause <[email protected]>
atm: update msg_namelen in vcc_recvmsg()

Linus Torvalds <[email protected]>
net: fix incorrect credentials passing

Eric Dumazet <[email protected]>
tcp: call tcp_replace_ts_recent() from tcp_ack()

Daniel Borkmann <[email protected]>
net: sctp: sctp_auth_key_put: use kzfree instead of kfree

Wei Yongjun <[email protected]>
esp4: fix error return code in esp_output()

Dmitry Popov <[email protected]>
tcp: incoming connections might use wrong route under synflood

Michael Riesch <[email protected]>
rtnetlink: Call nlmsg_parse() with correct header length

Patrick McHardy <[email protected]>
netfilter: don't reset nf_trace in nf_reset()

Eric W. Biederman <[email protected]>
af_unix: If we don't care about credentials coallesce all messages

[email protected] <[email protected]>
bonding: IFF_BONDING is not stripped on enslave failure

Hannes Frederic Sowa <[email protected]>
atl1e: limit gso segment size to prevent generation of wrong ip length fields

Vlad Yasevich <[email protected]>
net: count hw_addr syncs so that unsync works properly.

Balakumaran Kannan <[email protected]>
net IPv6 : Fix broken IPv6 routing table after loopback down-up

Vasily Averin <[email protected]>
cbq: incorrect processing of high limits

David S. Miller <[email protected]>
sparc64: Fix race in TLB batch processing.

Jiri Slaby <[email protected]>
TTY: fix atime/mtime regression

Jiri Slaby <[email protected]>
TTY: do not update atime/mtime on read/write

-------------

Diffstat:

 Makefile                             |   4 +-
 arch/sparc/Kconfig                   |   1 +
 arch/sparc/include/asm/atomic_32.h   |   2 +
 arch/sparc/include/asm/pgtable_64.h  |   1 +
 arch/sparc/include/asm/system_64.h   |   3 +-
 arch/sparc/include/asm/tlbflush_64.h |  37 +++++++++--
 arch/sparc/kernel/smp_64.c           |  41 ++++++++++--
 arch/sparc/mm/tlb.c                  |  39 ++++++++++--
 arch/sparc/mm/tsb.c                  |  57 ++++++++++++-----
 arch/sparc/mm/ultra.S                | 119 ++++++++++++++++++++++++++++-------
 drivers/net/atl1e/atl1e.h            |   2 +-
 drivers/net/atl1e/atl1e_main.c       |   1 +
 drivers/net/bonding/bond_main.c      |   1 +
 drivers/tty/tty_io.c                 |  14 ++++-
 include/linux/netdevice.h            |   2 +-
 include/linux/skbuff.h               |   8 +++
 include/linux/socket.h               |   3 +-
 include/net/scm.h                    |   2 +-
 net/atm/common.c                     |   2 +
 net/ax25/af_ax25.c                   |   1 +
 net/bluetooth/af_bluetooth.c         |   4 +-
 net/bluetooth/rfcomm/sock.c          |   1 +
 net/caif/caif_socket.c               |   2 +
 net/core/dev.c                       |   1 +
 net/core/dev_addr_lists.c            |   6 +-
 net/core/rtnetlink.c                 |   4 +-
 net/core/sock.c                      |  14 +++--
 net/ipv4/esp4.c                      |   6 +-
 net/ipv4/ip_fragment.c               |  15 +++--
 net/ipv4/syncookies.c                |   4 +-
 net/ipv4/tcp_input.c                 |  65 ++++++++++---------
 net/ipv6/addrconf.c                  |  27 ++++++++
 net/ipv6/reassembly.c                |  13 +++-
 net/irda/af_irda.c                   |   2 +
 net/iucv/af_iucv.c                   |   2 +
 net/llc/af_llc.c                     |   2 +
 net/netrom/af_netrom.c               |   1 +
 net/rose/af_rose.c                   |   1 +
 net/sched/sch_cbq.c                  |   5 +-
 net/sctp/auth.c                      |   2 +-
 net/tipc/socket.c                    |   7 +++
 net/unix/af_unix.c                   |   2 +-
 42 files changed, 405 insertions(+), 121 deletions(-)
author maintainer
#1 lore raw

PATCH 1/30 TTY: do not update atime/mtime on read/write

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiri Slaby <[email protected]>

commit b0de59b5733d18b0d1974a060860a8b5c1b36a2e upstream.

On http://vladz.devzero.fr/013_ptmx-timing.php, we can see how to find out length of a password using timestamps of /dev/ptmx. It is documented in "Timing Analysis of Keystrokes and Timing Attacks on SSH". To avoid that problem, do not update time when reading from/writing to a TTY.

I am afraid of regressions as this is a behavior we have since 0.97 and apps may expect the time to be current, e.g. for monitoring whether there was a change on the TTY. Now, there is no change. So this would better have a lot of testing before it goes upstream.

References: CVE-2013-0160

---
 drivers/tty/tty_io.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/tty/tty_io.c +2 -6
@@ -975,8 +975,7 @@ static ssize_t tty_read(struct file *fil
 	else
 		i = -EIO;
 	tty_ldisc_deref(ld);
-	if (i > 0)
-		inode->i_atime = current_fs_time(inode->i_sb);
+
 	return i;
 }
 
@@ -1077,11 +1076,8 @@ static inline ssize_t do_tty_write(
 			break;
 		cond_resched();
 	}
-	if (written) {
-		struct inode *inode = file->f_path.dentry->d_inode;
-		inode->i_mtime = current_fs_time(inode->i_sb);
+	if (written)
 		ret = written;
-	}
 out:
 	tty_write_unlock(tty);
 	return ret;
author maintainer
#2 lore raw

PATCH 2/30 TTY: fix atime/mtime regression

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jiri Slaby <[email protected]>

commit 37b7f3c76595e23257f61bd80b223de8658617ee upstream.

In commit b0de59b5733d ("TTY: do not update atime/mtime on read/write") we removed timestamps from tty inodes to fix a security issue and waited if something breaks. Well, 'w', the utility to find out logged users and their inactivity time broke. It shows that users are inactive since the time they logged in.

To revert to the old behaviour while still preventing attackers to guess the password length, we update the timestamps in one-minute intervals by this patch.

---
 drivers/tty/tty_io.c |   16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/tty/tty_io.c +15 -1
@@ -939,6 +939,14 @@ void start_tty(struct tty_struct *tty)
 
 EXPORT_SYMBOL(start_tty);
 
+static void tty_update_time(struct timespec *time)
+{
+	unsigned long sec = get_seconds();
+	sec -= sec % 60;
+	if ((long)(sec - time->tv_sec) > 0)
+		time->tv_sec = sec;
+}
+
 /**
  *	tty_read	-	read method for tty device files
  *	@file: pointer to tty file
@@ -976,6 +984,9 @@ static ssize_t tty_read(struct file *fil
 		i = -EIO;
 	tty_ldisc_deref(ld);
 
+	if (i > 0)
+		tty_update_time(&inode->i_atime);
+
 	return i;
 }
 
@@ -1076,8 +1087,11 @@ static inline ssize_t do_tty_write(
 			break;
 		cond_resched();
 	}
-	if (written)
+	if (written) {
+		struct inode *inode = file->f_path.dentry->d_inode;
+		tty_update_time(&inode->i_mtime);
 		ret = written;
+	}
 out:
 	tty_write_unlock(tty);
 	return ret;
author maintainer
#3 lore raw

PATCH 3/30 sparc64: Fix race in TLB batch processing.

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: "David S. Miller" <[email protected]>

[ Commits f36391d2790d04993f48da6a45810033a2cdf847 and
f0af97070acbad5d6a361f485828223a4faaa0ee upstream. ]

As reported by Dave Kleikamp, when we emit cross calls to do batched TLB flush processing we have a race because we do not synchronize on the sibling cpus completing the cross call.

So meanwhile the TLB batch can be reset (tb->tlb_nr set to zero, etc.) and either flushes are missed or flushes will flush the wrong addresses.

Fix this by using generic infrastructure to synchonize on the completion of the cross call.

This first required getting the flush_tlb_pending() call out from switch_to() which operates with locks held and interrupts disabled. The problem is that smp_call_function_many() cannot be invoked with IRQs disabled and this is explicitly checked for with WARN_ON_ONCE().

We get the batch processing outside of locked IRQ disabled sections by using some ideas from the powerpc port. Namely, we only batch inside of arch_{enter,leave}_lazy_mmu_mode() calls. If we're not in such a region, we flush TLBs synchronously.

1) Get rid of xcall_flush_tlb_pending and per-cpu type implementations.

2) Do TLB batch cross calls instead via:

	smp_call_function_many()
		tlb_pending_func()
			__flush_tlb_pending()

3) Batch only in lazy mmu sequences:

a) Add 'active' member to struct tlb_batch
b) Define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
c) Set 'active' in arch_enter_lazy_mmu_mode()
d) Run batch and clear 'active' in arch_leave_lazy_mmu_mode()
e) Check 'active' in tlb_batch_add_one() and do a synchronous flush if it's clear.

4) Add infrastructure for synchronous TLB page flushes.

a) Implement __flush_tlb_page and per-cpu variants, patch as needed.
b) Likewise for xcall_flush_tlb_page.
c) Implement smp_flush_tlb_page() to invoke the cross-call.
d) Wire up global_flush_tlb_page() to the right routine based upon CONFIG_SMP

5) It turns out that singleton batches are very common, 2 out of every 3 batch flushes have only a single entry in them.

The batch flush waiting is very expensive, both because of the poll on sibling cpu completeion, as well as because passing the tlb batch pointer to the sibling cpus invokes a shared memory dereference.

Therefore, in flush_tlb_pending(), if there is only one entry in the batch perform a completely asynchronous global_flush_tlb_page() instead.

---
 arch/sparc/include/asm/pgtable_64.h  |    1 
 arch/sparc/include/asm/system_64.h   |    3 
 arch/sparc/include/asm/tlbflush_64.h |   37 +++++++++-
 arch/sparc/kernel/smp_64.c           |   41 ++++++++++--
 arch/sparc/mm/tlb.c                  |   39 ++++++++++-
 arch/sparc/mm/tsb.c                  |   57 ++++++++++++----
 arch/sparc/mm/ultra.S                |  119 +++++++++++++++++++++++++++--------
 7 files changed, 242 insertions(+), 55 deletions(-)
arch/sparc/include/asm/pgtable_64.h +1 -0
@@ -774,6 +774,7 @@ static inline int io_remap_pfn_range(str
 	return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
 }
 
+#include <asm/tlbflush.h>
 #include <asm-generic/pgtable.h>
 
 /* We provide our own get_unmapped_area to cope with VA holes and
arch/sparc/include/asm/system_64.h +1 -2
@@ -140,8 +140,7 @@ do {						\
 	 * and 2 stores in this critical code path.  -DaveM
 	 */
 #define switch_to(prev, next, last)					\
-do {	flush_tlb_pending();						\
-	save_and_clear_fpu();						\
+do {	save_and_clear_fpu();						\
 	/* If you are tempted to conditionalize the following */	\
 	/* so that ASI is only written if it changes, think again. */	\
 	__asm__ __volatile__("wr %%g0, %0, %%asi"			\
arch/sparc/include/asm/tlbflush_64.h +31 -6
@@ -11,24 +11,40 @@
 struct tlb_batch {
 	struct mm_struct *mm;
 	unsigned long tlb_nr;
+	unsigned long active;
 	unsigned long vaddrs[TLB_BATCH_NR];
 };
 
 extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
 extern void flush_tsb_user(struct tlb_batch *tb);
+extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
 
 /* TLB flush operations. */
 
-extern void flush_tlb_pending(void);
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma,
+				  unsigned long vmaddr)
+{
+}
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+				   unsigned long start, unsigned long end)
+{
+}
+
+#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
 
-#define flush_tlb_range(vma,start,end)	\
-	do { (void)(start); flush_tlb_pending(); } while (0)
-#define flush_tlb_page(vma,addr)	flush_tlb_pending()
-#define flush_tlb_mm(mm)		flush_tlb_pending()
+extern void flush_tlb_pending(void);
+extern void arch_enter_lazy_mmu_mode(void);
+extern void arch_leave_lazy_mmu_mode(void);
+#define arch_flush_lazy_mmu_mode()      do {} while (0)
 
 /* Local cpu only.  */
 extern void __flush_tlb_all(void);
-
+extern void __flush_tlb_page(unsigned long context, unsigned long vaddr);
 extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);
 
 #ifndef CONFIG_SMP
@@ -38,15 +54,24 @@ do {	flush_tsb_kernel_range(start,end);
 	__flush_tlb_kernel_range(start,end); \
 } while (0)
 
+static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
+{
+	__flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
+}
+
 #else /* CONFIG_SMP */
 
 extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);
 
 #define flush_tlb_kernel_range(start, end) \
 do {	flush_tsb_kernel_range(start,end); \
 	smp_flush_tlb_kernel_range(start, end); \
 } while (0)
 
+#define global_flush_tlb_page(mm, vaddr) \
+	smp_flush_tlb_page(mm, vaddr)
+
 #endif /* ! CONFIG_SMP */
 
 #endif /* _SPARC64_TLBFLUSH_H */
arch/sparc/kernel/smp_64.c +37 -4

66 lines not on this page · raw message

arch/sparc/mm/tlb.c +35 -4
@@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch,
 void flush_tlb_pending(void)
 {
 	struct tlb_batch *tb = &get_cpu_var(tlb_batch);
+	struct mm_struct *mm = tb->mm;
 
-	if (tb->tlb_nr) {
-		flush_tsb_user(tb);
+	if (!tb->tlb_nr)
+		goto out;
 
-		if (CTX_VALID(tb->mm->context)) {
+	flush_tsb_user(tb);
+
+	if (CTX_VALID(mm->context)) {
+		if (tb->tlb_nr == 1) {
+			global_flush_tlb_page(mm, tb->vaddrs[0]);
+		} else {
 #ifdef CONFIG_SMP
 			smp_flush_tlb_pending(tb->mm, tb->tlb_nr,
 					      &tb->vaddrs[0]);
@@ -37,12 +43,30 @@ void flush_tlb_pending(void)
 					    tb->tlb_nr, &tb->vaddrs[0]);
 #endif
 		}
-		tb->tlb_nr = 0;
 	}
 
+	tb->tlb_nr = 0;
+
+out:
 	put_cpu_var(tlb_batch);
 }
 
+void arch_enter_lazy_mmu_mode(void)
+{
+	struct tlb_batch *tb = &__get_cpu_var(tlb_batch);
+
+	tb->active = 1;
+}
+
+void arch_leave_lazy_mmu_mode(void)
+{
+	struct tlb_batch *tb = &__get_cpu_var(tlb_batch);
+
+	if (tb->tlb_nr)
+		flush_tlb_pending();
+	tb->active = 0;
+}
+
 void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
 		   pte_t *ptep, pte_t orig, int fullmm)
 {
@@ -90,6 +114,12 @@ no_cache_flush:
 		nr = 0;
 	}
 
+	if (!tb->active) {
+		global_flush_tlb_page(mm, vaddr);
+		flush_tsb_user_page(mm, vaddr);
+		goto out;
+	}
+
 	if (nr == 0)
 		tb->mm = mm;
 
@@ -98,5 +128,6 @@ no_cache_flush:
 	if (nr >= TLB_BATCH_NR)
 		flush_tlb_pending();
 
+out:
 	put_cpu_var(tlb_batch);
 }
arch/sparc/mm/tsb.c +42 -15

82 lines not on this page · raw message

arch/sparc/mm/ultra.S +95 -24

190 lines not on this page · raw message

author maintainer
#4 lore raw

PATCH 4/30 cbq: incorrect processing of high limits

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vasily Averin <[email protected]>

[ Upstream commit f0f6ee1f70c4eaab9d52cf7d255df4bd89f8d1c2 ]

currently cbq works incorrectly for limits > 10% real link bandwidth, and practically does not work for limits > 50% real link bandwidth. Below are results of experiments taken on 1 Gbit link

In shaper | Actual Result
-----------+---------------

  100M     | 108 Mbps
  200M     | 244 Mbps
  300M     | 412 Mbps
  500M     | 893 Mbps

This happen because of q->now changes incorrectly in cbq_dequeue():
when it is called before real end of packet transmitting, L2T is greater than real time delay, q_now gets an extra boost but never compensate it.

To fix this problem we prevent change of q->now until its synchronization with real time.

---
 net/sched/sch_cbq.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
net/sched/sch_cbq.c +4 -1
@@ -963,8 +963,11 @@ cbq_dequeue(struct Qdisc *sch)
 		cbq_update(q);
 		if ((incr -= incr2) < 0)
 			incr = 0;
+		q->now += incr;
+	} else {
+		if (now > q->now)
+			q->now = now;
 	}
-	q->now += incr;
 	q->now_rt = now;
 
 	for (;;) {
author maintainer
#5 lore raw

PATCH 5/30 net IPv6 : Fix broken IPv6 routing table after loopback down-up

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Balakumaran Kannan <[email protected]>

[ Upstream commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f ]

IPv6 Routing table becomes broken once we do ifdown, ifup of the loopback(lo) interface. After down-up, routes of other interface's IPv6 addresses through 'lo' are lost.

IPv6 addresses assigned to all interfaces are routed through 'lo' for internal communication. Once 'lo' is down, those routing entries are removed from routing table. But those removed entries are not being re-created properly when 'lo' is brought up. So IPv6 addresses of other interfaces becomes unreachable from the same machine. Also this breaks communication with other machines because of NDISC packet processing failure.

This patch fixes this issue by reading all interface's IPv6 addresses and adding them to IPv6 routing table while bringing up 'lo'.

==Testing==
Before applying the patch:

$ route -A inet6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2000::20/128                   ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
::1/128                        ::                         Un   0   1     0 lo
2000::20/128                   ::                         Un   0   1     0 lo
fe80::xxxx:xxxx:xxxx:xxxx/128  ::                         Un   0   1     0 lo
ff00::/8                       ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
$ sudo ifdown lo
$ sudo ifup lo
$ route -A inet6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2000::20/128                   ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
::1/128                        ::                         Un   0   1     0 lo
ff00::/8                       ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
$

After applying the patch:

$ route -A inet6
Kernel IPv6 routing
table
Destination                    Next Hop                   Flag Met Ref Use If
2000::20/128                   ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
::1/128                        ::                         Un   0   1     0 lo
2000::20/128                   ::                         Un   0   1     0 lo
fe80::xxxx:xxxx:xxxx:xxxx/128  ::                         Un   0   1     0 lo
ff00::/8                       ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
$ sudo ifdown lo
$ sudo ifup lo
$ route -A inet6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
2000::20/128                   ::                         U    256 0     0 eth0
fe80::/64                      ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
::1/128                        ::                         Un   0   1     0 lo
2000::20/128                   ::                         Un   0   1     0 lo
fe80::xxxx:xxxx:xxxx:xxxx/128  ::                         Un   0   1     0 lo
ff00::/8                       ::                         U    256 0     0 eth0
::/0                           ::                         !n   -1  1     1 lo
$
---
 net/ipv6/addrconf.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
net/ipv6/addrconf.c +27 -0
@@ -2327,6 +2327,9 @@ static void sit_add_v4_addrs(struct inet
 static void init_loopback(struct net_device *dev)
 {
 	struct inet6_dev  *idev;
+	struct net_device *sp_dev;
+	struct inet6_ifaddr *sp_ifa;
+	struct rt6_info *sp_rt;
 
 	/* ::1 */
 
@@ -2338,6 +2341,30 @@ static void init_loopback(struct net_dev
 	}
 
 	add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
+
+	/* Add routes to other interface's IPv6 addresses */
+	for_each_netdev(dev_net(dev), sp_dev) {
+		if (!strcmp(sp_dev->name, dev->name))
+			continue;
+
+		idev = __in6_dev_get(sp_dev);
+		if (!idev)
+			continue;
+
+		read_lock_bh(&idev->lock);
+		list_for_each_entry(sp_ifa, &idev->addr_list, if_list) {
+
+			if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))
+				continue;
+
+			sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
+
+			/* Failure cases are ignored */
+			if (!IS_ERR(sp_rt))
+				ip6_ins_rt(sp_rt);
+		}
+		read_unlock_bh(&idev->lock);
+	}
 }
 
 static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
author maintainer
#6 lore raw

PATCH 6/30 net: count hw_addr syncs so that unsync works properly.

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vlad Yasevich <[email protected]>

[ Upstream commit 4543fbefe6e06a9e40d9f2b28d688393a299f079 ]

A few drivers use dev_uc_sync/unsync to synchronize the address lists from master down to slave/lower devices. In some cases (bond/team) a single address list is synched down to multiple devices. At the time of unsync, we have a leak in these lower devices, because "synced" is treated as a boolean and the address will not be unsynced for anything after the first device/call.

Treat "synced" as a count (same as refcount) and allow all unsync calls to work.

---
 include/linux/netdevice.h |    2 +-
 net/core/dev_addr_lists.c |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
include/linux/netdevice.h +1 -1
@@ -231,9 +231,9 @@ struct netdev_hw_addr {
 #define NETDEV_HW_ADDR_T_SLAVE		3
 #define NETDEV_HW_ADDR_T_UNICAST	4
 #define NETDEV_HW_ADDR_T_MULTICAST	5
-	bool			synced;
 	bool			global_use;
 	int			refcount;
+	int			synced;
 	struct rcu_head		rcu_head;
 };
 
net/core/dev_addr_lists.c +3 -3
@@ -56,7 +56,7 @@ static int __hw_addr_add_ex(struct netde
 	ha->type = addr_type;
 	ha->refcount = 1;
 	ha->global_use = global;
-	ha->synced = false;
+	ha->synced = 0;
 	list_add_tail_rcu(&ha->list, &list->list);
 	list->count++;
 	return 0;
@@ -154,7 +154,7 @@ int __hw_addr_sync(struct netdev_hw_addr
 					    addr_len, ha->type);
 			if (err)
 				break;
-			ha->synced = true;
+			ha->synced++;
 			ha->refcount++;
 		} else if (ha->refcount == 1) {
 			__hw_addr_del(to_list, ha->addr, addr_len, ha->type);
@@ -175,7 +175,7 @@ void __hw_addr_unsync(struct netdev_hw_a
 		if (ha->synced) {
 			__hw_addr_del(to_list, ha->addr,
 				      addr_len, ha->type);
-			ha->synced = false;
+			ha->synced--;
 			__hw_addr_del(from_list, ha->addr,
 				      addr_len, ha->type);
 		}
author maintainer
#7 lore raw

PATCH 7/30 atl1e: limit gso segment size to prevent generation of wrong ip length fields

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hannes Frederic Sowa <[email protected]>

[ Upstream commit 31d1670e73f4911fe401273a8f576edc9c2b5fea ]

The limit of 0x3c00 is taken from the windows driver.

---
 drivers/net/atl1e/atl1e.h      |    2 +-
 drivers/net/atl1e/atl1e_main.c |    1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/net/atl1e/atl1e.h +1 -1
@@ -186,7 +186,7 @@ struct atl1e_tpd_desc {
 /* how about 0x2000 */
 #define MAX_TX_BUF_LEN      0x2000
 #define MAX_TX_BUF_SHIFT    13
-/*#define MAX_TX_BUF_LEN  0x3000 */
+#define MAX_TSO_SEG_SIZE    0x3c00
 
 /* rrs word 1 bit 0:31 */
 #define RRS_RX_CSUM_MASK	0xFFFF
drivers/net/atl1e/atl1e_main.c +1 -0
@@ -2333,6 +2333,7 @@ static int __devinit atl1e_probe(struct
 
 	INIT_WORK(&adapter->reset_task, atl1e_reset_task);
 	INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task);
+	netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE);
 	err = register_netdev(netdev);
 	if (err) {
 		netdev_err(netdev, "register netdevice failed\n");
author maintainer
#8 lore raw

PATCH 8/30 bonding: IFF_BONDING is not stripped on enslave failure

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: "[email protected]" <[email protected]>

[ Upstream commit b6a5a7b9a528a8b4c8bec940b607c5dd9102b8cc ]

While enslaving a new device and after IFF_BONDING flag is set, in case of failure it is not stripped from the device's priv_flags while cleaning up, which could lead to other problems.
Cleaning at err_close because the flag is set after dev_open().

v2: no change

---
 drivers/net/bonding/bond_main.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/bonding/bond_main.c +1 -0
@@ -1949,6 +1949,7 @@ err_detach:
 	write_unlock_bh(&bond->lock);
 
 err_close:
+	slave_dev->priv_flags &= ~IFF_BONDING;
 	dev_close(slave_dev);
 
 err_unset_master:
author maintainer
#9 lore raw

PATCH 9/30 af_unix: If we dont care about credentials coallesce all messages

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: "Eric W. Biederman" <[email protected]>

[ Upstream commit 0e82e7f6dfeec1013339612f74abc2cdd29d43d2 ]

It was reported that the following LSB test case failed
https://lsbbugs.linuxfoundation.org/attachment.cgi?id=2144 because we were not coallescing unix stream messages when the application was expecting us to.

The problem was that the first send was before the socket was accepted and thus sock->sk_socket was NULL in maybe_add_creds, and the second send after the socket was accepted had a non-NULL value for sk->socket and thus we could tell the credentials were not needed so we did not bother.

The unnecessary credentials on the first message cause unix_stream_recvmsg to start verifying that all messages had the same credentials before coallescing and then the coallescing failed because the second message had no credentials.

Ignoring credentials when we don't care in unix_stream_recvmsg fixes a long standing pessimization which would fail to coallesce messages when reading from a unix stream socket if the senders were different even if we did not care about their credentials.

I have tested this and verified that the in the LSB test case mentioned above that the messages do coallesce now, while the were failing to coallesce without this change.

---
 net/unix/af_unix.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
@@ -1940,7 +1940,7 @@ static int unix_stream_recvmsg(struct ki
 				skb_queue_head(&sk->sk_receive_queue, skb);
 				break;
 			}
-		} else {
+		} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
 			/* Copy credentials */
 			scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
 			check_creds = 1;
author maintainer
#10 lore raw

PATCH 10/30 netfilter: dont reset nf_trace in nf_reset()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Patrick McHardy <[email protected]>

[ Upstream commit 124dff01afbdbff251f0385beca84ba1b9adda68 ]

Commit 130549fe ("netfilter: reset nf_trace in nf_reset") added code to reset nf_trace in nf_reset(). This is wrong and unnecessary.

nf_reset() is used in the following cases:

- when passing packets up the the socket layer, at which point we want to release all netfilter references that might keep modules pinned while the packet is queued. nf_trace doesn't matter anymore at this point.

- when encapsulating or decapsulating IPsec packets. We want to continue tracing these packets after IPsec processing.

- when passing packets through virtual network devices. Only devices on that encapsulate in IPv4/v6 matter since otherwise nf_trace is not used anymore. Its not entirely clear whether those packets should be traced after that, however we've always done that.

- when passing packets through virtual network devices that make the packet cross network namespace boundaries. This is the only cases where we clearly want to reset nf_trace and is also what the original patch intended to fix.

Add a new function nf_reset_trace() and use it in dev_forward_skb() to fix this properly.

---
 include/linux/skbuff.h |    8 ++++++++
 net/core/dev.c         |    1 +
 2 files changed, 9 insertions(+)
include/linux/skbuff.h +8 -0
@@ -2135,6 +2135,14 @@ static inline void nf_reset(struct sk_bu
 #endif
 }
 
+static inline void nf_reset_trace(struct sk_buff *skb)
+{
+#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
+	defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
+	skb->nf_trace = 0;
+#endif
+}
+
 /* Note: This doesn't put any conntrack and bridge info in dst. */
 static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
 {
net/core/dev.c +1 -0
@@ -1545,6 +1545,7 @@ int dev_forward_skb(struct net_device *d
 	skb->mark = 0;
 	secpath_reset(skb);
 	nf_reset(skb);
+	nf_reset_trace(skb);
 	return netif_rx(skb);
 }
 EXPORT_SYMBOL_GPL(dev_forward_skb);
author maintainer
#11 lore raw

PATCH 11/30 rtnetlink: Call nlmsg_parse() with correct header length

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael Riesch <[email protected]>

[ Upstream commit 88c5b5ce5cb57af6ca2a7cf4d5715fa320448ff9 ]

---
 net/core/rtnetlink.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/rtnetlink.c +2 -2
@@ -1045,7 +1045,7 @@ static int rtnl_dump_ifinfo(struct sk_bu
 
 	rcu_read_lock();
 
-	if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+	if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
 			ifla_policy) >= 0) {
 
 		if (tb[IFLA_EXT_MASK])
@@ -1876,7 +1876,7 @@ static u16 rtnl_calcit(struct sk_buff *s
 	u32 ext_filter_mask = 0;
 	u16 min_ifinfo_dump_size = 0;
 
-	if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+	if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
 			ifla_policy) >= 0) {
 		if (tb[IFLA_EXT_MASK])
 			ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
author maintainer
#12 lore raw

PATCH 12/30 tcp: incoming connections might use wrong route under synflood

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dmitry Popov <[email protected]>

[ Upstream commit d66954a066158781ccf9c13c91d0316970fe57b6 ]

There is a bug in cookie_v4_check (net/ipv4/syncookies.c):

	flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
			   RT_SCOPE_UNIVERSE, IPPROTO_TCP,
			   inet_sk_flowi_flags(sk),
			   (opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
			   ireq->loc_addr, th->source, th->dest);

Here we do not respect sk->sk_bound_dev_if, therefore wrong dst_entry may be taken. This dst_entry is used by new socket (get_cookie_sock -> tcp_v4_syn_recv_sock), so its packets may take the wrong path.

---
 net/ipv4/syncookies.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv4/syncookies.c +2 -2
@@ -345,8 +345,8 @@ struct sock *cookie_v4_check(struct sock
 	 * hasn't changed since we received the original syn, but I see
 	 * no easy way to do this.
 	 */
-	flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk),
-			   RT_SCOPE_UNIVERSE, IPPROTO_TCP,
+	flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark,
+			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP,
 			   inet_sk_flowi_flags(sk),
 			   (opt && opt->srr) ? opt->faddr : ireq->rmt_addr,
 			   ireq->loc_addr, th->source, th->dest);
author maintainer
#13 lore raw

PATCH 13/30 esp4: fix error return code in esp_output()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wei Yongjun <[email protected]>

[ Upstream commit 06848c10f720cbc20e3b784c0df24930b7304b93 ]

Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in this function.

---
 net/ipv4/esp4.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
net/ipv4/esp4.c +3 -3
@@ -137,8 +137,6 @@ static int esp_output(struct xfrm_state
 
 	/* skb is pure payload to encrypt */
 
-	err = -ENOMEM;
-
 	esp = x->data;
 	aead = esp->aead;
 	alen = crypto_aead_authsize(aead);
@@ -174,8 +172,10 @@ static int esp_output(struct xfrm_state
 	}
 
 	tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen);
-	if (!tmp)
+	if (!tmp) {
+		err = -ENOMEM;
 		goto error;
+	}
 
 	seqhi = esp_tmp_seqhi(tmp);
 	iv = esp_tmp_iv(aead, tmp, seqhilen);
author maintainer
#14 lore raw

PATCH 14/30 net: sctp: sctp_auth_key_put: use kzfree instead of kfree

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <[email protected]>

[ Upstream commit 586c31f3bf04c290dc0a0de7fc91d20aa9a5ee53 ]

For sensitive data like keying material, it is common practice to zero out keys before returning the memory back to the allocator. Thus, use kzfree instead of kfree.

---
 net/sctp/auth.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/auth.c +1 -1
@@ -71,7 +71,7 @@ void sctp_auth_key_put(struct sctp_auth_
 		return;
 
 	if (atomic_dec_and_test(&key->refcnt)) {
-		kfree(key);
+		kzfree(key);
 		SCTP_DBG_OBJCNT_DEC(keys);
 	}
 }
author maintainer
#15 lore raw

PATCH 15/30 tcp: call tcp_replace_ts_recent() from tcp_ack()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 12fb3dd9dc3c64ba7d64cec977cca9b5fb7b1d4e ]

commit bd090dfc634d (tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming()) introduced a TS ecr bug in slow path processing.

1 A > B P. 1:10001(10000) ack 1 <nop,nop,TS val 1001 ecr 200> 2 B < A . 1:1(0) ack 1 win 257 <sack 9001:10001,TS val 300 ecr 1001> 3 A > B . 1:1001(1000) ack 1 win 227 <nop,nop,TS val 1002 ecr 200> 4 A > B . 1001:2001(1000) ack 1 win 227 <nop,nop,TS val 1002 ecr 200>

(ecr 200 should be ecr 300 in packets 3 & 4)

Problem is tcp_ack() can trigger send of new packets (retransmits), reflecting the prior TSval, instead of the TSval contained in the currently processed incoming packet.

Fix this by calling tcp_replace_ts_recent() from tcp_ack() after the checks, but before the actions.

---
 net/ipv4/tcp_input.c |   65 +++++++++++++++++++++++++--------------------------
 1 file changed, 32 insertions(+), 33 deletions(-)
net/ipv4/tcp_input.c +32 -33
@@ -115,6 +115,7 @@ int sysctl_tcp_abc __read_mostly;
 #define FLAG_DSACKING_ACK	0x800 /* SACK blocks contained D-SACK info */
 #define FLAG_NONHEAD_RETRANS_ACKED	0x1000 /* Non-head rexmitted data was ACKed */
 #define FLAG_SACK_RENEGING	0x2000 /* snd_una advanced to a sacked seq */
+#define FLAG_UPDATE_TS_RECENT	0x4000 /* tcp_replace_ts_recent() */
 
 #define FLAG_ACKED		(FLAG_DATA_ACKED|FLAG_SYN_ACKED)
 #define FLAG_NOT_DUP		(FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
@@ -3656,6 +3657,27 @@ static void tcp_send_challenge_ack(struc
 	}
 }
 
+static void tcp_store_ts_recent(struct tcp_sock *tp)
+{
+	tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
+	tp->rx_opt.ts_recent_stamp = get_seconds();
+}
+
+static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
+{
+	if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
+		/* PAWS bug workaround wrt. ACK frames, the PAWS discard
+		 * extra check below makes sure this can only happen
+		 * for pure ACK frames.  -DaveM
+		 *
+		 * Not only, also it occurs for expired timestamps.
+		 */
+
+		if (tcp_paws_check(&tp->rx_opt, 0))
+			tcp_store_ts_recent(tp);
+	}
+}
+
 /* This routine deals with incoming acks, but not outgoing ones. */
 static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
 {
@@ -3702,6 +3724,12 @@ static int tcp_ack(struct sock *sk, stru
 	prior_fackets = tp->fackets_out;
 	prior_in_flight = tcp_packets_in_flight(tp);
 
+	/* ts_recent update must be made after we are sure that the packet
+	 * is in window.
+	 */
+	if (flag & FLAG_UPDATE_TS_RECENT)
+		tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
+
 	if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
 		/* Window is constant, pure forward advance.
 		 * No more checks are required.
@@ -3988,27 +4016,6 @@ u8 *tcp_parse_md5sig_option(struct tcphd
 EXPORT_SYMBOL(tcp_parse_md5sig_option);
 #endif
 
-static inline void tcp_store_ts_recent(struct tcp_sock *tp)
-{
-	tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval;
-	tp->rx_opt.ts_recent_stamp = get_seconds();
-}
-
-static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq)
-{
-	if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) {
-		/* PAWS bug workaround wrt. ACK frames, the PAWS discard
-		 * extra check below makes sure this can only happen
-		 * for pure ACK frames.  -DaveM
-		 *
-		 * Not only, also it occurs for expired timestamps.
-		 */
-
-		if (tcp_paws_check(&tp->rx_opt, 0))
-			tcp_store_ts_recent(tp);
-	}
-}
-
 /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM
  *
  * It is not fatal. If this ACK does _not_ change critical state (seqs, window)
@@ -5477,14 +5484,10 @@ slow_path:
 		return 0;
 
 step5:
-	if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0)
+	if (th->ack &&
+	    tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0)
 		goto discard;
 
-	/* ts_recent update must be made after we are sure that the packet
-	 * is in window.
-	 */
-	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
 	tcp_rcv_rtt_measure_ts(sk, skb);
 
 	/* Process urgent data. */
@@ -5848,7 +5851,8 @@ int tcp_rcv_state_process(struct sock *s
 
 	/* step 5: check the ACK field */
 	if (th->ack) {
-		int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0;
+		int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH |
+						  FLAG_UPDATE_TS_RECENT) > 0;
 
 		switch (sk->sk_state) {
 		case TCP_SYN_RECV:
@@ -5961,11 +5965,6 @@ int tcp_rcv_state_process(struct sock *s
 	} else
 		goto discard;
 
-	/* ts_recent update must be made after we are sure that the packet
-	 * is in window.
-	 */
-	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
-
 	/* step 6: check the URG bit */
 	tcp_urg(sk, skb, th);
 
author maintainer
#16 lore raw

PATCH 16/30 net: fix incorrect credentials passing

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Linus Torvalds <[email protected]>

[ Upstream commit 83f1b4ba917db5dc5a061a44b3403ddb6e783494 ]

Commit 257b5358b32f ("scm: Capture the full credentials of the scm sender") changed the credentials passing code to pass in the effective uid/gid instead of the real uid/gid.

Obviously this doesn't matter most of the time (since normally they are the same), but it results in differences for suid binaries when the wrong uid/gid ends up being used.

This just undoes that (presumably unintentional) part of the commit.

---
 include/linux/socket.h |    3 ++-
 include/net/scm.h      |    2 +-
 net/core/sock.c        |   14 ++++++++++----
 3 files changed, 13 insertions(+), 6 deletions(-)
include/linux/socket.h +2 -1
@@ -312,7 +312,8 @@ struct ucred {
 /* IPX options */
 #define IPX_TYPE	1
 
-extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred);
+extern void cred_to_ucred(struct pid *pid, const struct cred *cred, struct ucred *ucred,
+			  bool use_effective);
 
 extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
 extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
include/net/scm.h +1 -1
@@ -50,7 +50,7 @@ static __inline__ void scm_set_cred(stru
 {
 	scm->pid  = get_pid(pid);
 	scm->cred = get_cred(cred);
-	cred_to_ucred(pid, cred, &scm->creds);
+	cred_to_ucred(pid, cred, &scm->creds, false);
 }
 
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
net/core/sock.c +10 -4
@@ -752,15 +752,20 @@ EXPORT_SYMBOL(sock_setsockopt);
 
 
 void cred_to_ucred(struct pid *pid, const struct cred *cred,
-		   struct ucred *ucred)
+		   struct ucred *ucred, bool use_effective)
 {
 	ucred->pid = pid_vnr(pid);
 	ucred->uid = ucred->gid = -1;
 	if (cred) {
 		struct user_namespace *current_ns = current_user_ns();
 
-		ucred->uid = user_ns_map_uid(current_ns, cred, cred->euid);
-		ucred->gid = user_ns_map_gid(current_ns, cred, cred->egid);
+		if (use_effective) {
+			ucred->uid = user_ns_map_uid(current_ns, cred, cred->euid);
+			ucred->gid = user_ns_map_gid(current_ns, cred, cred->egid);
+		} else {
+			ucred->uid = user_ns_map_uid(current_ns, cred, cred->uid);
+			ucred->gid = user_ns_map_gid(current_ns, cred, cred->gid);
+		}
 	}
 }
 EXPORT_SYMBOL_GPL(cred_to_ucred);
@@ -921,7 +926,8 @@ int sock_getsockopt(struct socket *sock,
 		struct ucred peercred;
 		if (len > sizeof(peercred))
 			len = sizeof(peercred);
-		cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred, &peercred);
+		cred_to_ucred(sk->sk_peer_pid, sk->sk_peer_cred,
+			      &peercred, true);
 		if (copy_to_user(optval, &peercred, len))
 			return -EFAULT;
 		goto lenout;
author maintainer
#17 lore raw

PATCH 17/30 atm: update msg_namelen in vcc_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit 9b3e617f3df53822345a8573b6d358f6b9e5ed87 ]

The current code does not fill the msg_name member in case it is set. It also does not set the msg_namelen member to 0 and therefore makes net/socket.c leak the local, uninitialized sockaddr_storage variable to userland -- 128 bytes of kernel stack memory.

Fix that by simply setting msg_namelen to 0 as obviously nobody cared about vcc_recvmsg() not filling the msg_name in case it was set.

---
 net/atm/common.c |    2 ++
 1 file changed, 2 insertions(+)
net/atm/common.c +2 -0
@@ -500,6 +500,8 @@ int vcc_recvmsg(struct kiocb *iocb, stru
 	struct sk_buff *skb;
 	int copied, error = -EINVAL;
 
+	msg->msg_namelen = 0;
+
 	if (sock->state != SS_CONNECTED)
 		return -ENOTCONN;
 	if (flags & ~MSG_DONTWAIT)		/* only handle MSG_DONTWAIT */
author maintainer
#18 lore raw

PATCH 18/30 ax25: fix info leak via msg_name in ax25_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit ef3313e84acbf349caecae942ab3ab731471f1a1 ]

When msg_namelen is non-zero the sockaddr info gets filled out, as requested, but the code fails to initialize the padding bytes of struct sockaddr_ax25 inserted by the compiler for alignment. Additionally the msg_namelen value is updated to sizeof(struct full_sockaddr_ax25) but is not always filled up to this size.

Both issues lead to the fact that the code will leak uninitialized kernel stack bytes in net/socket.c.

Fix both issues by initializing the memory with memset(0).

---
 net/ax25/af_ax25.c |    1 +
 1 file changed, 1 insertion(+)
net/ax25/af_ax25.c +1 -0
@@ -1641,6 +1641,7 @@ static int ax25_recvmsg(struct kiocb *io
 		ax25_address src;
 		const unsigned char *mac = skb_mac_header(skb);
 
+		memset(sax, 0, sizeof(struct full_sockaddr_ax25));
 		ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
 				&digi, NULL, NULL);
 		sax->sax25_family = AF_AX25;
author maintainer
#19 lore raw

PATCH 19/30 Bluetooth: fix possible info leak in bt_sock_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit 4683f42fde3977bdb4e8a09622788cc8b5313778 ]

In case the socket is already shutting down, bt_sock_recvmsg() returns with 0 without updating msg_namelen leading to net/socket.c leaking the local, uninitialized sockaddr_storage variable to userland -- 128 bytes of kernel stack memory.

Fix this by moving the msg_namelen assignment in front of the shutdown test.

---
 net/bluetooth/af_bluetooth.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
net/bluetooth/af_bluetooth.c +2 -2
@@ -245,6 +245,8 @@ int bt_sock_recvmsg(struct kiocb *iocb,
 	if (flags & (MSG_OOB))
 		return -EOPNOTSUPP;
 
+	msg->msg_namelen = 0;
+
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
 	if (!skb) {
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
@@ -252,8 +254,6 @@ int bt_sock_recvmsg(struct kiocb *iocb,
 		return err;
 	}
 
-	msg->msg_namelen = 0;
-
 	copied = skb->len;
 	if (len < copied) {
 		msg->msg_flags |= MSG_TRUNC;
author maintainer
#20 lore raw

PATCH 20/30 Bluetooth: RFCOMM - Fix missing msg_namelen update in rfcomm_sock_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit e11e0455c0d7d3d62276a0c55d9dfbc16779d691 ]

If RFCOMM_DEFER_SETUP is set in the flags, rfcomm_sock_recvmsg() returns early with 0 without updating the possibly set msg_namelen member. This, in turn, leads to a 128 byte kernel stack leak in net/socket.c.

Fix this by updating msg_namelen in this case. For all other cases it will be handled in bt_sock_stream_recvmsg().

---
 net/bluetooth/rfcomm/sock.c |    1 +
 1 file changed, 1 insertion(+)
net/bluetooth/rfcomm/sock.c +1 -0
@@ -624,6 +624,7 @@ static int rfcomm_sock_recvmsg(struct ki
 
 	if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
 		rfcomm_dlc_accept(d);
+		msg->msg_namelen = 0;
 		return 0;
 	}
 
author maintainer
#21 lore raw

PATCH 21/30 caif: Fix missing msg_namelen update in caif_seqpkt_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit 2d6fbfe733f35c6b355c216644e08e149c61b271 ]

The current code does not fill the msg_name member in case it is set. It also does not set the msg_namelen member to 0 and therefore makes net/socket.c leak the local, uninitialized sockaddr_storage variable to userland -- 128 bytes of kernel stack memory.

Fix that by simply setting msg_namelen to 0 as obviously nobody cared about caif_seqpkt_recvmsg() not filling the msg_name in case it was set.

---
 net/caif/caif_socket.c |    2 ++
 1 file changed, 2 insertions(+)
net/caif/caif_socket.c +2 -0
@@ -320,6 +320,8 @@ static int caif_seqpkt_recvmsg(struct ki
 	if (m->msg_flags&MSG_OOB)
 		goto read_error;
 
+	m->msg_namelen = 0;
+
 	skb = skb_recv_datagram(sk, flags, 0 , &ret);
 	if (!skb)
 		goto read_error;
author maintainer
#22 lore raw

PATCH 22/30 irda: Fix missing msg_namelen update in irda_recvmsg_dgram()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit 5ae94c0d2f0bed41d6718be743985d61b7f5c47d ]

The current code does not fill the msg_name member in case it is set. It also does not set the msg_namelen member to 0 and therefore makes net/socket.c leak the local, uninitialized sockaddr_storage variable to userland -- 128 bytes of kernel stack memory.

Fix that by simply setting msg_namelen to 0 as obviously nobody cared about irda_recvmsg_dgram() not filling the msg_name in case it was set.

---
 net/irda/af_irda.c |    2 ++
 1 file changed, 2 insertions(+)
net/irda/af_irda.c +2 -0
@@ -1386,6 +1386,8 @@ static int irda_recvmsg_dgram(struct kio
 
 	IRDA_DEBUG(4, "%s()\n", __func__);
 
+	msg->msg_namelen = 0;
+
 	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
 				flags & MSG_DONTWAIT, &err);
 	if (!skb)
author maintainer
#23 lore raw

PATCH 23/30 iucv: Fix missing msg_namelen update in iucv_sock_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit a5598bd9c087dc0efc250a5221e5d0e6f584ee88 ]

The current code does not fill the msg_name member in case it is set. It also does not set the msg_namelen member to 0 and therefore makes net/socket.c leak the local, uninitialized sockaddr_storage variable to userland -- 128 bytes of kernel stack memory.

Fix that by simply setting msg_namelen to 0 as obviously nobody cared about iucv_sock_recvmsg() not filling the msg_name in case it was set.

---
 net/iucv/af_iucv.c |    2 ++
 1 file changed, 2 insertions(+)
net/iucv/af_iucv.c +2 -0
@@ -1157,6 +1157,8 @@ static int iucv_sock_recvmsg(struct kioc
 	struct sk_buff *skb, *rskb, *cskb;
 	int err = 0;
 
+	msg->msg_namelen = 0;
+
 	if ((sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_SEVERED) &&
 	    skb_queue_empty(&iucv->backlog_skb_q) &&
 	    skb_queue_empty(&sk->sk_receive_queue) &&
author maintainer
#24 lore raw

PATCH 24/30 llc: Fix missing msg_namelen update in llc_ui_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit c77a4b9cffb6215a15196ec499490d116dfad181 ]

For stream sockets the code misses to update the msg_namelen member to 0 and therefore makes net/socket.c leak the local, uninitialized sockaddr_storage variable to userland -- 128 bytes of kernel stack memory. The msg_namelen update is also missing for datagram sockets in case the socket is shutting down during receive.

Fix both issues by setting msg_namelen to 0 early. It will be updated later if we're going to fill the msg_name member.

---
 net/llc/af_llc.c |    2 ++
 1 file changed, 2 insertions(+)
net/llc/af_llc.c +2 -0
@@ -720,6 +720,8 @@ static int llc_ui_recvmsg(struct kiocb *
 	int target;	/* Read at least this many bytes */
 	long timeo;
 
+	msg->msg_namelen = 0;
+
 	lock_sock(sk);
 	copied = -ENOTCONN;
 	if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
author maintainer
#25 lore raw

PATCH 25/30 netrom: fix info leak via msg_name in nr_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commits 3ce5efad47b62c57a4f5c54248347085a750ce0e and
c802d759623acbd6e1ee9fbdabae89159a513913 ]

In case msg_name is set the sockaddr info gets filled out, as requested, but the code fails to initialize the padding bytes of struct sockaddr_ax25 inserted by the compiler for alignment. Also the sax25_ndigis member does not get assigned, leaking four more bytes.

Both issues lead to the fact that the code will leak uninitialized kernel stack bytes in net/socket.c.

Fix both issues by initializing the memory with memset(0).

---
 net/netrom/af_netrom.c |    1 +
 1 file changed, 1 insertion(+)
net/netrom/af_netrom.c +1 -0
@@ -1178,6 +1178,7 @@ static int nr_recvmsg(struct kiocb *iocb
 	}
 
 	if (sax != NULL) {
+		memset(sax, 0, sizeof(sax));
 		sax->sax25_family = AF_NETROM;
 		skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
 			      AX25_ADDR_LEN);
author maintainer
#26 lore raw

PATCH 26/30 rose: fix info leak via msg_name in rose_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit 4a184233f21645cf0b719366210ed445d1024d72 ]

The code in rose_recvmsg() does not initialize all of the members of struct sockaddr_rose/full_sockaddr_rose when filling the sockaddr info. Nor does it initialize the padding bytes of the structure inserted by the compiler for alignment. This will lead to leaking uninitialized kernel stack bytes in net/socket.c.

Fix the issue by initializing the memory used for sockaddr info with memset(0).

---
 net/rose/af_rose.c |    1 +
 1 file changed, 1 insertion(+)
net/rose/af_rose.c +1 -0
@@ -1258,6 +1258,7 @@ static int rose_recvmsg(struct kiocb *io
 	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
 	if (srose != NULL) {
+		memset(srose, 0, msg->msg_namelen);
 		srose->srose_family = AF_ROSE;
 		srose->srose_addr   = rose->dest_addr;
 		srose->srose_call   = rose->dest_call;
author maintainer
#27 lore raw

PATCH 27/30 tipc: fix info leaks via msg_name in recv_msg/recv_stream

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mathias Krause <[email protected]>

[ Upstream commit 60085c3d009b0df252547adb336d1ccca5ce52ec ]

The code in set_orig_addr() does not initialize all of the members of struct sockaddr_tipc when filling the sockaddr info -- namely the union is only partly filled. This will make recv_msg() and recv_stream() -- the only users of this function -- leak kernel stack memory as the msg_name member is a local variable in net/socket.c.

Additionally to that both recv_msg() and recv_stream() fail to update the msg_namelen member to 0 while otherwise returning with 0, i.e. "success". This is the case for, e.g., non-blocking sockets. This will lead to a 128 byte kernel stack leak in net/socket.c.

Fix the first issue by initializing the memory of the union with memset(0). Fix the second one by setting msg_namelen to 0 early as it will be updated later if we're going to fill the msg_name member.

---
 net/tipc/socket.c |    7 +++++++
 1 file changed, 7 insertions(+)
net/tipc/socket.c +7 -0
@@ -829,6 +829,7 @@ static void set_orig_addr(struct msghdr
 	if (addr) {
 		addr->family = AF_TIPC;
 		addr->addrtype = TIPC_ADDR_ID;
+		memset(&addr->addr, 0, sizeof(addr->addr));
 		addr->addr.id.ref = msg_origport(msg);
 		addr->addr.id.node = msg_orignode(msg);
 		addr->addr.name.domain = 0;	/* could leave uninitialized */
@@ -948,6 +949,9 @@ static int recv_msg(struct kiocb *iocb,
 		goto exit;
 	}
 
+	/* will be updated in set_orig_addr() if needed */
+	m->msg_namelen = 0;
+
 	timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 restart:
 
@@ -1074,6 +1078,9 @@ static int recv_stream(struct kiocb *ioc
 		goto exit;
 	}
 
+	/* will be updated in set_orig_addr() if needed */
+	m->msg_namelen = 0;
+
 	target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
 	timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 restart:
author maintainer
#28 lore raw

PATCH 28/30 netrom: fix invalid use of sizeof in nr_recvmsg()

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Wei Yongjun <[email protected]>

[ Upstream commit c802d759623acbd6e1ee9fbdabae89159a513913 ]

sizeof() when applied to a pointer typed expression gives the size of the pointer, not that of the pointed data.
Introduced by commit 3ce5ef(netrom: fix info leak via msg_name in nr_recvmsg)

---
 net/netrom/af_netrom.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/netrom/af_netrom.c +1 -1
@@ -1178,7 +1178,7 @@ static int nr_recvmsg(struct kiocb *iocb
 	}
 
 	if (sax != NULL) {
-		memset(sax, 0, sizeof(sax));
+		memset(sax, 0, sizeof(*sax));
 		sax->sax25_family = AF_NETROM;
 		skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
 			      AX25_ADDR_LEN);
author maintainer
#29 lore raw

PATCH 29/30 net: drop dst before queueing fragments

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

[ Upstream commit 97599dc792b45b1669c3cdb9a4b365aad0232f65 ]

Commit 4a94445c9a5c (net: Use ip_route_input_noref() in input path) added a bug in IP defragmentation handling, as non refcounted dst could escape an RCU protected section.

Commit 64f3b9e203bd068 (net: ip_expire() must revalidate route) fixed the case of timeouts, but not the general problem.

Tom Parkin noticed crashes in UDP stack and provided a patch, but further analysis permitted us to pinpoint the root cause.

Before queueing a packet into a frag list, we must drop its dst, as this dst has limited lifetime (RCU protected)

When/if a packet is finally reassembled, we use the dst of the very last skb, still protected by RCU and valid, as the dst of the reassembled packet.

Use same logic in IPv6, as there is no need to hold dst references.

---
 net/ipv4/ip_fragment.c |   15 +++++++++++----
 net/ipv6/reassembly.c  |   13 +++++++++++--
 2 files changed, 22 insertions(+), 6 deletions(-)
net/ipv4/ip_fragment.c +11 -4
@@ -251,8 +251,7 @@ static void ip_expire(unsigned long arg)
 		if (!head->dev)
 			goto out_rcu_unlock;
 
-		/* skb dst is stale, drop it, and perform route lookup again */
-		skb_dst_drop(head);
+		/* skb has no dst, perform route lookup again */
 		iph = ip_hdr(head);
 		err = ip_route_input_noref(head, iph->daddr, iph->saddr,
 					   iph->tos, head->dev);
@@ -517,8 +516,16 @@ found:
 		qp->q.last_in |= INET_FRAG_FIRST_IN;
 
 	if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
-	    qp->q.meat == qp->q.len)
-		return ip_frag_reasm(qp, prev, dev);
+	    qp->q.meat == qp->q.len) {
+		unsigned long orefdst = skb->_skb_refdst;
+
+		skb->_skb_refdst = 0UL;
+		err = ip_frag_reasm(qp, prev, dev);
+		skb->_skb_refdst = orefdst;
+		return err;
+	}
+
+	skb_dst_drop(skb);
 
 	write_lock(&ip4_frags.lock);
 	list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list);
net/ipv6/reassembly.c +11 -2
@@ -385,8 +385,17 @@ found:
 	}
 
 	if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
-	    fq->q.meat == fq->q.len)
-		return ip6_frag_reasm(fq, prev, dev);
+	    fq->q.meat == fq->q.len) {
+		int res;
+		unsigned long orefdst = skb->_skb_refdst;
+
+		skb->_skb_refdst = 0UL;
+		res = ip6_frag_reasm(fq, prev, dev);
+		skb->_skb_refdst = orefdst;
+		return res;
+	}
+
+	skb_dst_drop(skb);
 
 	write_lock(&ip6_frags.lock);
 	list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list);
author maintainer
#30 lore raw

PATCH 30/30 sparc32: support atomic64_t

In reply to Greg Kroah-Hartman

3.0-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sam Ravnborg <[email protected]>

commit aea1181b0bd0a09c54546399768f359d1e198e45 upstream, Needed to compile ext4 for sparc32 since commit 503f4bdcc078e7abee273a85ce322de81b18a224

There is no-one that really require atomic64_t support on sparc32. But several drivers fails to build without proper atomic64 support. And for an allyesconfig build for sparc32 this is annoying.

Include the generic atomic64_t support for sparc32. This has a text footprint cost:

$size vmlinux (before atomic64_t support)
text data bss dec hex filename
3578860 134260 108781 3821901 3a514d vmlinux

$size vmlinux (after atomic64_t support)
text data bss dec hex filename
3579892 130684 108781 3819357 3a475d vmlinux

text increase (3579892 - 3578860) = 1032 bytes

data decreases - but I fail to explain why!
I have rebuild twice to check my numbers.

---
 arch/sparc/Kconfig                 |    1 +
 arch/sparc/include/asm/atomic_32.h |    2 ++
 2 files changed, 3 insertions(+)
arch/sparc/Kconfig +1 -0
@@ -31,6 +31,7 @@ config SPARC
 
 config SPARC32
 	def_bool !64BIT
+	select GENERIC_ATOMIC64
 
 config SPARC64
 	def_bool 64BIT
arch/sparc/include/asm/atomic_32.h +2 -0
@@ -15,6 +15,8 @@
 
 #ifdef __KERNEL__
 
+#include <asm-generic/atomic64.h>
+
 #include <asm/system.h>
 
 #define ATOMIC_INIT(i)  { (i) }
#31 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 3.0.76 release. There are 30 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed May 1 18:42:50 UTC 2013. Anything received after that time might be too late.

Quoted 8 lines

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v3.0/stable-review/patch-3.0.76-rc1.gz

and the diffstat can be found below.

thanks,

greg k-h

Patches applied cleanly to 3.0.75, 3.4.42, and 3.8.10

Compiled and booted on the following systems:

Samsung Series 9 Intel Corei5 (3.4.43-rc1 and 3.8.11-rc1) HP ProBook 6475b AMD A10-4600M APU with Radeon(tm) HD Graphics

dmesgs for all releases look good. No regressions compared to the previous dmesgs for each of these releases.

Cross-compile tests results:

alpha: defconfig passed on all
arm: defconfig passed on all
arm64: not applicable to 3.0.y, 3.4.y. defconfig passed on 3.8.y
c6x: not applicable to 3.0.y, defconfig passed on 3.4.y, and 3.8.y.
mips: defconfig passed on all
mipsel: defconfig passed on all
powerpc: wii_defconfig passed on all
sh: defconfig passed on all
sparc: defconfig passed on all
tile: tilegx_defconfig passed on all

-- Shuah