3.0.76-stable review
Subsystems (19)
Greg Kroah-Hartman
maintainercover 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(-)
Greg Kroah-Hartman
maintainerPATCH 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 *filelse 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;
Greg Kroah-Hartman
maintainerPATCH 2/30 TTY: fix atime/mtime regression
In reply to Greg Kroah-Hartman3.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;
Greg Kroah-Hartman
maintainerPATCH 3/30 sparc64: Fix race in TLB batch processing.
In reply to Greg Kroah-Hartman3.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(strreturn 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
Greg Kroah-Hartman
maintainerPATCH 4/30 cbq: incorrect processing of high limits
In reply to Greg Kroah-Hartman3.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 (;;) {
Greg Kroah-Hartman
maintainerPATCH 5/30 net IPv6 : Fix broken IPv6 routing table after loopback down-up
In reply to Greg Kroah-Hartman3.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 inetstatic 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)
Greg Kroah-Hartman
maintainerPATCH 6/30 net: count hw_addr syncs so that unsync works properly.
In reply to Greg Kroah-Hartman3.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_aif (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); }
Greg Kroah-Hartman
maintainerPATCH 7/30 atl1e: limit gso segment size to prevent generation of wrong ip length fields
In reply to Greg Kroah-Hartman3.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(structINIT_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" );
Greg Kroah-Hartman
maintainerPATCH 8/30 bonding: IFF_BONDING is not stripped on enslave failure
In reply to Greg Kroah-Hartman3.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:
Greg Kroah-Hartman
maintainerPATCH 9/30 af_unix: If we dont care about credentials coallesce all messages
In reply to Greg Kroah-Hartman3.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 kiskb_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 ;
Greg Kroah-Hartman
maintainerPATCH 10/30 netfilter: dont reset nf_trace in nf_reset()
In reply to Greg Kroah-Hartman3.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);
Greg Kroah-Hartman
maintainerPATCH 11/30 rtnetlink: Call nlmsg_parse() with correct header length
In reply to Greg Kroah-Hartman3.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_burcu_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 *su32 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 ]);
Greg Kroah-Hartman
maintainerPATCH 12/30 tcp: incoming connections might use wrong route under synflood
In reply to Greg Kroah-Hartman3.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);
Greg Kroah-Hartman
maintainerPATCH 13/30 esp4: fix error return code in esp_output()
In reply to Greg Kroah-Hartman3.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);
Greg Kroah-Hartman
maintainerPATCH 14/30 net: sctp: sctp_auth_key_put: use kzfree instead of kfree
In reply to Greg Kroah-Hartman3.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); } }
Greg Kroah-Hartman
maintainerPATCH 15/30 tcp: call tcp_replace_ts_recent() from tcp_ack()
In reply to Greg Kroah-Hartman3.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 tcphdEXPORT_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);
Greg Kroah-Hartman
maintainerPATCH 16/30 net: fix incorrect credentials passing
In reply to Greg Kroah-Hartman3.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;
Greg Kroah-Hartman
maintainerPATCH 17/30 atm: update msg_namelen in vcc_recvmsg()
In reply to Greg Kroah-Hartman3.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, strustruct 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 */
Greg Kroah-Hartman
maintainerPATCH 18/30 ax25: fix info leak via msg_name in ax25_recvmsg()
In reply to Greg Kroah-Hartman3.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 *ioax25_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 ;
Greg Kroah-Hartman
maintainerPATCH 19/30 Bluetooth: fix possible info leak in bt_sock_recvmsg()
In reply to Greg Kroah-Hartman3.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 ;
Greg Kroah-Hartman
maintainerPATCH 20/30 Bluetooth: RFCOMM - Fix missing msg_namelen update in rfcomm_sock_recvmsg()
In reply to Greg Kroah-Hartman3.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 kiif (test_and_clear_bit (RFCOMM_DEFER_SETUP , &d->flags)) {rfcomm_dlc_accept (d); + msg->msg_namelen =0 ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 21/30 caif: Fix missing msg_namelen update in caif_seqpkt_recvmsg()
In reply to Greg Kroah-Hartman3.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 kiif (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;
Greg Kroah-Hartman
maintainerPATCH 22/30 irda: Fix missing msg_namelen update in irda_recvmsg_dgram()
In reply to Greg Kroah-Hartman3.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 kioIRDA_DEBUG (4 ,"%s()\n" , __func__); + msg->msg_namelen =0 ; + skb =skb_recv_datagram (sk, flags & ~MSG_DONTWAIT , flags &MSG_DONTWAIT , &err);if (!skb)
Greg Kroah-Hartman
maintainerPATCH 23/30 iucv: Fix missing msg_namelen update in iucv_sock_recvmsg()
In reply to Greg Kroah-Hartman3.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 kiocstruct 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) &&
Greg Kroah-Hartman
maintainerPATCH 24/30 llc: Fix missing msg_namelen update in llc_ui_recvmsg()
In reply to Greg Kroah-Hartman3.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 ))
Greg Kroah-Hartman
maintainerPATCH 25/30 netrom: fix info leak via msg_name in nr_recvmsg()
In reply to Greg Kroah-Hartman3.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 );
Greg Kroah-Hartman
maintainerPATCH 26/30 rose: fix info leak via msg_name in rose_recvmsg()
In reply to Greg Kroah-Hartman3.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 *ioskb_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;
Greg Kroah-Hartman
maintainerPATCH 27/30 tipc: fix info leaks via msg_name in recv_msg/recv_stream
In reply to Greg Kroah-Hartman3.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 msghdrif (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:
Greg Kroah-Hartman
maintainerPATCH 28/30 netrom: fix invalid use of sizeof in nr_recvmsg()
In reply to Greg Kroah-Hartman3.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 );
Greg Kroah-Hartman
maintainerPATCH 29/30 net: drop dst before queueing fragments
In reply to Greg Kroah-Hartman3.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);
Greg Kroah-Hartman
maintainerPATCH 30/30 sparc32: support atomic64_t
In reply to Greg Kroah-Hartman3.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) }
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.gzand 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