Merge changes from sid up to 3.14.5-1

svn path=/dists/trunk/linux/; revision=21401
This commit is contained in:
Ben Hutchings 2014-06-05 17:57:19 +00:00
commit 7c0cc59b3c
50 changed files with 889 additions and 181 deletions

106
debian/changelog vendored
View File

@ -49,6 +49,112 @@ linux (3.15~rc5-1~exp1) experimental; urgency=medium
-- maximilian attems <maks@debian.org> Fri, 16 May 2014 14:33:57 +0200
linux (3.14.5-1) unstable; urgency=high
* New upstream stable update:
http://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.14.5
- SCSI: dual scan thread bug fix
- SCSI: megaraid: missing bounds check in mimd_to_kioc()
- [x86] KVM: remove WARN_ON from get_kernel_ns()
- audit: convert PPIDs to the inital PID namespace.
- netfilter: nf_tables: fix nft_cmp_fast failure on big endian for size < 4
- netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len
(Closes: #741667)
- netfilter: Can't fail and free after table replacement
- [i386] x86,preempt: Fix preemption for i386
- rbd: fix error paths in rbd_img_request_fill()
- [x86] drm/i915: restore QUIRK_NO_PCH_PWM_ENABLE (regression in 3.14)
- tick-sched: Don't call update_wall_time() when delta is lesser than
tick_period (regression in 3.14)
- tick-sched: Check tick_nohz_enabled in tick_nohz_switch_to_nohz()
(regression in 3.13)
- [hppa] change value of SHMLBA from 0x00400000 to PAGE_SIZE
- [hppa] fix epoll_pwait syscall on compat kernel
- [hppa] remove _STK_LIM_MAX override
- vfs: don't bother with {get,put}_write_access() on non-regular files
- cifs: Wait for writebacks to complete before attempting write.
- xen/spinlock: Don't enable them unconditionally. (regression in 3.12)
- thp: close race between split and zap huge pages (regression in 3.13)
- mm/hugetlb.c: add cond_resched_lock() in return_unused_surplus_pages()
- mm: use paravirt friendly ops for NUMA hinting ptes
- USB: io_ti: fix firmware download on big-endian machines
- fs: Don't return 0 from get_anon_bdev (regression in 3.14)
- [x86] drm/vmwgfx: Make sure user-space can't DMA across buffer object
boundaries v2
- [x86] drm/i915: Do not dereference pointers from ring buffer in evict
event (regression in 3.13)
- net: core: don't account for udp header size when computing seglen
(regression in 3.14)
- bridge: Fix double free and memory leak around br_allowed_ingress
- filter: prevent nla extensions to peek beyond the end of the message
(CVE-2014-3144, CVE-2014-3145)
- Revert "net: sctp: Fix a_rwnd/rwnd management to reflect real state of
the receiver's buffer" (regression in 3.14)
- ip6_gre: don't allow to remove the fb_tunnel_dev
- net: sctp: cache auth_enable per endpoint
- net: Fix ns_capable check in sock_diag_put_filterinfo
- rtnetlink: Warn when interface's information won't fit in our packet
- rtnetlink: Only supply IFLA_VF_PORTS information when RTEXT_FILTER_VF
is set
- tcp_cubic: fix the range of delayed_ack
- net: cdc_ncm: fix buffer overflow (regression in 3.13)
- ip_tunnel: Set network header properly for IP_ECN_decapsulate()
(regression in 3.11)
- ipv4: ip_tunnels: disable cache for nbma gre tunnels (regression in 3.14)
- net: cdc_mbim: __vlan_find_dev_deep need rcu_read_lock
(regression in 3.13)
- net: ipv4: ip_forward: fix inverted local_df test (regression in 3.14)
- net: ipv6: send pkttoobig immediately if orig frag size > mtu
(regression in 3.14)
- ip6_tunnel: fix potential NULL pointer dereference
- neigh: set nud_state to NUD_INCOMPLETE when probing router reachability
(regression in 3.14)
- batman-adv: fix neigh_ifinfo imbalance (regression in 3.14)
- batman-adv: fix neigh reference imbalance (regression in 3.14)
- batman-adv: always run purge_orig_neighbors (regression in 3.14)
- batman-adv: fix removing neigh_ifinfo (regression in 3.14)
- [s390,x86] net: filter: fix JIT address randomization
- net: avoid dependency of net_get_random_once on nop patching
(regression in 3.13)
- ipv6: fix calculation of option len in ip6_append_data
(regression in 3.13)
- rtnetlink: wait for unregistering devices in rtnl_link_unregister()
- bonding: fix out of range parameters for bond_intmax_tbl
(regression in 3.14)
- net: gro: make sure skb->cb[] initial content has not to be zero
(regression in 3.13)
- batman-adv: fix indirect hard_iface NULL dereference (regression in 3.14)
- batman-adv: fix reference counting imbalance while sending fragment
(regression in 3.14)
- batman-adv: increase orig refcount when storing ref in gw_node
- batman-adv: fix local TT check for outgoing arp requests in DAT
(regression in 3.13)
- net_sched: fix an oops in tcindex filter (regression in 3.14)
- ipv6: gro: fix CHECKSUM_COMPLETE support (regression in 3.14)
- ipv4: initialise the itag variable in __mkroute_input
- net-gro: reset skb->truesize in napi_reuse_skb()
[ Ben Hutchings ]
* [x86] ACPICA: Tables: Fix invalid pointer accesses in
acpi_tb_parse_root_table(). (Closes: #748574)
* net: Revert lockdep changes in 3.14.5 to avoid an ABI change
* futex: Add another early deadlock detection check
* futex: Prevent attaching to kernel threads
* futex: Forbid uaddr == uaddr2 in futex_requeue(..., requeue_pi=1)
(CVE-2014-3153)
* futex: Validate atomic acquisition in futex_lock_pi_atomic()
* futex: Always cleanup owner tid in unlock_pi
* futex: Make lookup_pi_state more robust
[ Ian Campbell ]
* [arm64] Initial kernel configuration and packaging (Closes: #745349).
* [armhf] Add virtio-modules udeb.
[ Aurelien Jarno ]
* [mips,mipsel] Fix branch emulation of branch likely instructions.
-- Ben Hutchings <ben@decadent.org.uk> Thu, 05 Jun 2014 13:49:15 +0100
linux (3.14.4-1) unstable; urgency=high
* New upstream stable update:

74
debian/config/arm64/config vendored Normal file
View File

@ -0,0 +1,74 @@
##
## file: arch/arm64/Kconfig
##
CONFIG_ARCH_VEXPRESS=y
CONFIG_ARCH_XGENE=y
CONFIG_SMP=y
CONFIG_XEN=y
##
## file: drivers/mmc/Kconfig
##
CONFIG_MMC=y
##
## file: drivers/mmc/host/Kconfig
##
CONFIG_MMC_ARMMMCI=m
CONFIG_MMC_SPI=m
##
## file: drivers/net/ethernet/8390/Kconfig
##
CONFIG_NET_VENDOR_8390=y
CONFIG_NE2K_PCI=m
##
## file: drivers/net/ethernet/realtek/Kconfig
##
CONFIG_8139CP=m
CONFIG_8139TOO=m
# CONFIG_8139TOO_PIO is not set
CONFIG_8139TOO_TUNE_TWISTER=y
CONFIG_8139TOO_8129=y
# CONFIG_8139_OLD_RX_RESET is not set
##
## file: drivers/net/ethernet/smsc/Kconfig
##
CONFIG_NET_VENDOR_SMSC=y
CONFIG_SMC91X=m
CONFIG_SMSC911X=m
##
## file: drivers/power/reset/Kconfig
##
CONFIG_POWER_RESET_VEXPRESS=y
CONFIG_POWER_RESET_XGENE=y
##
## file: drivers/tty/serial/Kconfig
##
CONFIG_SERIAL_AMBA_PL010=y
CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y
##
## file: drivers/tty/serial/8250/Kconfig
##
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
CONFIG_SERIAL_8250_DW=y
# CONFIG_SERIAL_8250_EM is not set
##
## file: drivers/virtio/Kconfig
##
CONFIG_VIRTIO_MMIO=m

View File

@ -1,4 +1,16 @@
[base]
kernel-arch: arm64
featuresets:
# empty; we don't have initramfs working yet
none
[build]
debug-info: true
image-file: arch/arm64/boot/Image
[image]
install-stem: vmlinuz
[arm64_description]
hardware: 64-bit ARMv8 machines
[arm64_image]

3
debian/config/arm64/none/defines vendored Normal file
View File

@ -0,0 +1,3 @@
[base]
flavours:
arm64

View File

@ -0,0 +1,2 @@
# arch version flavour installedname suffix build-depends
arm64 - arm64 - - -

View File

@ -0,0 +1 @@
libata

View File

@ -0,0 +1 @@
#include <btrfs-modules>

View File

@ -0,0 +1 @@
#include <core-modules>

View File

@ -0,0 +1 @@
#include <crc-modules>

View File

@ -0,0 +1 @@
#include <crypto-dm-modules>

View File

@ -0,0 +1 @@
#include <crypto-modules>

View File

@ -0,0 +1 @@
#include <event-modules>

View File

@ -0,0 +1 @@
#include <ext4-modules>

View File

@ -0,0 +1 @@
#include <fat-modules>

View File

@ -0,0 +1 @@
#include <fuse-modules>

View File

@ -0,0 +1 @@
#include <input-modules>

View File

@ -0,0 +1 @@
#include <isofs-modules>

View File

@ -0,0 +1 @@
#include <jfs-modules>

View File

@ -0,0 +1 @@
# empty

View File

@ -0,0 +1 @@
#include <loop-modules>

View File

@ -0,0 +1 @@
#include <md-modules>

View File

@ -0,0 +1 @@
#include <mmc-modules>

View File

@ -0,0 +1 @@
#include <multipath-modules>

View File

@ -0,0 +1 @@
#include <nbd-modules>

View File

@ -0,0 +1,3 @@
#include <nic-modules>
smc91x
smsc911x

View File

@ -0,0 +1 @@
#include <nic-shared-modules>

View File

@ -0,0 +1 @@
#include <nic-usb-modules>

View File

@ -0,0 +1 @@
#include <nic-wireless-modules>

View File

@ -0,0 +1 @@
#include <ppp-modules>

View File

@ -0,0 +1 @@
#include <sata-modules>

View File

@ -0,0 +1 @@
#include <scsi-core-modules>

View File

@ -0,0 +1,2 @@
#include <scsi-modules>

View File

@ -0,0 +1 @@
#include <squashfs-modules>

View File

@ -0,0 +1 @@
#include <udf-modules>

View File

@ -0,0 +1 @@
#include <uinput-modules>

View File

@ -0,0 +1 @@
#include <usb-modules>

View File

@ -0,0 +1,2 @@
#include <usb-storage-modules>
usb-storage -

View File

@ -0,0 +1 @@
#include <virtio-modules>

View File

@ -0,0 +1 @@
#include <zlib-modules>

7
debian/installer/arm64/package-list vendored Normal file
View File

@ -0,0 +1,7 @@
# This file is used to build up the control file. The kernel version and
# "-di" are appended to the package names. Section can be left out. So can
# architecture, which is derived from the files in the modules directory.
# It overwrites specifications from /usr/share/kernel-wedge/package-list.
#
Package: kernel-image

View File

@ -0,0 +1 @@
#include <virtio-modules>

View File

@ -1,78 +0,0 @@
From: Mathias Krause <minipli@googlemail.com>
Date: Sun, 13 Apr 2014 18:23:33 +0200
Subject: filter: prevent nla extensions to peek beyond the end of the message
Origin: https://git.kernel.org/linus/05ab8f2647e4221cbdb3856dd7d32bd5407316b3
The BPF_S_ANC_NLATTR and BPF_S_ANC_NLATTR_NEST extensions fail to check
for a minimal message length before testing the supplied offset to be
within the bounds of the message. This allows the subtraction of the nla
header to underflow and therefore -- as the data type is unsigned --
allowing far to big offset and length values for the search of the
netlink attribute.
The remainder calculation for the BPF_S_ANC_NLATTR_NEST extension is
also wrong. It has the minuend and subtrahend mixed up, therefore
calculates a huge length value, allowing to overrun the end of the
message while looking for the netlink attribute.
The following three BPF snippets will trigger the bugs when attached to
a UNIX datagram socket and parsing a message with length 1, 2 or 3.
,-[ PoC for missing size check in BPF_S_ANC_NLATTR ]--
| ld #0x87654321
| ldx #42
| ld #nla
| ret a
`---
,-[ PoC for the same bug in BPF_S_ANC_NLATTR_NEST ]--
| ld #0x87654321
| ldx #42
| ld #nlan
| ret a
`---
,-[ PoC for wrong remainder calculation in BPF_S_ANC_NLATTR_NEST ]--
| ; (needs a fake netlink header at offset 0)
| ld #0
| ldx #42
| ld #nlan
| ret a
`---
Fix the first issue by ensuring the message length fulfills the minimal
size constrains of a nla header. Fix the second bug by getting the math
for the remainder calculation right.
Fixes: 4738c1db15 ("[SKFILTER]: Add SKF_ADF_NLATTR instruction")
Fixes: d214c7537b ("filter: add SKF_AD_NLATTR_NEST to look for nested..")
Cc: Patrick McHardy <kaber@trash.net>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Mathias Krause <minipli@googlemail.com>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.14: This code is all in sk_run_filter(), not
separate functions]
---
net/core/filter.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -371,11 +371,15 @@ load_b:
if (skb_is_nonlinear(skb))
return 0;
+ if (skb->len < sizeof(struct nlattr))
+ return 0;
+ if (skb->len < sizeof(struct nlattr))
+ return 0;
if (A > skb->len - sizeof(struct nlattr))
return 0;
nla = (struct nlattr *)&skb->data[A];
- if (nla->nla_len > A - skb->len)
+ if (nla->nla_len > skb->len - A)
return 0;
nla = nla_find_nested(nla, X);

View File

@ -0,0 +1,131 @@
Return-Path: <tglx@linutronix.de>
Received: from Galois.linutronix.de (Galois.linutronix.de
[IPv6:2001:470:1f0b:db:abcd:42:0:1]) by vinyl.outflux.net
(8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id s53CRBS5010805
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for
<kees@outflux.net>; Tue, 3 Jun 2014 05:27:17 -0700
Received: from localhost ([127.0.0.1] helo=[127.0.1.1]) by
Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from
<tglx@linutronix.de>) id 1Wrno4-0002Sb-9g; Tue, 03 Jun 2014 14:27:08 +0200
Message-Id: <20140603121944.949737592@linutronix.de>
User-Agent: quilt/0.63-1
Date: Tue, 03 Jun 2014 12:27:07 -0000
From: Thomas Gleixner <tglx@linutronix.de>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Darren Hart <dvhart@linux.intel.com>, Kees Cook <kees@outflux.net>,
"security@kernel.org" <security@kernel.org>, linux-distros@vs.openwall.org,
Sebastian Krahmer <krahmer@suse.de>, Ingo Molnar <mingo@kernel.org>, Kees
Cook <keescook@chromium.org>, Will Drewry <wad@chromium.org>
Subject: [patch 3/4] futex: Always cleanup owner tid in unlock_pi
References: <20140603113303.799564413@linutronix.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Disposition: inline; filename=futex-cleanup-owner-tid-on-unlock.patch
X-Linutronix-Spam-Score: -1.0
X-Linutronix-Spam-Level: -
X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required,
ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001
Received-SPF: none (linutronix.de: No applicable sender policy available)
receiver=smtp.outflux.net; identity=mailfrom;
envelope-from="tglx@linutronix.de"; helo=Galois.linutronix.de;
client-ip="2001:470:1f0b:db:abcd:42:0:1"
Envelope-To: kees@outflux.net
X-MIMEDefang-Filter: outflux$Revision: 1.316 $
X-HELO: Galois.linutronix.de
X-Spam-Status: No, hits=-0.651 required=5 tests=RP_MATCHES_RCVD
X-Spam-Checker-Version: SpamAssassin 3.4.0-outflux_revision__1.66__
X-Scanned-By: MIMEDefang 2.73
Content-Length: 2854
Lines: 93
If the owner died bit is set at futex_unlock_pi, we currently do not
cleanup the user space futex. So the owner TID of the current owner
(the unlocker) persists. That's observable inconsistant state,
especially when the ownership of the pi state got transferred.
Clean it up unconditionally.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Drewry <wad@chromium.org>
Cc: Darren Hart <dvhart@linux.intel.com>
Cc: stable@vger.kernel.org
---
kernel/futex.c | 44 ++++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 24 deletions(-)
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1038,6 +1038,7 @@ static int wake_futex_pi(u32 __user *uad
struct task_struct *new_owner;
struct futex_pi_state *pi_state = this->pi_state;
u32 uninitialized_var(curval), newval;
+ int ret = 0;
if (!pi_state)
return -EINVAL;
@@ -1061,23 +1062,19 @@ static int wake_futex_pi(u32 __user *uad
new_owner = this->task;
/*
- * We pass it to the next owner. (The WAITERS bit is always
- * kept enabled while there is PI state around. We must also
- * preserve the owner died bit.)
- */
- if (!(uval & FUTEX_OWNER_DIED)) {
- int ret = 0;
-
- newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
-
- if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
- ret = -EFAULT;
- else if (curval != uval)
- ret = -EINVAL;
- if (ret) {
- raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
- return ret;
- }
+ * We pass it to the next owner. The WAITERS bit is always
+ * kept enabled while there is PI state around. We cleanup the
+ * owner died bit, because we are the owner.
+ */
+ newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
+
+ if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))
+ ret = -EFAULT;
+ else if (curval != uval)
+ ret = -EINVAL;
+ if (ret) {
+ raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
+ return ret;
}
raw_spin_lock_irq(&pi_state->owner->pi_lock);
@@ -2337,9 +2334,10 @@ retry:
/*
* To avoid races, try to do the TID -> 0 atomic transition
* again. If it succeeds then we can return without waking
- * anyone else up:
+ * anyone else up. We only try this if neither the waiters nor
+ * the owner died bit are set.
*/
- if (!(uval & FUTEX_OWNER_DIED) &&
+ if (!(uval & ~FUTEX_TID_MASK) &&
cmpxchg_futex_value_locked(&uval, uaddr, vpid, 0))
goto pi_faulted;
/*
@@ -2369,11 +2367,9 @@ retry:
/*
* No waiters - kernel unlocks the futex:
*/
- if (!(uval & FUTEX_OWNER_DIED)) {
- ret = unlock_futex_pi(uaddr, uval);
- if (ret == -EFAULT)
- goto pi_faulted;
- }
+ ret = unlock_futex_pi(uaddr, uval);
+ if (ret == -EFAULT)
+ goto pi_faulted;
out_unlock:
spin_unlock(&hb->lock);

View File

@ -0,0 +1,309 @@
Return-Path: <tglx@linutronix.de>
Received: from Galois.linutronix.de (Galois.linutronix.de
[IPv6:2001:470:1f0b:db:abcd:42:0:1]) by vinyl.outflux.net
(8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id s53CRPJj010831
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for
<kees@outflux.net>; Tue, 3 Jun 2014 05:27:31 -0700
Received: from localhost ([127.0.0.1] helo=[127.0.1.1]) by
Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from
<tglx@linutronix.de>) id 1Wrno5-0002Se-1m; Tue, 03 Jun 2014 14:27:09 +0200
Message-Id: <20140603121945.039282525@linutronix.de>
User-Agent: quilt/0.63-1
Date: Tue, 03 Jun 2014 12:27:08 -0000
From: Thomas Gleixner <tglx@linutronix.de>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Darren Hart <dvhart@linux.intel.com>, Kees Cook <kees@outflux.net>,
"security@kernel.org" <security@kernel.org>, linux-distros@vs.openwall.org,
Sebastian Krahmer <krahmer@suse.de>, Ingo Molnar <mingo@kernel.org>, Kees
Cook <keescook@chromium.org>, Will Drewry <wad@chromium.org>
Subject: [patch 4/4] futex: Make lookup_pi_state more robust
References: <20140603113303.799564413@linutronix.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Disposition: inline; filename=futex-make-lookup-pi-state-more-robust.patch
X-Linutronix-Spam-Score: -1.0
X-Linutronix-Spam-Level: -
X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required,
ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001
Received-SPF: none (linutronix.de: No applicable sender policy available)
receiver=smtp.outflux.net; identity=mailfrom;
envelope-from="tglx@linutronix.de"; helo=Galois.linutronix.de;
client-ip="2001:470:1f0b:db:abcd:42:0:1"
Envelope-To: kees@outflux.net
X-MIMEDefang-Filter: outflux$Revision: 1.316 $
X-HELO: Galois.linutronix.de
X-Spam-Status: No, hits=-0.651 required=5 tests=RP_MATCHES_RCVD
X-Spam-Checker-Version: SpamAssassin 3.4.0-outflux_revision__1.66__
X-Scanned-By: MIMEDefang 2.73
Status: RO
Content-Length: 8955
Lines: 270
The current implementation of lookup_pi_state has ambigous handling of
the TID value 0 in the user space futex. We can get into the kernel
even if the TID value is 0, because either there is a stale waiters
bit or the owner died bit is set or we are called from the requeue_pi
path or from user space just for fun.
The current code avoids an explicit sanity check for pid = 0 in case
that kernel internal state (waiters) are found for the user space
address. This can lead to state leakage and worse under some
circumstances.
Handle the cases explicit:
Waiter | pi_state | pi->owner | uTID | uODIED | ?
[1] NULL | --- | --- | 0 | 0/1 | Valid
[2] NULL | --- | --- | >0 | 0/1 | Valid
[3] Found | NULL | -- | Any | 0/1 | Invalid
[4] Found | Found | NULL | 0 | 1 | Valid
[5] Found | Found | NULL | >0 | 1 | Invalid
[6] Found | Found | task | 0 | 1 | Valid
[7] Found | Found | NULL | Any | 0 | Invalid
[8] Found | Found | task | ==taskTID | 0/1 | Valid
[9] Found | Found | task | 0 | 0 | Invalid
[10] Found | Found | task | !=taskTID | 0/1 | Invalid
[1] Indicates that the kernel can acquire the futex atomically. We
came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
[2] Valid, if TID does not belong to a kernel thread. If no matching
thread is found then it indicates that the owner TID has died.
[3] Invalid. The waiter is queued on a non PI futex
[4] Valid state after exit_robust_list(), which sets the user space
value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
[5] The user space value got manipulated between exit_robust_list()
and exit_pi_state_list()
[6] Valid state after exit_pi_state_list() which sets the new owner in
the pi_state but cannot access the user space value.
[7] pi_state->owner can only be NULL when the OWNER_DIED bit is set.
[8] Owner and user space value match
[9] There is no transient state which sets the user space TID to 0
except exit_robust_list(), but this is indicated by the
FUTEX_OWNER_DIED bit. See [4]
[10] There is no transient state which leaves owner and user space
TID out of sync.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Drewry <wad@chromium.org>
Cc: Darren Hart <dvhart@linux.intel.com>
Cc: stable@vger.kernel.org
---
kernel/futex.c | 134 +++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 106 insertions(+), 28 deletions(-)
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -729,10 +729,58 @@ void exit_pi_state_list(struct task_stru
raw_spin_unlock_irq(&curr->pi_lock);
}
+/*
+ * We need to check the following states:
+ *
+ * Waiter | pi_state | pi->owner | uTID | uODIED | ?
+ *
+ * [1] NULL | --- | --- | 0 | 0/1 | Valid
+ * [2] NULL | --- | --- | >0 | 0/1 | Valid
+ *
+ * [3] Found | NULL | -- | Any | 0/1 | Invalid
+ *
+ * [4] Found | Found | NULL | 0 | 1 | Valid
+ * [5] Found | Found | NULL | >0 | 1 | Invalid
+ *
+ * [6] Found | Found | task | 0 | 1 | Valid
+ *
+ * [7] Found | Found | NULL | Any | 0 | Invalid
+ *
+ * [8] Found | Found | task | ==taskTID | 0/1 | Valid
+ * [9] Found | Found | task | 0 | 0 | Invalid
+ * [10] Found | Found | task | !=taskTID | 0/1 | Invalid
+ *
+ * [1] Indicates that the kernel can acquire the futex atomically. We
+ * came came here due to a stale FUTEX_WAITERS/FUTEX_OWNER_DIED bit.
+ *
+ * [2] Valid, if TID does not belong to a kernel thread. If no matching
+ * thread is found then it indicates that the owner TID has died.
+ *
+ * [3] Invalid. The waiter is queued on a non PI futex
+ *
+ * [4] Valid state after exit_robust_list(), which sets the user space
+ * value to FUTEX_WAITERS | FUTEX_OWNER_DIED.
+ *
+ * [5] The user space value got manipulated between exit_robust_list()
+ * and exit_pi_state_list()
+ *
+ * [6] Valid state after exit_pi_state_list() which sets the new owner in
+ * the pi_state but cannot access the user space value.
+ *
+ * [7] pi_state->owner can only be NULL when the OWNER_DIED bit is set.
+ *
+ * [8] Owner and user space value match
+ *
+ * [9] There is no transient state which sets the user space TID to 0
+ * except exit_robust_list(), but this is indicated by the
+ * FUTEX_OWNER_DIED bit. See [4]
+ *
+ * [10] There is no transient state which leaves owner and user space
+ * TID out of sync.
+ */
static int
lookup_pi_state(u32 uval, struct futex_hash_bucket *hb,
- union futex_key *key, struct futex_pi_state **ps,
- struct task_struct *task)
+ union futex_key *key, struct futex_pi_state **ps)
{
struct futex_pi_state *pi_state = NULL;
struct futex_q *this, *next;
@@ -742,12 +790,13 @@ lookup_pi_state(u32 uval, struct futex_h
plist_for_each_entry_safe(this, next, &hb->chain, list) {
if (match_futex(&this->key, key)) {
/*
- * Another waiter already exists - bump up
- * the refcount and return its pi_state:
+ * Sanity check the waiter before increasing
+ * the refcount and attaching to it.
*/
pi_state = this->pi_state;
/*
- * Userspace might have messed up non-PI and PI futexes
+ * Userspace might have messed up non-PI and
+ * PI futexes [3]
*/
if (unlikely(!pi_state))
return -EINVAL;
@@ -755,44 +804,70 @@ lookup_pi_state(u32 uval, struct futex_h
WARN_ON(!atomic_read(&pi_state->refcount));
/*
- * When pi_state->owner is NULL then the owner died
- * and another waiter is on the fly. pi_state->owner
- * is fixed up by the task which acquires
- * pi_state->rt_mutex.
- *
- * We do not check for pid == 0 which can happen when
- * the owner died and robust_list_exit() cleared the
- * TID.
+ * Handle the owner died case:
*/
- if (pid && pi_state->owner) {
+ if (uval & FUTEX_OWNER_DIED) {
/*
- * Bail out if user space manipulated the
- * futex value.
+ * exit_pi_state_list sets owner to NULL and
+ * wakes the topmost waiter. The task which
+ * acquires the pi_state->rt_mutex will fixup
+ * owner.
*/
- if (pid != task_pid_vnr(pi_state->owner))
+ if (!pi_state->owner) {
+ /*
+ * No pi state owner, but the user
+ * space TID is not 0. Inconsistent
+ * state. [5]
+ */
+ if (pid)
+ return -EINVAL;
+ /*
+ * Take a ref on the state and
+ * return. [4]
+ */
+ goto out_state;
+ }
+
+ /*
+ * If TID is 0, then either the dying owner
+ * has not yet executed exit_pi_state_list()
+ * or some waiter acquired the rtmutex in the
+ * pi state, but did not yet fixup the TID in
+ * user space.
+ *
+ * Take a ref on the state and return. [6]
+ */
+ if (!pid)
+ goto out_state;
+ } else {
+ /*
+ * If the owner died bit is not set,
+ * then the pi_state must have an
+ * owner. [7]
+ */
+ if (!pi_state->owner)
return -EINVAL;
}
/*
- * Protect against a corrupted uval. If uval
- * is 0x80000000 then pid is 0 and the waiter
- * bit is set. So the deadlock check in the
- * calling code has failed and we did not fall
- * into the check above due to !pid.
+ * Bail out if user space manipulated the
+ * futex value. If pi state exists then the
+ * owner TID must be the same as the user
+ * space TID. [9/10]
*/
- if (task && pi_state->owner == task)
- return -EDEADLK;
+ if (pid != task_pid_vnr(pi_state->owner))
+ return -EINVAL;
+ out_state:
atomic_inc(&pi_state->refcount);
*ps = pi_state;
-
return 0;
}
}
/*
* We are the first waiter - try to look up the real owner and attach
- * the new pi_state to it, but bail out when TID = 0
+ * the new pi_state to it, but bail out when TID = 0 [1]
*/
if (!pid)
return -ESRCH;
@@ -825,6 +900,9 @@ lookup_pi_state(u32 uval, struct futex_h
return ret;
}
+ /*
+ * No existing pi state. First waiter. [2]
+ */
pi_state = alloc_pi_state();
/*
@@ -945,7 +1023,7 @@ retry:
* We dont have the lock. Look up the PI state (or create it if
* we are the first waiter):
*/
- ret = lookup_pi_state(uval, hb, key, ps, task);
+ ret = lookup_pi_state(uval, hb, key, ps);
if (unlikely(ret)) {
switch (ret) {
@@ -1551,7 +1629,7 @@ retry_private:
* rereading and handing potential crap to
* lookup_pi_state.
*/
- ret = lookup_pi_state(ret, hb2, &key2, &pi_state, NULL);
+ ret = lookup_pi_state(ret, hb2, &key2, &pi_state);
}
switch (ret) {

View File

@ -0,0 +1,86 @@
Return-Path: <tglx@linutronix.de>
Received: from Galois.linutronix.de (Galois.linutronix.de
[IPv6:2001:470:1f0b:db:abcd:42:0:1]) by vinyl.outflux.net
(8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id s53CRBqO010803
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for
<kees@outflux.net>; Tue, 3 Jun 2014 05:27:17 -0700
Received: from localhost ([127.0.0.1] helo=[127.0.1.1]) by
Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from
<tglx@linutronix.de>) id 1Wrno3-0002SY-Hl; Tue, 03 Jun 2014 14:27:07 +0200
Message-Id: <20140603121944.859726103@linutronix.de>
User-Agent: quilt/0.63-1
Date: Tue, 03 Jun 2014 12:27:06 -0000
From: Thomas Gleixner <tglx@linutronix.de>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Darren Hart <dvhart@linux.intel.com>, Kees Cook <kees@outflux.net>,
"security@kernel.org" <security@kernel.org>, linux-distros@vs.openwall.org,
Sebastian Krahmer <krahmer@suse.de>, Ingo Molnar <mingo@kernel.org>, Kees
Cook <keescook@chromium.org>, Will Drewry <wad@chromium.org>
Subject: [patch 2/4] futex: Validate atomic acquisition in
futex_lock_pi_atomic()
References: <20140603113303.799564413@linutronix.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Disposition: inline; filename=futex-validate-atomic-acquisiton.patch
X-Linutronix-Spam-Score: -1.0
X-Linutronix-Spam-Level: -
X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required,
ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001
Received-SPF: none (linutronix.de: No applicable sender policy available)
receiver=smtp.outflux.net; identity=mailfrom;
envelope-from="tglx@linutronix.de"; helo=Galois.linutronix.de;
client-ip="2001:470:1f0b:db:abcd:42:0:1"
Envelope-To: kees@outflux.net
X-MIMEDefang-Filter: outflux$Revision: 1.316 $
X-HELO: Galois.linutronix.de
X-Spam-Status: No, hits=-0.651 required=5 tests=RP_MATCHES_RCVD
X-Spam-Checker-Version: SpamAssassin 3.4.0-outflux_revision__1.66__
X-Scanned-By: MIMEDefang 2.73
Content-Length: 1615
Lines: 47
We need to protect the atomic acquisition in the kernel against rogue
user space which sets the user space futex to 0, so the kernel side
acquisition succeeds while there is existing state in the kernel
associated to the real owner.
Verify whether the futex has waiters associated with kernel state. If
it has, return -EINVAL. The state is corrupted already, so no point in
cleaning it up. Subsequent calls will fail as well. Not our problem.
[ tglx: Use futex_top_waiter() and explain why we do not need to try
restoring the already corrupted user space state. ]
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Drewry <wad@chromium.org>
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/futex.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -896,10 +896,18 @@ retry:
return -EDEADLK;
/*
- * Surprise - we got the lock. Just return to userspace:
+ * Surprise - we got the lock, but we do not trust user space at all.
*/
- if (unlikely(!curval))
- return 1;
+ if (unlikely(!curval)) {
+ /*
+ * We verify whether there is kernel state for this
+ * futex. If not, we can safely assume, that the 0 ->
+ * TID transition is correct. If state exists, we do
+ * not bother to fixup the user space state as it was
+ * corrupted already.
+ */
+ return futex_top_waiter(hb, key) ? -EINVAL : 1;
+ }
uval = curval;

View File

@ -0,0 +1,113 @@
Return-Path: <tglx@linutronix.de>
Received: from Galois.linutronix.de (Galois.linutronix.de
[IPv6:2001:470:1f0b:db:abcd:42:0:1]) by vinyl.outflux.net
(8.14.4/8.14.4/Debian-4.1ubuntu1) with ESMTP id s53CRBLI010804
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for
<kees@outflux.net>; Tue, 3 Jun 2014 05:27:17 -0700
Received: from localhost ([127.0.0.1] helo=[127.0.1.1]) by
Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from
<tglx@linutronix.de>) id 1Wrno2-0002SV-Po; Tue, 03 Jun 2014 14:27:06 +0200
Message-Id: <20140603121944.770732571@linutronix.de>
User-Agent: quilt/0.63-1
Date: Tue, 03 Jun 2014 12:27:06 -0000
From: Thomas Gleixner <tglx@linutronix.de>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Darren Hart <dvhart@linux.intel.com>, Kees Cook <kees@outflux.net>,
"security@kernel.org" <security@kernel.org>, linux-distros@vs.openwall.org,
Sebastian Krahmer <krahmer@suse.de>, Ingo Molnar <mingo@kernel.org>, Will
Drewry <wad@chromium.org>, Kees Cook <keescook@chromium.org>
Subject: [patch 1/4] futex-prevent-requeue-pi-on-same-futex.patch futex:
Forbid uaddr == uaddr2 in futex_requeue(..., requeue_pi=1)
References: <20140603113303.799564413@linutronix.de>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Disposition: inline; filename=futex-prevent-requeue-pi-on-same-futex.patch
X-Linutronix-Spam-Score: -1.0
X-Linutronix-Spam-Level: -
X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required,
ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001
Received-SPF: none (linutronix.de: No applicable sender policy available)
receiver=smtp.outflux.net; identity=mailfrom;
envelope-from="tglx@linutronix.de"; helo=Galois.linutronix.de;
client-ip="2001:470:1f0b:db:abcd:42:0:1"
Envelope-To: kees@outflux.net
X-MIMEDefang-Filter: outflux$Revision: 1.316 $
X-HELO: Galois.linutronix.de
X-Spam-Status: No, hits=-0.651 required=5 tests=RP_MATCHES_RCVD
X-Spam-Checker-Version: SpamAssassin 3.4.0-outflux_revision__1.66__
X-Scanned-By: MIMEDefang 2.73
Status: RO
Content-Length: 2114
Lines: 73
If uaddr == uaddr2, then we have broken the rule of only requeueing
from a non-pi futex to a pi futex with this call. If we attempt this,
then dangling pointers may be left for rt_waiter resulting in an
exploitable condition.
This change brings futex_requeue() into line with
futex_wait_requeue_pi() which performs the same check as per commit
6f7b0a2a5 (futex: Forbid uaddr == uaddr2 in futex_wait_requeue_pi())
[ tglx: Compare the resulting keys as well, as uaddrs might be
different depending on the mapping ]
Fixes CVE-2014-3153.
Reported-by: Pinkie Pie
Signed-off-by: Will Drewry <wad@chromium.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/futex.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1428,6 +1428,13 @@ static int futex_requeue(u32 __user *uad
if (requeue_pi) {
/*
+ * Requeue PI only works on two distinct uaddrs. This
+ * check is only valid for private futexes. See below.
+ */
+ if (uaddr1 == uaddr2)
+ return -EINVAL;
+
+ /*
* requeue_pi requires a pi_state, try to allocate it now
* without any locks in case it fails.
*/
@@ -1465,6 +1472,15 @@ retry:
if (unlikely(ret != 0))
goto out_put_key1;
+ /*
+ * The check above which compares uaddrs is not sufficient for
+ * shared futexes. We need to compare the keys:
+ */
+ if (requeue_pi && match_futex(&key1, &key2)) {
+ ret = -EINVAL;
+ goto out_put_keys;
+ }
+
hb1 = hash_futex(&key1);
hb2 = hash_futex(&key2);
@@ -2511,6 +2527,15 @@ static int futex_wait_requeue_pi(u32 __u
if (ret)
goto out_key2;
+ /*
+ * The check above which compares uaddrs is not sufficient for
+ * shared futexes. We need to compare the keys:
+ */
+ if (match_futex(&q.key, &key2)) {
+ ret = -EINVAL;
+ goto out_put_keys;
+ }
+
/* Queue the futex_q, drop the hb lock, wait for wakeup. */
futex_wait_queue_me(hb, &q, to);

View File

@ -1,40 +0,0 @@
From: Vlad Yasevich <vyasevic@redhat.com>
Date: Mon, 14 Apr 2014 17:37:26 -0400
Subject: net: Start with correct mac_len in skb_network_protocol
Origin: https://git.kernel.org/linus/1e785f48d29a09b6cf96db7b49b6320dada332e1
Sometimes, when the packet arrives at skb_mac_gso_segment()
its skb->mac_len already accounts for some of the mac lenght
headers in the packet. This seems to happen when forwarding
through and OpenSSL tunnel.
When we start looking for any vlan headers in skb_network_protocol()
we seem to ignore any of the already known mac headers and start
with an ETH_HLEN. This results in an incorrect offset, dropped
TSO frames and general slowness of the connection.
We can start counting from the known skb->mac_len
and return at least that much if all mac level headers
are known and accounted for.
Fixes: 53d6471cef17262d3ad1c7ce8982a234244f68ec (net: Account for all vlan headers in skb_mac_gso_segment)
CC: Eric Dumazet <eric.dumazet@gmail.com>
CC: Daniel Borkman <dborkman@redhat.com>
Tested-by: Martin Filip <nexus+kernel@smoula.net>
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/core/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2289,7 +2289,7 @@ EXPORT_SYMBOL(skb_checksum_help);
__be16 skb_network_protocol(struct sk_buff *skb, int *depth)
{
__be16 type = skb->protocol;
- int vlan_depth = ETH_HLEN;
+ int vlan_depth = skb->mac_len;
/* Tunnel gso handlers can set protocol to ethernet. */
if (type == htons(ETH_P_TEB)) {

View File

@ -1,61 +0,0 @@
From: "Wang, Xiaoming" <xiaoming.wang@intel.com>
Date: Mon, 14 Apr 2014 12:30:45 -0400
Subject: net: ipv4: current group_info should be put after using.
Origin: https://git.kernel.org/linus/b04c46190219a4f845e46a459e3102137b7f6cac
Plug a group_info refcount leak in ping_init.
group_info is only needed during initialization and
the code failed to release the reference on exit.
While here move grabbing the reference to a place
where it is actually needed.
Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com>
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/ipv4/ping.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5..8210964 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk)
{
struct net *net = sock_net(sk);
kgid_t group = current_egid();
- struct group_info *group_info = get_current_groups();
- int i, j, count = group_info->ngroups;
+ struct group_info *group_info;
+ int i, j, count;
kgid_t low, high;
+ int ret = 0;
inet_get_ping_group_range_net(net, &low, &high);
if (gid_lte(low, group) && gid_lte(group, high))
return 0;
+ group_info = get_current_groups();
+ count = group_info->ngroups;
for (i = 0; i < group_info->nblocks; i++) {
int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
for (j = 0; j < cp_count; j++) {
kgid_t gid = group_info->blocks[i][j];
if (gid_lte(low, gid) && gid_lte(gid, high))
- return 0;
+ goto out_release_group;
}
count -= cp_count;
}
- return -EACCES;
+ ret = -EACCES;
+
+out_release_group:
+ put_group_info(group_info);
+ return ret;
}
EXPORT_SYMBOL_GPL(ping_init_sock);

View File

@ -94,3 +94,8 @@ features/arm/ARM-dts-sun5i-Add-reg_vcc3v3-to-sun5i-board-mmc-node.patch
features/arm/ARM-dts-sun6i-Add-reg_vcc3v3-to-sun6i-board-mmc-node.patch
features/arm/ARM-dts-sun7i-Add-reg_vcc3v3-to-sun7i-board-mmc-node.patch
features/arm/ARM-dts-sun7i-cubietruck-set-mmc3-bus-width-property.patch
bugfix/all/futex-prevent-requeue-pi-on-same-futex.patch
bugfix/all/futex-Validate-atomic-acquisition-in-futex_lock_pi_atomic.patch
bugfix/all/futex-Always-cleanup-owner-tid-in-unlock_pi.patch
bugfix/all/futex-Make-lookup_pi_state-more-robust.patch

2
debian/rules.real vendored
View File

@ -373,7 +373,7 @@ endif
install-image_$(ARCH)_$(FEATURESET)_$(FLAVOUR)_plain_dt: DT_INSTALL_DIR = $(PACKAGE_DIR)/usr/lib/linux-image-$(REAL_VERSION)
install-image_$(ARCH)_$(FEATURESET)_$(FLAVOUR)_plain_dt:
ifneq ($(filter armel armhf,$(ARCH)),)
ifneq ($(filter arm64 armel armhf,$(ARCH)),)
+$(MAKE_CLEAN) -C $(DIR) dtbs
shopt -s nullglob ; for i in $(DIR)/arch/$(KERNEL_ARCH)/boot/dts/*.dtb ; do \
install -D -m644 $$i '$(DT_INSTALL_DIR)'/$$(basename $$i) ; \