2016-04-22 11:05:53

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 00/78] 3.12.59-stable review

This is the start of the stable review cycle for the 3.12.59 release.
There are 78 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 Tue Apr 26 13:05:33 CEST 2016.
Anything received after that time might be too late.

The whole patch series can be found in one patch at:
http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.59-rc1.xz
and the diffstat can be found below.

thanks,
js

===============


Alan Stern (1):
HID: usbhid: fix inconsistent reset/resume/reset-resume behavior

Aleksander Morgado (3):
net: qmi_wwan: add Netgear AirCard 341U
net: qmi_wwan: add additional Sierra Wireless QMI devices
net: qmi_wwan: interface #11 in Sierra Wireless MC73xx is not QMI

Alex Deucher (2):
drm/radeon: add a dpm quirk for sapphire Dual-X R7 370 2G D5
drm/radeon: add a dpm quirk for all R7 370 parts

Alexey Khoroshilov (1):
usbvision: fix leak of usb_dev on failure paths in usbvision_probe()

Andrew Honig (1):
KVM: x86: Reload pit counters for all channels when restoring state

Arnaldo Carvalho de Melo (1):
net: Fix use after free in the recvmmsg exit path

Arnd Bergmann (3):
mlx4: add missing braces in verify_qp_parameters
farsync: fix off-by-one bug in fst_add_one
ath9k: fix buffer overrun for ar9287

Bernie Harris (1):
tunnel: Clear IPCB(skb)->opt before dst_link_failure called

Bill Sommerfeld (1):
udp6: fix UDP/IPv6 encap resubmit path

Bjørn Mork (7):
qmi_wwan: add "D-Link DWM-221 B1" device id
qmi_wwan: add Sierra Wireless MC74xx/EM74xx
net: qmi_wwan: remove 1199:9070 device id
qmi_wwan: add Sierra Wireless EM74xx device ID
cdc_ncm: toggle altsetting to force reset before setup
net: qmi_wwan: MDM9x30 specific power management
cdc_ncm: do not call usbnet_link_change from cdc_ncm_bind

Boris Ostrovsky (1):
xen/events: Mask a moving irq

Chuck Lever (1):
SUNRPC: Fix large reads on NFS/RDMA

David Howells (1):
KEYS: Fix handling of stored error in a negatively instantiated user
key

David Rientjes (1):
fs, seq_file: fallback to vmalloc instead of oom kill processes

David Ward (2):
net: qmi_wwan: add HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module
net: qmi_wwan: Sierra Wireless MC73xx -> Sierra Wireless MC7304/MC7354

Diego Viola (1):
net: jme: fix suspend/resume on JMC260

Dmitri Epshtein (1):
net: mvneta: enable change MAC address when interface is up

Dmitry Monakhov (1):
fs/pipe.c: skip file_update_time on frozen fs

Eric W. Biederman (1):
mnt: Move the clear of MNT_LOCKED from copy_tree to it's callers.

Eryu Guan (1):
ext4: fix NULL pointer dereference in ext4_mark_inode_dirty()

Felipe F. Tonello (1):
usb: gadget: f_midi: Fixed a bug when buflen was smaller than
wMaxPacketSize

Florian Westphal (3):
ipv6: re-enable fragment header matching in ipv6_find_hdr
netfilter: x_tables: validate e->target_offset early
netfilter: x_tables: fix unconditional helper

Greg Thelen (1):
fs, seqfile: always allow oom killer

Guenter Roeck (1):
hwmon: (max1111) Return -ENODEV from max1111_read_channel if not
instantiated

Guillaume Nault (1):
ppp: take reference on channels netns

Guo-Fu Tseng (2):
jme: Do not enable NIC WoL functions on S0
jme: Fix device PM wakeup API usage

Haishuang Yan (2):
ipv4: l2tp: fix a potential issue in l2tp_ip_recv
ipv6: l2tp: fix a potential issue in l2tp_ip6_recv

Helge Deller (2):
parisc: Avoid function pointers for kernel exception routines
parisc: Fix kernel crash with reversed copy_from_user()

Ignat Korchagin (1):
USB: usbip: fix potential out-of-bounds write

Jakub Sitnicki (1):
ipv6: Count in extension headers in skb->network_header

James Yonan (1):
crypto: crypto_memneq - add equality testing of memory regions w/o
timing leaks

Kristian Evensen (2):
net: qmi_wwan: Add WeTelecom-WPD600N
net: qmi_wwan: Add SIMCom 7230E

Manish Chopra (1):
qlge: Fix receive packets drop.

Michal Kazior (1):
mac80211: fix unnecessary frame drops in mesh fwding

Nicolai Hähnle (1):
drm/radeon: hold reference to fences in radeon_sa_bo_new (3.17 and
older)

Oliver Neukum (1):
usbnet: cleanup after bind() in probe()

Patrik Halfar (1):
Add Dell Wireless 5809e Gobi 4G HSPA+ Mobile Broadband Card (rev3) to
qmi_wwan

Peter Zijlstra (1):
perf: Cure event->pending_disable race

Petr Štetiar (1):
USB: qmi_wwan: Add quirk for Quectel EC20 Mini PCIe module

Pieter Hollants (1):
qmi_wwan: Add support for Dell Wireless 5809e 4G Modem

Reinhard Speyerer (1):
qmi_wwan: add the second QMI/network interface for Sierra Wireless
MC7305/MC7355

Romain Izard (1):
mmc: Allow forward compatibility for eMMC

Ryan Ware (1):
EVM: Use crypto_memneq() for digest comparisons

Saurabh Sengar (1):
KVM: x86: removing unused variable

Schemmel Hans-Christoph (1):
qmi_wwan: Added support for Gemalto's Cinterion PHxx WWAN interface

Sergei Shtylyov (1):
sh_eth: fix NULL pointer dereference in sh_eth_ring_format()

Takashi Iwai (2):
ALSA: timer: Use mod_timer() for rearming the system timer
ALSA: timer: Sync timer deletion at closing the system timer

Thadeu Lima de Souza Cascardo (1):
ip6_tunnel: set rtnl_link_ops before calling register_netdevice

Theodore Ts'o (1):
ext4: add lockdep annotations for i_data_sem

Vladis Dronov (1):
usbvision: fix crash on detecting device with invalid configuration

Wei Liu (1):
xen/events: introduce test_and_set_mask()

Willem de Bruijn (1):
macvtap: always pass ethernet header in linear

Willy Tarreau (1):
pipe: limit the per-user amount of pages allocated in pipes

Xin Long (1):
sctp: lack the check for ports in sctp_v6_cmp_addr

Xishi Qiu (1):
mm: fix invalid node in alloc_migrate_target()

Yegor Yefremov (1):
qmi_wwan/cdc_ether: move Novatel E371 (1410:9011) to qmi_wwan

Yoshihiro Shimoda (2):
usb: renesas_usbhs: avoid NULL pointer derefernce in
usbhsf_pkt_handler()
usb: renesas_usbhs: disable TX IRQ before starting TX DMAC transfer

[email protected] (1):
xfrm: Fix crash observed during device unregistration and decryption

Documentation/sysctl/fs.txt | 23 ++++
arch/parisc/kernel/parisc_ksyms.c | 10 +-
arch/parisc/kernel/traps.c | 3 +
arch/x86/kvm/x86.c | 24 ++--
crypto/Makefile | 7 +-
crypto/asymmetric_keys/rsa.c | 5 +-
crypto/authenc.c | 6 +-
crypto/authencesn.c | 8 +-
crypto/ccm.c | 4 +-
crypto/gcm.c | 2 +-
crypto/memneq.c | 138 +++++++++++++++++++++
drivers/gpu/drm/radeon/radeon_sa.c | 7 ++
drivers/gpu/drm/radeon/si_dpm.c | 5 +
drivers/hid/usbhid/hid-core.c | 73 +++++------
drivers/hwmon/max1111.c | 6 +
drivers/media/usb/usbvision/usbvision-video.c | 40 ++++--
drivers/mmc/core/mmc.c | 11 +-
drivers/net/ethernet/jme.c | 26 ++--
drivers/net/ethernet/marvell/mvneta.c | 2 +-
.../net/ethernet/mellanox/mlx4/resource_tracker.c | 3 +-
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 11 ++
drivers/net/ethernet/renesas/sh_eth.c | 3 +-
drivers/net/macvtap.c | 9 +-
drivers/net/ppp/ppp_generic.c | 4 +-
drivers/net/usb/cdc_ether.c | 7 ++
drivers/net/usb/cdc_ncm.c | 26 ++--
drivers/net/usb/qmi_wwan.c | 90 +++++++++++++-
drivers/net/usb/usbnet.c | 7 ++
drivers/net/wan/farsync.c | 2 +-
drivers/net/wireless/ath/ath9k/eeprom.c | 7 +-
drivers/staging/usbip/usbip_common.c | 11 ++
drivers/usb/gadget/f_midi.c | 4 +-
drivers/usb/renesas_usbhs/fifo.c | 4 +-
drivers/xen/events.c | 39 ++++--
fs/ext4/ext4.h | 23 ++++
fs/ext4/inode.c | 6 +-
fs/ext4/move_extent.c | 11 +-
fs/ext4/super.c | 25 +++-
fs/namespace.c | 1 -
fs/pipe.c | 50 +++++++-
fs/pnode.c | 1 +
fs/seq_file.c | 11 +-
include/crypto/algapi.h | 18 ++-
include/linux/pipe_fs_i.h | 4 +
include/linux/sched.h | 1 +
kernel/events/core.c | 6 +-
kernel/sysctl.c | 14 +++
mm/page_isolation.c | 8 +-
net/ipv4/ip_tunnel.c | 3 +-
net/ipv4/netfilter/arp_tables.c | 35 +++---
net/ipv4/netfilter/ip_tables.c | 40 +++---
net/ipv6/exthdrs_core.c | 6 +-
net/ipv6/ip6_gre.c | 2 +
net/ipv6/ip6_output.c | 9 +-
net/ipv6/ip6_tunnel.c | 4 +-
net/ipv6/netfilter/ip6_tables.c | 40 +++---
net/ipv6/udp.c | 6 +-
net/l2tp/l2tp_ip.c | 8 +-
net/l2tp/l2tp_ip6.c | 8 +-
net/mac80211/rx.c | 5 +-
net/sctp/ipv6.c | 2 +
net/socket.c | 38 +++---
net/sunrpc/xprtrdma/rpc_rdma.c | 4 +-
net/xfrm/xfrm_input.c | 3 +
security/integrity/evm/evm_main.c | 3 +-
security/keys/encrypted-keys/encrypted.c | 2 +
security/keys/trusted.c | 5 +-
security/keys/user_defined.c | 5 +-
sound/core/timer.c | 14 ++-
69 files changed, 789 insertions(+), 259 deletions(-)
create mode 100644 crypto/memneq.c

--
2.8.1


2016-04-22 11:06:22

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 20/78] ipv6: re-enable fragment header matching in ipv6_find_hdr

From: Florian Westphal <[email protected]>

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

===============

[ Upstream commit 5d150a985520bbe3cb2aa1ceef24a7e32f20c15f ]

When ipv6_find_hdr is used to find a fragment header
(caller specifies target NEXTHDR_FRAGMENT) we erronously return
-ENOENT for all fragments with nonzero offset.

Before commit 9195bb8e381d, when target was specified, we did not
enter the exthdr walk loop as nexthdr == target so this used to work.

Now we do (so we can skip empty route headers). When we then stumble upon
a frag with nonzero frag_off we must return -ENOENT ("header not found")
only if the caller did not specifically request NEXTHDR_FRAGMENT.

This allows nfables exthdr expression to match ipv6 fragments, e.g. via

nft add rule ip6 filter input frag frag-off gt 0

Fixes: 9195bb8e381d ("ipv6: improve ipv6_find_hdr() to skip empty routing headers")
Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv6/exthdrs_core.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 8af3eb57f438..c7c8f71d0d48 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -257,7 +257,11 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
*fragoff = _frag_off;
return hp->nexthdr;
}
- return -ENOENT;
+ if (!found)
+ return -ENOENT;
+ if (fragoff)
+ *fragoff = _frag_off;
+ break;
}
hdrlen = 8;
} else if (nexthdr == NEXTHDR_AUTH) {
--
2.8.1

2016-04-22 11:06:29

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 47/78] xen/events: Mask a moving irq

From: Boris Ostrovsky <[email protected]>

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

===============

commit ff1e22e7a638a0782f54f81a6c9cb139aca2da35 upstream.

Moving an unmasked irq may result in irq handler being invoked on both
source and target CPUs.

With 2-level this can happen as follows:

On source CPU:
evtchn_2l_handle_events() ->
generic_handle_irq() ->
handle_edge_irq() ->
eoi_pirq():
irq_move_irq(data);

/***** WE ARE HERE *****/

if (VALID_EVTCHN(evtchn))
clear_evtchn(evtchn);

If at this moment target processor is handling an unrelated event in
evtchn_2l_handle_events()'s loop it may pick up our event since target's
cpu_evtchn_mask claims that this event belongs to it *and* the event is
unmasked and still pending. At the same time, source CPU will continue
executing its own handle_edge_irq().

With FIFO interrupt the scenario is similar: irq_move_irq() may result
in a EVTCHNOP_unmask hypercall which, in turn, may make the event
pending on the target CPU.

We can avoid this situation by moving and clearing the event while
keeping event masked.

Signed-off-by: Boris Ostrovsky <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/xen/events.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index bd12a6660fe3..3715a54117bb 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -573,9 +573,19 @@ static void eoi_pirq(struct irq_data *data)
struct physdev_eoi eoi = { .irq = pirq_from_irq(data->irq) };
int rc = 0;

- irq_move_irq(data);
+ if (!VALID_EVTCHN(evtchn))
+ return;

- if (VALID_EVTCHN(evtchn))
+ if (unlikely(irqd_is_setaffinity_pending(data))) {
+ int masked = test_and_set_mask(evtchn);
+
+ clear_evtchn(evtchn);
+
+ irq_move_masked_irq(data);
+
+ if (!masked)
+ unmask_evtchn(evtchn);
+ } else
clear_evtchn(evtchn);

if (pirq_needs_eoi(data->irq)) {
@@ -1603,9 +1613,19 @@ static void ack_dynirq(struct irq_data *data)
{
int evtchn = evtchn_from_irq(data->irq);

- irq_move_irq(data);
+ if (!VALID_EVTCHN(evtchn))
+ return;

- if (VALID_EVTCHN(evtchn))
+ if (unlikely(irqd_is_setaffinity_pending(data))) {
+ int masked = test_and_set_mask(evtchn);
+
+ clear_evtchn(evtchn);
+
+ irq_move_masked_irq(data);
+
+ if (!masked)
+ unmask_evtchn(evtchn);
+ } else
clear_evtchn(evtchn);
}

--
2.8.1

2016-04-22 11:06:43

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 73/78] mnt: Move the clear of MNT_LOCKED from copy_tree to it's callers.

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

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

===============

commit 8486a7882b5ba906992fd78bbfcefaae7fe285cc upstream.

Clear MNT_LOCKED in the callers of copy_tree except copy_mnt_ns, and
collect_mounts. In copy_mnt_ns it is necessary to create an exact
copy of a mount tree, so not clearing MNT_LOCKED is important.
Similarly collect_mounts is used to take a snapshot of the mount tree
for audit logging purposes and auditing using a faithful copy of the
tree is important.

This becomes particularly significant when we start setting MNT_LOCKED
on rootfs to prevent it from being unmounted.

Signed-off-by: "Eric W. Biederman" <[email protected]>
Acked-by: NeilBrown <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/namespace.c | 1 -
fs/pnode.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index d727b0ce11df..f67473272010 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1416,7 +1416,6 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
if (IS_ERR(q))
return q;

- q->mnt.mnt_flags &= ~MNT_LOCKED;
q->mnt_mountpoint = mnt->mnt_mountpoint;

p = mnt;
diff --git a/fs/pnode.c b/fs/pnode.c
index 9af0df15256e..509d046e2b3e 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -249,6 +249,7 @@ int propagate_mnt(struct mount *dest_mnt, struct mountpoint *dest_mp,
list_splice(tree_list, tmp_list.prev);
goto out;
}
+ child->mnt.mnt_flags &= ~MNT_LOCKED;

if (is_subdir(dest_mp->m_dentry, m->mnt.mnt_root)) {
mnt_set_mountpoint(m, dest_mp, child);
--
2.8.1

2016-04-22 11:06:48

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 74/78] KEYS: Fix handling of stored error in a negatively instantiated user key

From: David Howells <[email protected]>

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

===============

commit 096fe9eaea40a17e125569f9e657e34cdb6d73bd upstream.

If a user key gets negatively instantiated, an error code is cached in the
payload area. A negatively instantiated key may be then be positively
instantiated by updating it with valid data. However, the ->update key
type method must be aware that the error code may be there.

The following may be used to trigger the bug in the user key type:

keyctl request2 user user "" @u
keyctl add user user "a" @u

which manifests itself as:

BUG: unable to handle kernel paging request at 00000000ffffff8a
IP: [<ffffffff810a376f>] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
PGD 7cc30067 PUD 0
Oops: 0002 [#1] SMP
Modules linked in:
CPU: 3 PID: 2644 Comm: a.out Not tainted 4.3.0+ #49
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
task: ffff88003ddea700 ti: ffff88003dd88000 task.ti: ffff88003dd88000
RIP: 0010:[<ffffffff810a376f>] [<ffffffff810a376f>] __call_rcu.constprop.76+0x1f/0x280
[<ffffffff810a376f>] __call_rcu.constprop.76+0x1f/0x280 kernel/rcu/tree.c:3046
RSP: 0018:ffff88003dd8bdb0 EFLAGS: 00010246
RAX: 00000000ffffff82 RBX: 0000000000000000 RCX: 0000000000000001
RDX: ffffffff81e3fe40 RSI: 0000000000000000 RDI: 00000000ffffff82
RBP: ffff88003dd8bde0 R08: ffff88007d2d2da0 R09: 0000000000000000
R10: 0000000000000000 R11: ffff88003e8073c0 R12: 00000000ffffff82
R13: ffff88003dd8be68 R14: ffff88007d027600 R15: ffff88003ddea700
FS: 0000000000b92880(0063) GS:ffff88007fd00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00000000ffffff8a CR3: 000000007cc5f000 CR4: 00000000000006e0
Stack:
ffff88003dd8bdf0 ffffffff81160a8a 0000000000000000 00000000ffffff82
ffff88003dd8be68 ffff88007d027600 ffff88003dd8bdf0 ffffffff810a39e5
ffff88003dd8be20 ffffffff812a31ab ffff88007d027600 ffff88007d027620
Call Trace:
[<ffffffff810a39e5>] kfree_call_rcu+0x15/0x20 kernel/rcu/tree.c:3136
[<ffffffff812a31ab>] user_update+0x8b/0xb0 security/keys/user_defined.c:129
[< inline >] __key_update security/keys/key.c:730
[<ffffffff8129e5c1>] key_create_or_update+0x291/0x440 security/keys/key.c:908
[< inline >] SYSC_add_key security/keys/keyctl.c:125
[<ffffffff8129fc21>] SyS_add_key+0x101/0x1e0 security/keys/keyctl.c:60
[<ffffffff8185f617>] entry_SYSCALL_64_fastpath+0x12/0x6a arch/x86/entry/entry_64.S:185

Note the error code (-ENOKEY) in EDX.

A similar bug can be tripped by:

keyctl request2 trusted user "" @u
keyctl add trusted user "a" @u

This should also affect encrypted keys - but that has to be correctly
parameterised or it will fail with EINVAL before getting to the bit that
will crashes.

Reported-by: Dmitry Vyukov <[email protected]>
Signed-off-by: David Howells <[email protected]>
Acked-by: Mimi Zohar <[email protected]>
Signed-off-by: James Morris <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
security/keys/encrypted-keys/encrypted.c | 2 ++
security/keys/trusted.c | 5 ++++-
security/keys/user_defined.c | 5 ++++-
3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index c4c8df4b214d..45d5c5926d03 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -845,6 +845,8 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
size_t datalen = prep->datalen;
int ret = 0;

+ if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+ return -ENOKEY;
if (datalen <= 0 || datalen > 32767 || !prep->data)
return -EINVAL;

diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index e13fcf7636f7..d72ff37e3da9 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -984,13 +984,16 @@ static void trusted_rcu_free(struct rcu_head *rcu)
*/
static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
{
- struct trusted_key_payload *p = key->payload.data;
+ struct trusted_key_payload *p;
struct trusted_key_payload *new_p;
struct trusted_key_options *new_o;
size_t datalen = prep->datalen;
char *datablob;
int ret = 0;

+ if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+ return -ENOKEY;
+ p = key->payload.data;
if (!p->migratable)
return -EPERM;
if (datalen <= 0 || datalen > 32767 || !prep->data)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 55dc88939185..637f43d45b28 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -119,7 +119,10 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)

if (ret == 0) {
/* attach the new data, displacing the old */
- zap = key->payload.data;
+ if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+ zap = key->payload.data;
+ else
+ zap = NULL;
rcu_assign_keypointer(key, upayload);
key->expiry = 0;
}
--
2.8.1

2016-04-22 11:06:39

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 43/78] mm: fix invalid node in alloc_migrate_target()

From: Xishi Qiu <[email protected]>

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

===============

commit 6f25a14a7053b69917e2ebea0d31dd444cd31fd5 upstream.

It is incorrect to use next_node to find a target node, it will return
MAX_NUMNODES or invalid node. This will lead to crash in buddy system
allocation.

Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage")
Signed-off-by: Xishi Qiu <[email protected]>
Acked-by: Vlastimil Babka <[email protected]>
Acked-by: Naoya Horiguchi <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: "Laura Abbott" <[email protected]>
Cc: Hui Zhu <[email protected]>
Cc: Wang Xiaoqiang <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
mm/page_isolation.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index d1473b2e9481..88bdbf48cf6c 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -259,11 +259,11 @@ struct page *alloc_migrate_target(struct page *page, unsigned long private,
* now as a simple work-around, we use the next node for destination.
*/
if (PageHuge(page)) {
- nodemask_t src = nodemask_of_node(page_to_nid(page));
- nodemask_t dst;
- nodes_complement(dst, src);
+ int node = next_online_node(page_to_nid(page));
+ if (node == MAX_NUMNODES)
+ node = first_online_node;
return alloc_huge_page_node(page_hstate(compound_head(page)),
- next_node(page_to_nid(page), dst));
+ node);
}

if (PageHighMem(page))
--
2.8.1

2016-04-22 11:06:45

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 72/78] fs/pipe.c: skip file_update_time on frozen fs

From: Dmitry Monakhov <[email protected]>

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

===============

commit 7e775f46a125f894a1d71e96797c776dbec161f0 upstream.

Pipe has no data associated with fs so it is not good idea to block
pipe_write() if FS is frozen, but we can not update file's time on such
filesystem. Let's use same idea as we use in touch_time().

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=65701

Signed-off-by: Dmitry Monakhov <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/pipe.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/pipe.c b/fs/pipe.c
index c281867c453e..fff8057a0809 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -681,10 +681,11 @@ out:
wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
}
- if (ret > 0) {
+ if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
int err = file_update_time(filp);
if (err)
ret = err;
+ sb_end_write(file_inode(filp)->i_sb);
}
return ret;
}
--
2.8.1

2016-04-22 11:07:39

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 69/78] netfilter: x_tables: validate e->target_offset early

From: Florian Westphal <[email protected]>

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

===============

commit bdf533de6968e9686df777dc178486f600c6e617 upstream.

We should check that e->target_offset is sane before
mark_source_chains gets called since it will fetch the target entry
for loop detection.

Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
Acked-by: Michal Kubecek <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/netfilter/arp_tables.c | 17 ++++++++---------
net/ipv4/netfilter/ip_tables.c | 17 ++++++++---------
net/ipv6/netfilter/ip6_tables.c | 17 ++++++++---------
3 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index c8abe31961ed..269759dd96f4 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -465,14 +465,12 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
return 1;
}

-static inline int check_entry(const struct arpt_entry *e, const char *name)
+static inline int check_entry(const struct arpt_entry *e)
{
const struct xt_entry_target *t;

- if (!arp_checkentry(&e->arp)) {
- duprintf("arp_tables: arp check failed %p %s.\n", e, name);
+ if (!arp_checkentry(&e->arp))
return -EINVAL;
- }

if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
return -EINVAL;
@@ -513,10 +511,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
struct xt_target *target;
int ret;

- ret = check_entry(e, name);
- if (ret)
- return ret;
-
t = arpt_get_target(e);
target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
t->u.user.revision);
@@ -561,6 +555,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
unsigned int valid_hooks)
{
unsigned int h;
+ int err;

if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 ||
(unsigned char *)e + sizeof(struct arpt_entry) >= limit) {
@@ -575,6 +570,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
return -EINVAL;
}

+ err = check_entry(e);
+ if (err)
+ return err;
+
/* Check hooks & underflows */
for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
if (!(valid_hooks & (1 << h)))
@@ -1232,7 +1231,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
}

/* For purposes of check_entry casting the compat entry is fine */
- ret = check_entry((struct arpt_entry *)e, name);
+ ret = check_entry((struct arpt_entry *)e);
if (ret)
return ret;

diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 651c10774d58..5ca478f13080 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -560,14 +560,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
}

static int
-check_entry(const struct ipt_entry *e, const char *name)
+check_entry(const struct ipt_entry *e)
{
const struct xt_entry_target *t;

- if (!ip_checkentry(&e->ip)) {
- duprintf("ip check failed %p %s.\n", e, name);
+ if (!ip_checkentry(&e->ip))
return -EINVAL;
- }

if (e->target_offset + sizeof(struct xt_entry_target) >
e->next_offset)
@@ -657,10 +655,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;

- ret = check_entry(e, name);
- if (ret)
- return ret;
-
j = 0;
mtpar.net = net;
mtpar.table = name;
@@ -724,6 +718,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
unsigned int valid_hooks)
{
unsigned int h;
+ int err;

if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
(unsigned char *)e + sizeof(struct ipt_entry) >= limit) {
@@ -738,6 +733,10 @@ check_entry_size_and_hooks(struct ipt_entry *e,
return -EINVAL;
}

+ err = check_entry(e);
+ if (err)
+ return err;
+
/* Check hooks & underflows */
for (h = 0; h < NF_INET_NUMHOOKS; h++) {
if (!(valid_hooks & (1 << h)))
@@ -1498,7 +1497,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
}

/* For purposes of check_entry casting the compat entry is fine */
- ret = check_entry((struct ipt_entry *)e, name);
+ ret = check_entry((struct ipt_entry *)e);
if (ret)
return ret;

diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 89a4e4ddd8bb..597f539f3d33 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -570,14 +570,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
}

static int
-check_entry(const struct ip6t_entry *e, const char *name)
+check_entry(const struct ip6t_entry *e)
{
const struct xt_entry_target *t;

- if (!ip6_checkentry(&e->ipv6)) {
- duprintf("ip_tables: ip check failed %p %s.\n", e, name);
+ if (!ip6_checkentry(&e->ipv6))
return -EINVAL;
- }

if (e->target_offset + sizeof(struct xt_entry_target) >
e->next_offset)
@@ -668,10 +666,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
struct xt_mtchk_param mtpar;
struct xt_entry_match *ematch;

- ret = check_entry(e, name);
- if (ret)
- return ret;
-
j = 0;
mtpar.net = net;
mtpar.table = name;
@@ -735,6 +729,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
unsigned int valid_hooks)
{
unsigned int h;
+ int err;

if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 ||
(unsigned char *)e + sizeof(struct ip6t_entry) >= limit) {
@@ -749,6 +744,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
return -EINVAL;
}

+ err = check_entry(e);
+ if (err)
+ return err;
+
/* Check hooks & underflows */
for (h = 0; h < NF_INET_NUMHOOKS; h++) {
if (!(valid_hooks & (1 << h)))
@@ -1510,7 +1509,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
}

/* For purposes of check_entry casting the compat entry is fine */
- ret = check_entry((struct ip6t_entry *)e, name);
+ ret = check_entry((struct ip6t_entry *)e);
if (ret)
return ret;

--
2.8.1

2016-04-22 11:07:38

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 78/78] KVM: x86: Reload pit counters for all channels when restoring state

From: Andrew Honig <[email protected]>

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

===============

commit 0185604c2d82c560dab2f2933a18f797e74ab5a8 upstream.

Currently if userspace restores the pit counters with a count of 0
on channels 1 or 2 and the guest attempts to read the count on those
channels, then KVM will perform a mod of 0 and crash. This will ensure
that 0 values are converted to 65536 as per the spec.

This is CVE-2015-7513.

Signed-off-by: Andy Honig <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/x86.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1962a3999adf..e0c859e1999a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3479,9 +3479,11 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)

static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
{
+ int i;
mutex_lock(&kvm->arch.vpit->pit_state.lock);
memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
- kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
+ for (i = 0; i < 3; i++)
+ kvm_pit_load_count(kvm, i, ps->channels[i].count, 0);
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
return 0;
}
@@ -3500,6 +3502,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
{
int start = 0;
+ int i;
u32 prev_legacy, cur_legacy;
mutex_lock(&kvm->arch.vpit->pit_state.lock);
prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
@@ -3509,7 +3512,8 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
sizeof(kvm->arch.vpit->pit_state.channels));
kvm->arch.vpit->pit_state.flags = ps->flags;
- kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
+ for (i = 0; i < 3; i++)
+ kvm_pit_load_count(kvm, i, kvm->arch.vpit->pit_state.channels[i].count, start);
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
return 0;
}
--
2.8.1

2016-04-22 11:08:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 75/78] crypto: crypto_memneq - add equality testing of memory regions w/o timing leaks

From: James Yonan <[email protected]>

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

===============

commit 6bf37e5aa90f18baf5acf4874bca505dd667c37f upstream.

When comparing MAC hashes, AEAD authentication tags, or other hash
values in the context of authentication or integrity checking, it
is important not to leak timing information to a potential attacker,
i.e. when communication happens over a network.

Bytewise memory comparisons (such as memcmp) are usually optimized so
that they return a nonzero value as soon as a mismatch is found. E.g,
on x86_64/i5 for 512 bytes this can be ~50 cyc for a full mismatch
and up to ~850 cyc for a full match (cold). This early-return behavior
can leak timing information as a side channel, allowing an attacker to
iteratively guess the correct result.

This patch adds a new method crypto_memneq ("memory not equal to each
other") to the crypto API that compares memory areas of the same length
in roughly "constant time" (cache misses could change the timing, but
since they don't reveal information about the content of the strings
being compared, they are effectively benign). Iow, best and worst case
behaviour take the same amount of time to complete (in contrast to
memcmp).

Note that crypto_memneq (unlike memcmp) can only be used to test for
equality or inequality, NOT for lexicographical order. This, however,
is not an issue for its use-cases within the crypto API.

We tried to locate all of the places in the crypto API where memcmp was
being used for authentication or integrity checking, and convert them
over to crypto_memneq.

crypto_memneq is declared noinline, placed in its own source file,
and compiled with optimizations that might increase code size disabled
("Os") because a smart compiler (or LTO) might notice that the return
value is always compared against zero/nonzero, and might then
reintroduce the same early-return optimization that we are trying to
avoid.

Using #pragma or __attribute__ optimization annotations of the code
for disabling optimization was avoided as it seems to be considered
broken or unmaintained for long time in GCC [1]. Therefore, we work
around that by specifying the compile flag for memneq.o directly in
the Makefile. We found that this seems to be most appropriate.

As we use ("Os"), this patch also provides a loop-free "fast-path" for
frequently used 16 byte digests. Similarly to kernel library string
functions, leave an option for future even further optimized architecture
specific assembler implementations.

This was a joint work of James Yonan and Daniel Borkmann. Also thanks
for feedback from Florian Weimer on this and earlier proposals [2].

[1] http://gcc.gnu.org/ml/gcc/2012-07/msg00211.html
[2] https://lkml.org/lkml/2013/2/10/131

Signed-off-by: James Yonan <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Cc: Florian Weimer <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
crypto/Makefile | 7 ++-
crypto/asymmetric_keys/rsa.c | 5 +-
crypto/authenc.c | 6 +-
crypto/authencesn.c | 8 +--
crypto/ccm.c | 4 +-
crypto/gcm.c | 2 +-
crypto/memneq.c | 138 +++++++++++++++++++++++++++++++++++++++++++
include/crypto/algapi.h | 18 +++++-
8 files changed, 174 insertions(+), 14 deletions(-)
create mode 100644 crypto/memneq.c

diff --git a/crypto/Makefile b/crypto/Makefile
index 80019ba8da3a..e0ec1c0e0eee 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -2,8 +2,13 @@
# Cryptographic API
#

+# memneq MUST be built with -Os or -O0 to prevent early-return optimizations
+# that will defeat memneq's actual purpose to prevent timing attacks.
+CFLAGS_REMOVE_memneq.o := -O1 -O2 -O3
+CFLAGS_memneq.o := -Os
+
obj-$(CONFIG_CRYPTO) += crypto.o
-crypto-y := api.o cipher.o compress.o
+crypto-y := api.o cipher.o compress.o memneq.o

obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o

diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 4a6a0696f8a3..1912b9be5043 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <crypto/algapi.h>
#include "public_key.h"

MODULE_LICENSE("GPL");
@@ -189,12 +190,12 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
}
}

- if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
+ if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) {
kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
return -EBADMSG;
}

- if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
+ if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) {
kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
return -EKEYREJECTED;
}
diff --git a/crypto/authenc.c b/crypto/authenc.c
index a2cfae251dd5..65bcd076b18b 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -188,7 +188,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);

- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;

@@ -227,7 +227,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);

- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;

@@ -463,7 +463,7 @@ static int crypto_authenc_verify(struct aead_request *req,
ihash = ohash + authsize;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
+ return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
}

static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 16c225cb28c2..a3ef98be2064 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -247,7 +247,7 @@ static void authenc_esn_verify_ahash_update_done(struct crypto_async_request *ar
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);

- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;

@@ -296,7 +296,7 @@ static void authenc_esn_verify_ahash_update_done2(struct crypto_async_request *a
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);

- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;

@@ -336,7 +336,7 @@ static void authenc_esn_verify_ahash_done(struct crypto_async_request *areq,
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);

- err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
+ err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
if (err)
goto out;

@@ -568,7 +568,7 @@ static int crypto_authenc_esn_verify(struct aead_request *req)
ihash = ohash + authsize;
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
authsize, 0);
- return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
+ return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
}

static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
diff --git a/crypto/ccm.c b/crypto/ccm.c
index c569c9c6afe3..003bbbd21a2b 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -364,7 +364,7 @@ static void crypto_ccm_decrypt_done(struct crypto_async_request *areq,

if (!err) {
err = crypto_ccm_auth(req, req->dst, cryptlen);
- if (!err && memcmp(pctx->auth_tag, pctx->odata, authsize))
+ if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize))
err = -EBADMSG;
}
aead_request_complete(req, err);
@@ -423,7 +423,7 @@ static int crypto_ccm_decrypt(struct aead_request *req)
return err;

/* verify */
- if (memcmp(authtag, odata, authsize))
+ if (crypto_memneq(authtag, odata, authsize))
return -EBADMSG;

return err;
diff --git a/crypto/gcm.c b/crypto/gcm.c
index b4c252066f7b..9cea4d0b6904 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -582,7 +582,7 @@ static int crypto_gcm_verify(struct aead_request *req,

crypto_xor(auth_tag, iauth_tag, 16);
scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0);
- return memcmp(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
+ return crypto_memneq(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
}

static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
diff --git a/crypto/memneq.c b/crypto/memneq.c
new file mode 100644
index 000000000000..cd0162221c14
--- /dev/null
+++ b/crypto/memneq.c
@@ -0,0 +1,138 @@
+/*
+ * Constant-time equality testing of memory regions.
+ *
+ * Authors:
+ *
+ * James Yonan <[email protected]>
+ * Daniel Borkmann <[email protected]>
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of OpenVPN Technologies nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <crypto/algapi.h>
+
+#ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
+
+/* Generic path for arbitrary size */
+static inline unsigned long
+__crypto_memneq_generic(const void *a, const void *b, size_t size)
+{
+ unsigned long neq = 0;
+
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
+ while (size >= sizeof(unsigned long)) {
+ neq |= *(unsigned long *)a ^ *(unsigned long *)b;
+ a += sizeof(unsigned long);
+ b += sizeof(unsigned long);
+ size -= sizeof(unsigned long);
+ }
+#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
+ while (size > 0) {
+ neq |= *(unsigned char *)a ^ *(unsigned char *)b;
+ a += 1;
+ b += 1;
+ size -= 1;
+ }
+ return neq;
+}
+
+/* Loop-free fast-path for frequently used 16-byte size */
+static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
+{
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ if (sizeof(unsigned long) == 8)
+ return ((*(unsigned long *)(a) ^ *(unsigned long *)(b))
+ | (*(unsigned long *)(a+8) ^ *(unsigned long *)(b+8)));
+ else if (sizeof(unsigned int) == 4)
+ return ((*(unsigned int *)(a) ^ *(unsigned int *)(b))
+ | (*(unsigned int *)(a+4) ^ *(unsigned int *)(b+4))
+ | (*(unsigned int *)(a+8) ^ *(unsigned int *)(b+8))
+ | (*(unsigned int *)(a+12) ^ *(unsigned int *)(b+12)));
+ else
+#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
+ return ((*(unsigned char *)(a) ^ *(unsigned char *)(b))
+ | (*(unsigned char *)(a+1) ^ *(unsigned char *)(b+1))
+ | (*(unsigned char *)(a+2) ^ *(unsigned char *)(b+2))
+ | (*(unsigned char *)(a+3) ^ *(unsigned char *)(b+3))
+ | (*(unsigned char *)(a+4) ^ *(unsigned char *)(b+4))
+ | (*(unsigned char *)(a+5) ^ *(unsigned char *)(b+5))
+ | (*(unsigned char *)(a+6) ^ *(unsigned char *)(b+6))
+ | (*(unsigned char *)(a+7) ^ *(unsigned char *)(b+7))
+ | (*(unsigned char *)(a+8) ^ *(unsigned char *)(b+8))
+ | (*(unsigned char *)(a+9) ^ *(unsigned char *)(b+9))
+ | (*(unsigned char *)(a+10) ^ *(unsigned char *)(b+10))
+ | (*(unsigned char *)(a+11) ^ *(unsigned char *)(b+11))
+ | (*(unsigned char *)(a+12) ^ *(unsigned char *)(b+12))
+ | (*(unsigned char *)(a+13) ^ *(unsigned char *)(b+13))
+ | (*(unsigned char *)(a+14) ^ *(unsigned char *)(b+14))
+ | (*(unsigned char *)(a+15) ^ *(unsigned char *)(b+15)));
+}
+
+/* Compare two areas of memory without leaking timing information,
+ * and with special optimizations for common sizes. Users should
+ * not call this function directly, but should instead use
+ * crypto_memneq defined in crypto/algapi.h.
+ */
+noinline unsigned long __crypto_memneq(const void *a, const void *b,
+ size_t size)
+{
+ switch (size) {
+ case 16:
+ return __crypto_memneq_16(a, b);
+ default:
+ return __crypto_memneq_generic(a, b, size);
+ }
+}
+EXPORT_SYMBOL(__crypto_memneq);
+
+#endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 418d270e1806..e73c19e90e38 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -386,5 +386,21 @@ static inline int crypto_requires_sync(u32 type, u32 mask)
return (type ^ CRYPTO_ALG_ASYNC) & mask & CRYPTO_ALG_ASYNC;
}

-#endif /* _CRYPTO_ALGAPI_H */
+noinline unsigned long __crypto_memneq(const void *a, const void *b, size_t size);
+
+/**
+ * crypto_memneq - Compare two areas of memory without leaking
+ * timing information.
+ *
+ * @a: One area of memory
+ * @b: Another area of memory
+ * @size: The size of the area.
+ *
+ * Returns 0 when data is equal, 1 otherwise.
+ */
+static inline int crypto_memneq(const void *a, const void *b, size_t size)
+{
+ return __crypto_memneq(a, b, size) != 0UL ? 1 : 0;
+}

+#endif /* _CRYPTO_ALGAPI_H */
--
2.8.1

2016-04-22 11:08:05

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 76/78] EVM: Use crypto_memneq() for digest comparisons

From: Ryan Ware <[email protected]>

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

===============

commit 613317bd212c585c20796c10afe5daaa95d4b0a1 upstream.

This patch fixes vulnerability CVE-2016-2085. The problem exists
because the vm_verify_hmac() function includes a use of memcmp().
Unfortunately, this allows timing side channel attacks; specifically
a MAC forgery complexity drop from 2^128 to 2^12. This patch changes
the memcmp() to the cryptographically safe crypto_memneq().

Reported-by: Xiaofei Rex Guo <[email protected]>
Signed-off-by: Ryan Ware <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
Signed-off-by: James Morris <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
security/integrity/evm/evm_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index d43b62c4a8e5..5bf01c8648a8 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -21,6 +21,7 @@
#include <linux/integrity.h>
#include <linux/evm.h>
#include <crypto/hash.h>
+#include <crypto/algapi.h>
#include "evm.h"

int evm_initialized;
@@ -132,7 +133,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
xattr_value_len, calc.digest);
if (rc)
break;
- rc = memcmp(xattr_data->digest, calc.digest,
+ rc = crypto_memneq(xattr_data->digest, calc.digest,
sizeof(calc.digest));
if (rc)
rc = -EINVAL;
--
2.8.1

2016-04-22 11:08:04

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 77/78] KVM: x86: removing unused variable

From: Saurabh Sengar <[email protected]>

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

===============

commit 2da29bccc5045ea10c70cb3a69be777768fd0b66 upstream.

removing unused variables, found by coccinelle

Signed-off-by: Saurabh Sengar <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/x86/kvm/x86.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c47a4ecb584c..1962a3999adf 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3471,41 +3471,35 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)

static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
{
- int r = 0;
-
mutex_lock(&kvm->arch.vpit->pit_state.lock);
memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state));
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
+ return 0;
}

static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
{
- int r = 0;
-
mutex_lock(&kvm->arch.vpit->pit_state.lock);
memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
+ return 0;
}

static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
{
- int r = 0;
-
mutex_lock(&kvm->arch.vpit->pit_state.lock);
memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
sizeof(ps->channels));
ps->flags = kvm->arch.vpit->pit_state.flags;
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
memset(&ps->reserved, 0, sizeof(ps->reserved));
- return r;
+ return 0;
}

static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
{
- int r = 0, start = 0;
+ int start = 0;
u32 prev_legacy, cur_legacy;
mutex_lock(&kvm->arch.vpit->pit_state.lock);
prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
@@ -3517,7 +3511,7 @@ static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
kvm->arch.vpit->pit_state.flags = ps->flags;
kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- return r;
+ return 0;
}

static int kvm_vm_ioctl_reinject(struct kvm *kvm,
--
2.8.1

2016-04-22 11:09:09

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 71/78] USB: usbip: fix potential out-of-bounds write

From: Ignat Korchagin <[email protected]>

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

===============

commit b348d7dddb6c4fbfc810b7a0626e8ec9e29f7cbb upstream.

Fix potential out-of-bounds write to urb->transfer_buffer
usbip handles network communication directly in the kernel. When receiving a
packet from its peer, usbip code parses headers according to protocol. As
part of this parsing urb->actual_length is filled. Since the input for
urb->actual_length comes from the network, it should be treated as untrusted.
Any entity controlling the network may put any value in the input and the
preallocated urb->transfer_buffer may not be large enough to hold the data.
Thus, the malicious entity is able to write arbitrary data to kernel memory.

Signed-off-by: Ignat Korchagin <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/staging/usbip/usbip_common.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index e3fc749c1e7e..15aeb41f7c84 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -785,6 +785,17 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
if (!(size > 0))
return 0;

+ if (size > urb->transfer_buffer_length) {
+ /* should not happen, probably malicious packet */
+ if (ud->side == USBIP_STUB) {
+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+ return 0;
+ } else {
+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+ return -EPIPE;
+ }
+ }
+
ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size);
if (ret != size) {
dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
--
2.8.1

2016-04-22 11:09:08

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 61/78] net: qmi_wwan: MDM9x30 specific power management

From: Bjørn Mork <[email protected]>

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

===============

commit 93725149794d3d418cf1eddcae60c7b536c5faa1 upstream.

MDM9x30 based modems appear to go into a deeper sleep when
suspended without "Remote Wakeup" enabled. The QMI interface
will not respond unless a "set DTR" control request is sent
on resume. The effect is similar to a QMI_CTL SYNC request,
resetting (some of) the firmware state.

We allow userspace sessions to span multiple character device
open/close sequences. This means that userspace can depend
on firmware state while both the netdev and the character
device are closed. We have disabled "needs_remote_wakeup" at
this point to allow devices without remote wakeup support to
be auto-suspended.

To make sure the MDM9x30 keeps firmware state, we need to
keep "needs_remote_wakeup" always set. We also need to
issue a "set DTR" request to enable the QMI interface.

Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 18101e3fcd04..415bbe0365c6 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -216,6 +216,20 @@ err:
return rv;
}

+/* Send CDC SetControlLineState request, setting or clearing the DTR.
+ * "Required for Autoconnect and 9x30 to wake up" according to the
+ * GobiNet driver. The requirement has been verified on an MDM9230
+ * based Sierra Wireless MC7455
+ */
+static int qmi_wwan_change_dtr(struct usbnet *dev, bool on)
+{
+ u8 intf = dev->intf->cur_altsetting->desc.bInterfaceNumber;
+
+ return usbnet_write_cmd(dev, USB_CDC_REQ_SET_CONTROL_LINE_STATE,
+ USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ on ? 0x01 : 0x00, intf, NULL, 0);
+}
+
static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status = -1;
@@ -320,6 +334,24 @@ next_desc:
usb_driver_release_interface(driver, info->data);
}

+ /* disabling remote wakeup on MDM9x30 devices has the same
+ * effect as clearing DTR. The device will not respond to QMI
+ * requests until we set DTR again. This is similar to a
+ * QMI_CTL SYNC request, clearing a lot of firmware state
+ * including the client ID allocations.
+ *
+ * Our usage model allows a session to span multiple
+ * open/close events, so we must prevent the firmware from
+ * clearing out state the clients might need.
+ *
+ * MDM9x30 is the first QMI chipset with USB3 support. Abuse
+ * this fact to enable the quirk.
+ */
+ if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
+ qmi_wwan_manage_power(dev, 1);
+ qmi_wwan_change_dtr(dev, true);
+ }
+
/* Never use the same address on both ends of the link, even
* if the buggy firmware told us to.
*/
@@ -345,6 +377,12 @@ static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
if (info->subdriver && info->subdriver->disconnect)
info->subdriver->disconnect(info->control);

+ /* disable MDM9x30 quirk */
+ if (le16_to_cpu(dev->udev->descriptor.bcdUSB) >= 0x0201) {
+ qmi_wwan_change_dtr(dev, false);
+ qmi_wwan_manage_power(dev, 0);
+ }
+
/* allow user to unbind using either control or data */
if (intf == info->control)
other = info->data;
--
2.8.1

2016-04-22 11:06:37

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 44/78] drm/radeon: add a dpm quirk for sapphire Dual-X R7 370 2G D5

From: Alex Deucher <[email protected]>

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

===============

commit f971f2263deaa4a441e377b385c11aee0f3b3f9a upstream.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=94692

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/si_dpm.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index f39f2008afab..34527c050062 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -2915,6 +2915,7 @@ static struct si_dpm_quirk si_dpm_quirk_list[] = {
/* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */
{ PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 },
{ PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0xe271, 0, 120000 },
+ { PCI_VENDOR_ID_ATI, 0x6811, 0x174b, 0x2015, 0, 120000 },
{ PCI_VENDOR_ID_ATI, 0x6810, 0x174b, 0xe271, 85000, 90000 },
{ 0, 0, 0, 0 },
};
--
2.8.1

2016-04-22 11:10:00

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 57/78] jme: Do not enable NIC WoL functions on S0

From: Guo-Fu Tseng <[email protected]>

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

===============

commit 0772a99b818079e628a1da122ac7ee023faed83e upstream.

Otherwise it might be back on resume right after going to suspend in
some hardware.

Reported-by: Diego Viola <[email protected]>
Signed-off-by: Guo-Fu Tseng <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/jme.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 2602fb324157..3291bf72e998 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -270,11 +270,17 @@ jme_reset_mac_processor(struct jme_adapter *jme)
}

static inline void
-jme_clear_pm(struct jme_adapter *jme)
+jme_clear_pm_enable_wol(struct jme_adapter *jme)
{
jwrite32(jme, JME_PMCS, PMCS_STMASK | jme->reg_pmcs);
}

+static inline void
+jme_clear_pm_disable_wol(struct jme_adapter *jme)
+{
+ jwrite32(jme, JME_PMCS, PMCS_STMASK);
+}
+
static int
jme_reload_eeprom(struct jme_adapter *jme)
{
@@ -1857,7 +1863,7 @@ jme_open(struct net_device *netdev)
struct jme_adapter *jme = netdev_priv(netdev);
int rc;

- jme_clear_pm(jme);
+ jme_clear_pm_disable_wol(jme);
JME_NAPI_ENABLE(jme);

tasklet_init(&jme->linkch_task, jme_link_change_tasklet,
@@ -1933,7 +1939,7 @@ jme_powersave_phy(struct jme_adapter *jme)
jme_set_100m_half(jme);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
- jme_clear_pm(jme);
+ jme_clear_pm_enable_wol(jme);
} else {
jme_phy_off(jme);
}
@@ -2621,7 +2627,6 @@ jme_set_wol(struct net_device *netdev,
if (wol->wolopts & WAKE_MAGIC)
jme->reg_pmcs |= PMCS_MFEN;

- jwrite32(jme, JME_PMCS, jme->reg_pmcs);
device_set_wakeup_enable(&jme->pdev->dev, !!(jme->reg_pmcs));

return 0;
@@ -3147,7 +3152,7 @@ jme_init_one(struct pci_dev *pdev,
jme->mii_if.mdio_read = jme_mdio_read;
jme->mii_if.mdio_write = jme_mdio_write;

- jme_clear_pm(jme);
+ jme_clear_pm_disable_wol(jme);
device_set_wakeup_enable(&pdev->dev, true);

jme_set_phyfifo_5level(jme);
@@ -3281,7 +3286,7 @@ jme_resume(struct device *dev)
if (!netif_running(netdev))
return 0;

- jme_clear_pm(jme);
+ jme_clear_pm_disable_wol(jme);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
jme_set_settings(netdev, &jme->old_ecmd);
--
2.8.1

2016-04-22 11:09:58

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 70/78] netfilter: x_tables: fix unconditional helper

From: Florian Westphal <[email protected]>

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

===============

commit 54d83fc74aa9ec72794373cb47432c5f7fb1a309 upstream.

Ben Hawkes says:

In the mark_source_chains function (net/ipv4/netfilter/ip_tables.c) it
is possible for a user-supplied ipt_entry structure to have a large
next_offset field. This field is not bounds checked prior to writing a
counter value at the supplied offset.

Problem is that mark_source_chains should not have been called --
the rule doesn't have a next entry, so its supposed to return
an absolute verdict of either ACCEPT or DROP.

However, the function conditional() doesn't work as the name implies.
It only checks that the rule is using wildcard address matching.

However, an unconditional rule must also not be using any matches
(no -m args).

The underflow validator only checked the addresses, therefore
passing the 'unconditional absolute verdict' test, while
mark_source_chains also tested for presence of matches, and thus
proceeeded to the next (not-existent) rule.

Unify this so that all the callers have same idea of 'unconditional rule'.

Reported-by: Ben Hawkes <[email protected]>
Signed-off-by: Florian Westphal <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/netfilter/arp_tables.c | 18 +++++++++---------
net/ipv4/netfilter/ip_tables.c | 23 +++++++++++------------
net/ipv6/netfilter/ip6_tables.c | 23 +++++++++++------------
3 files changed, 31 insertions(+), 33 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 269759dd96f4..29aa90ea4c8d 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -350,11 +350,12 @@ unsigned int arpt_do_table(struct sk_buff *skb,
}

/* All zeroes == unconditional rule. */
-static inline bool unconditional(const struct arpt_arp *arp)
+static inline bool unconditional(const struct arpt_entry *e)
{
static const struct arpt_arp uncond;

- return memcmp(arp, &uncond, sizeof(uncond)) == 0;
+ return e->target_offset == sizeof(struct arpt_entry) &&
+ memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
}

/* Figures out from what hook each rule can be called: returns 0 if
@@ -393,11 +394,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
|= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));

/* Unconditional return/END. */
- if ((e->target_offset == sizeof(struct arpt_entry) &&
+ if ((unconditional(e) &&
(strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) &&
- t->verdict < 0 && unconditional(&e->arp)) ||
- visited) {
+ t->verdict < 0) || visited) {
unsigned int oldpos, size;

if ((strcmp(t->target.u.user.name,
@@ -536,7 +536,7 @@ static bool check_underflow(const struct arpt_entry *e)
const struct xt_entry_target *t;
unsigned int verdict;

- if (!unconditional(&e->arp))
+ if (!unconditional(e))
return false;
t = arpt_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
@@ -582,9 +582,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
if (!check_underflow(e)) {
- pr_err("Underflows must be unconditional and "
- "use the STANDARD target with "
- "ACCEPT/DROP\n");
+ pr_debug("Underflows must be unconditional and "
+ "use the STANDARD target with "
+ "ACCEPT/DROP\n");
return -EINVAL;
}
newinfo->underflow[h] = underflows[h];
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 5ca478f13080..d400a2ad7c56 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset)

/* All zeroes == unconditional rule. */
/* Mildly perf critical (only if packet tracing is on) */
-static inline bool unconditional(const struct ipt_ip *ip)
+static inline bool unconditional(const struct ipt_entry *e)
{
static const struct ipt_ip uncond;

- return memcmp(ip, &uncond, sizeof(uncond)) == 0;
+ return e->target_offset == sizeof(struct ipt_entry) &&
+ memcmp(&e->ip, &uncond, sizeof(uncond)) == 0;
#undef FWINV
}

@@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e,
} else if (s == e) {
(*rulenum)++;

- if (s->target_offset == sizeof(struct ipt_entry) &&
+ if (unconditional(s) &&
strcmp(t->target.u.kernel.target->name,
XT_STANDARD_TARGET) == 0 &&
- t->verdict < 0 &&
- unconditional(&s->ip)) {
+ t->verdict < 0) {
/* Tail of chains: STANDARD target (return/policy) */
*comment = *chainname == hookname
? comments[NF_IP_TRACE_COMMENT_POLICY]
@@ -467,11 +467,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));

/* Unconditional return/END. */
- if ((e->target_offset == sizeof(struct ipt_entry) &&
+ if ((unconditional(e) &&
(strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) &&
- t->verdict < 0 && unconditional(&e->ip)) ||
- visited) {
+ t->verdict < 0) || visited) {
unsigned int oldpos, size;

if ((strcmp(t->target.u.user.name,
@@ -698,7 +697,7 @@ static bool check_underflow(const struct ipt_entry *e)
const struct xt_entry_target *t;
unsigned int verdict;

- if (!unconditional(&e->ip))
+ if (!unconditional(e))
return false;
t = ipt_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
@@ -745,9 +744,9 @@ check_entry_size_and_hooks(struct ipt_entry *e,
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
if (!check_underflow(e)) {
- pr_err("Underflows must be unconditional and "
- "use the STANDARD target with "
- "ACCEPT/DROP\n");
+ pr_debug("Underflows must be unconditional and "
+ "use the STANDARD target with "
+ "ACCEPT/DROP\n");
return -EINVAL;
}
newinfo->underflow[h] = underflows[h];
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 597f539f3d33..e0538df697c8 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -195,11 +195,12 @@ get_entry(const void *base, unsigned int offset)

/* All zeroes == unconditional rule. */
/* Mildly perf critical (only if packet tracing is on) */
-static inline bool unconditional(const struct ip6t_ip6 *ipv6)
+static inline bool unconditional(const struct ip6t_entry *e)
{
static const struct ip6t_ip6 uncond;

- return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
+ return e->target_offset == sizeof(struct ip6t_entry) &&
+ memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0;
}

static inline const struct xt_entry_target *
@@ -255,11 +256,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e,
} else if (s == e) {
(*rulenum)++;

- if (s->target_offset == sizeof(struct ip6t_entry) &&
+ if (unconditional(s) &&
strcmp(t->target.u.kernel.target->name,
XT_STANDARD_TARGET) == 0 &&
- t->verdict < 0 &&
- unconditional(&s->ipv6)) {
+ t->verdict < 0) {
/* Tail of chains: STANDARD target (return/policy) */
*comment = *chainname == hookname
? comments[NF_IP6_TRACE_COMMENT_POLICY]
@@ -477,11 +477,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));

/* Unconditional return/END. */
- if ((e->target_offset == sizeof(struct ip6t_entry) &&
+ if ((unconditional(e) &&
(strcmp(t->target.u.user.name,
XT_STANDARD_TARGET) == 0) &&
- t->verdict < 0 &&
- unconditional(&e->ipv6)) || visited) {
+ t->verdict < 0) || visited) {
unsigned int oldpos, size;

if ((strcmp(t->target.u.user.name,
@@ -709,7 +708,7 @@ static bool check_underflow(const struct ip6t_entry *e)
const struct xt_entry_target *t;
unsigned int verdict;

- if (!unconditional(&e->ipv6))
+ if (!unconditional(e))
return false;
t = ip6t_get_target_c(e);
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
@@ -756,9 +755,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
newinfo->hook_entry[h] = hook_entries[h];
if ((unsigned char *)e - base == underflows[h]) {
if (!check_underflow(e)) {
- pr_err("Underflows must be unconditional and "
- "use the STANDARD target with "
- "ACCEPT/DROP\n");
+ pr_debug("Underflows must be unconditional and "
+ "use the STANDARD target with "
+ "ACCEPT/DROP\n");
return -EINVAL;
}
newinfo->underflow[h] = underflows[h];
--
2.8.1

2016-04-22 11:10:48

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 68/78] pipe: limit the per-user amount of pages allocated in pipes

From: Willy Tarreau <[email protected]>

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

===============

commit 759c01142a5d0f364a462346168a56de28a80f52 upstream.

On no-so-small systems, it is possible for a single process to cause an
OOM condition by filling large pipes with data that are never read. A
typical process filling 4000 pipes with 1 MB of data will use 4 GB of
memory. On small systems it may be tricky to set the pipe max size to
prevent this from happening.

This patch makes it possible to enforce a per-user soft limit above
which new pipes will be limited to a single page, effectively limiting
them to 4 kB each, as well as a hard limit above which no new pipes may
be created for this user. This has the effect of protecting the system
against memory abuse without hurting other users, and still allowing
pipes to work correctly though with less data at once.

The limit are controlled by two new sysctls : pipe-user-pages-soft, and
pipe-user-pages-hard. Both may be disabled by setting them to zero. The
default soft limit allows the default number of FDs per process (1024)
to create pipes of the default size (64kB), thus reaching a limit of 64MB
before starting to create only smaller pipes. With 256 processes limited
to 1024 FDs each, this results in 1024*64kB + (256*1024 - 1024) * 4kB =
1084 MB of memory allocated for a user. The hard limit is disabled by
default to avoid breaking existing applications that make intensive use
of pipes (eg: for splicing).

Reported-by: [email protected]
Reported-by: Tetsuo Handa <[email protected]>
Mitigates: CVE-2013-4312 (Linux 2.0+)
Suggested-by: Linus Torvalds <[email protected]>
Signed-off-by: Willy Tarreau <[email protected]>
Signed-off-by: Al Viro <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
Documentation/sysctl/fs.txt | 23 ++++++++++++++++++++++
fs/pipe.c | 47 +++++++++++++++++++++++++++++++++++++++++++--
include/linux/pipe_fs_i.h | 4 ++++
include/linux/sched.h | 1 +
kernel/sysctl.c | 14 ++++++++++++++
5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt
index 88152f214f48..302b5ed616a6 100644
--- a/Documentation/sysctl/fs.txt
+++ b/Documentation/sysctl/fs.txt
@@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
- nr_open
- overflowuid
- overflowgid
+- pipe-user-pages-hard
+- pipe-user-pages-soft
- protected_hardlinks
- protected_symlinks
- suid_dumpable
@@ -159,6 +161,27 @@ The default is 65534.

==============================================================

+pipe-user-pages-hard:
+
+Maximum total number of pages a non-privileged user may allocate for pipes.
+Once this limit is reached, no new pipes may be allocated until usage goes
+below the limit again. When set to 0, no limit is applied, which is the default
+setting.
+
+==============================================================
+
+pipe-user-pages-soft:
+
+Maximum total number of pages a non-privileged user may allocate for pipes
+before the pipe size gets limited to a single page. Once this limit is reached,
+new pipes will be limited to a single page in size for this user in order to
+limit total memory usage, and trying to increase them using fcntl() will be
+denied until usage goes below the limit again. The default value allows to
+allocate up to 1024 pipes at their default size. When set to 0, no limit is
+applied.
+
+==============================================================
+
protected_hardlinks:

A long-standing class of security issues is the hardlink-based
diff --git a/fs/pipe.c b/fs/pipe.c
index 50267e6ba688..c281867c453e 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -39,6 +39,12 @@ unsigned int pipe_max_size = 1048576;
*/
unsigned int pipe_min_size = PAGE_SIZE;

+/* Maximum allocatable pages per user. Hard limit is unset by default, soft
+ * matches default values.
+ */
+unsigned long pipe_user_pages_hard;
+unsigned long pipe_user_pages_soft = PIPE_DEF_BUFFERS * INR_OPEN_CUR;
+
/*
* We use a start+len construction, which provides full use of the
* allocated memory.
@@ -794,20 +800,49 @@ pipe_fasync(int fd, struct file *filp, int on)
return retval;
}

+static void account_pipe_buffers(struct pipe_inode_info *pipe,
+ unsigned long old, unsigned long new)
+{
+ atomic_long_add(new - old, &pipe->user->pipe_bufs);
+}
+
+static bool too_many_pipe_buffers_soft(struct user_struct *user)
+{
+ return pipe_user_pages_soft &&
+ atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_soft;
+}
+
+static bool too_many_pipe_buffers_hard(struct user_struct *user)
+{
+ return pipe_user_pages_hard &&
+ atomic_long_read(&user->pipe_bufs) >= pipe_user_pages_hard;
+}
+
struct pipe_inode_info *alloc_pipe_info(void)
{
struct pipe_inode_info *pipe;

pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
if (pipe) {
- pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL);
+ unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
+ struct user_struct *user = get_current_user();
+
+ if (!too_many_pipe_buffers_hard(user)) {
+ if (too_many_pipe_buffers_soft(user))
+ pipe_bufs = 1;
+ pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * pipe_bufs, GFP_KERNEL);
+ }
+
if (pipe->bufs) {
init_waitqueue_head(&pipe->wait);
pipe->r_counter = pipe->w_counter = 1;
- pipe->buffers = PIPE_DEF_BUFFERS;
+ pipe->buffers = pipe_bufs;
+ pipe->user = user;
+ account_pipe_buffers(pipe, 0, pipe_bufs);
mutex_init(&pipe->mutex);
return pipe;
}
+ free_uid(user);
kfree(pipe);
}

@@ -818,6 +853,8 @@ void free_pipe_info(struct pipe_inode_info *pipe)
{
int i;

+ account_pipe_buffers(pipe, pipe->buffers, 0);
+ free_uid(pipe->user);
for (i = 0; i < pipe->buffers; i++) {
struct pipe_buffer *buf = pipe->bufs + i;
if (buf->ops)
@@ -1208,6 +1245,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages)
memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer));
}

+ account_pipe_buffers(pipe, pipe->buffers, nr_pages);
pipe->curbuf = 0;
kfree(pipe->bufs);
pipe->bufs = bufs;
@@ -1279,6 +1317,11 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg)
if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) {
ret = -EPERM;
goto out;
+ } else if ((too_many_pipe_buffers_hard(pipe->user) ||
+ too_many_pipe_buffers_soft(pipe->user)) &&
+ !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+ ret = -EPERM;
+ goto out;
}
ret = pipe_set_size(pipe, nr_pages);
break;
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index ab5752692113..b3374f63bc36 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -42,6 +42,7 @@ struct pipe_buffer {
* @fasync_readers: reader side fasync
* @fasync_writers: writer side fasync
* @bufs: the circular array of pipe buffers
+ * @user: the user who created this pipe
**/
struct pipe_inode_info {
struct mutex mutex;
@@ -57,6 +58,7 @@ struct pipe_inode_info {
struct fasync_struct *fasync_readers;
struct fasync_struct *fasync_writers;
struct pipe_buffer *bufs;
+ struct user_struct *user;
};

/*
@@ -140,6 +142,8 @@ void pipe_unlock(struct pipe_inode_info *);
void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);

extern unsigned int pipe_max_size, pipe_min_size;
+extern unsigned long pipe_user_pages_hard;
+extern unsigned long pipe_user_pages_soft;
int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);


diff --git a/include/linux/sched.h b/include/linux/sched.h
index 3ecea51ea060..2bc93e252fef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -665,6 +665,7 @@ struct user_struct {
#endif
unsigned long locked_shm; /* How many pages of mlocked shm ? */
unsigned long unix_inflight; /* How many files in flight in unix sockets */
+ atomic_long_t pipe_bufs; /* how many pages are allocated in pipe buffers */

#ifdef CONFIG_KEYS
struct key *uid_keyring; /* UID specific keyring */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 6a9b0c42fb30..37b95a2982af 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1637,6 +1637,20 @@ static struct ctl_table fs_table[] = {
.proc_handler = &pipe_proc_fn,
.extra1 = &pipe_min_size,
},
+ {
+ .procname = "pipe-user-pages-hard",
+ .data = &pipe_user_pages_hard,
+ .maxlen = sizeof(pipe_user_pages_hard),
+ .mode = 0644,
+ .proc_handler = proc_doulongvec_minmax,
+ },
+ {
+ .procname = "pipe-user-pages-soft",
+ .data = &pipe_user_pages_soft,
+ .maxlen = sizeof(pipe_user_pages_soft),
+ .mode = 0644,
+ .proc_handler = proc_doulongvec_minmax,
+ },
{ }
};

--
2.8.1

2016-04-22 11:11:09

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 65/78] mmc: Allow forward compatibility for eMMC

From: Romain Izard <[email protected]>

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

===============

commit 03a59437ef6b6ad7fb0165cb9b96c08d6bf057fc upstream.

As stated by the eMMC 5.0 specification, a chip should not be rejected
only because of the revision stated in the EXT_CSD_REV field of the
EXT_CSD register.

Remove the control on this value, the control of the CSD_STRUCTURE field
should be sufficient to reject future incompatible changes.

Signed-off-by: Romain Izard <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/mmc/core/mmc.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 6d02012a1d0b..36d6701de972 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -292,13 +292,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
}
}

+ /*
+ * The EXT_CSD format is meant to be forward compatible. As long
+ * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
+ * are authorized, see JEDEC JESD84-B50 section B.8.
+ */
card->ext_csd.rev = ext_csd[EXT_CSD_REV];
- if (card->ext_csd.rev > 7) {
- pr_err("%s: unrecognised EXT_CSD revision %d\n",
- mmc_hostname(card->host), card->ext_csd.rev);
- err = -EINVAL;
- goto out;
- }

card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
--
2.8.1

2016-04-22 11:11:08

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 67/78] SUNRPC: Fix large reads on NFS/RDMA

From: Chuck Lever <[email protected]>

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

===============

commit 2b7bbc963da8d076f263574af4138b5df2e1581f upstream.

After commit a11a2bf4, "SUNRPC: Optimise away unnecessary data moves
in xdr_align_pages", Thu Aug 2 13:21:43 2012, READs larger than a
few hundred bytes via NFS/RDMA no longer work. This commit exposed
a long-standing bug in rpcrdma_inline_fixup().

I reproduce this with an rsize=4096 mount using the cthon04 basic
tests. Test 5 fails with an EIO error.

For my reproducer, kernel log shows:

NFS: server cheating in read reply: count 4096 > recvd 0

rpcrdma_inline_fixup() is zeroing the xdr_stream::page_len field,
and xdr_align_pages() is now returning that value to the READ XDR
decoder function.

That field is set up by xdr_inline_pages() by the READ XDR encoder
function. As far as I can tell, it is supposed to be left alone
after that, as it describes the dimensions of the reply xdr_stream,
not the contents of that stream.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=68391
Signed-off-by: Chuck Lever <[email protected]>
Signed-off-by: Trond Myklebust <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sunrpc/xprtrdma/rpc_rdma.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index e03725bfe2b8..96ead526b125 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -649,9 +649,7 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
break;
page_base = 0;
}
- rqst->rq_rcv_buf.page_len = olen - copy_len;
- } else
- rqst->rq_rcv_buf.page_len = 0;
+ }

if (copy_len && rqst->rq_rcv_buf.tail[0].iov_len) {
curlen = copy_len;
--
2.8.1

2016-04-22 11:11:40

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 66/78] ALSA: timer: Sync timer deletion at closing the system timer

From: Takashi Iwai <[email protected]>

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

===============

commit f146357f069e71aff8e474c625bcebcd3094b3ab upstream.

ALSA timer core framework has no sync point at stopping because it's
called inside the spinlock. Thus we need a sync point at close for
avoiding the stray timer task. This is simply done by implementing
the close callback just calling del_timer_sync(). (It's harmless to
call it unconditionally, as the core timer itself cares of the already
deleted timer instance.)

Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/core/timer.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 38742e826900..10463beae4bb 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1033,11 +1033,21 @@ static int snd_timer_s_stop(struct snd_timer * timer)
return 0;
}

+static int snd_timer_s_close(struct snd_timer *timer)
+{
+ struct snd_timer_system_private *priv;
+
+ priv = (struct snd_timer_system_private *)timer->private_data;
+ del_timer_sync(&priv->tlist);
+ return 0;
+}
+
static struct snd_timer_hardware snd_timer_system =
{
.flags = SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
.resolution = 1000000000L / HZ,
.ticks = 10000000L,
+ .close = snd_timer_s_close,
.start = snd_timer_s_start,
.stop = snd_timer_s_stop
};
--
2.8.1

2016-04-22 11:11:53

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 64/78] fs, seqfile: always allow oom killer

From: Greg Thelen <[email protected]>

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

===============

commit 0f930902eb8806cff8dcaef9ff9faf3cfa5fd748 upstream.

Since 5cec38ac866b ("fs, seq_file: fallback to vmalloc instead of oom kill
processes") seq_buf_alloc() avoids calling the oom killer for PAGE_SIZE or
smaller allocations; but larger allocations can use the oom killer via
vmalloc(). Thus reads of small files can return ENOMEM, but larger files
use the oom killer to avoid ENOMEM.

The effect of this bug is that reads from /proc and other virtual
filesystems can return ENOMEM instead of the preferred behavior - oom
killing something (possibly the calling process). I don't know of anyone
except Google who has noticed the issue.

I suspect the fix is more needed in smaller systems where there isn't any
reclaimable memory. But these seem like the kinds of systems which
probably don't use the oom killer for production situations.

Memory overcommit requires use of the oom killer to select a victim
regardless of file size.

Enable oom killer for small seq_buf_alloc() allocations.

Fixes: 5cec38ac866b ("fs, seq_file: fallback to vmalloc instead of oom kill processes")
Signed-off-by: David Rientjes <[email protected]>
Signed-off-by: Greg Thelen <[email protected]>
Acked-by: Eric Dumazet <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/seq_file.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 96ae14abce98..a3e41be17e5e 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -35,12 +35,17 @@ static void seq_set_overflow(struct seq_file *m)
static void *seq_buf_alloc(unsigned long size)
{
void *buf;
+ gfp_t gfp = GFP_KERNEL;

/*
- * __GFP_NORETRY to avoid oom-killings with high-order allocations -
- * it's better to fall back to vmalloc() than to kill things.
+ * For high order allocations, use __GFP_NORETRY to avoid oom-killing -
+ * it's better to fall back to vmalloc() than to kill things. For small
+ * allocations, just use GFP_KERNEL which will oom kill, thus no need
+ * for vmalloc fallback.
*/
- buf = kmalloc(size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
+ if (size > PAGE_SIZE)
+ gfp |= __GFP_NORETRY | __GFP_NOWARN;
+ buf = kmalloc(size, gfp);
if (!buf && size > PAGE_SIZE)
buf = vmalloc(size);
return buf;
--
2.8.1

2016-04-22 11:12:10

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 63/78] fs, seq_file: fallback to vmalloc instead of oom kill processes

From: David Rientjes <[email protected]>

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

===============

commit 5cec38ac866bfb8775638e71a86e4d8cac30caae upstream.

Since commit 058504edd026 ("fs/seq_file: fallback to vmalloc allocation"),
seq_buf_alloc() falls back to vmalloc() when the kmalloc() for contiguous
memory fails. This was done to address order-4 slab allocations for
reading /proc/stat on large machines and noticed because
PAGE_ALLOC_COSTLY_ORDER < 4, so there is no infinite loop in the page
allocator when allocating new slab for such high-order allocations.

Contiguous memory isn't necessary for caller of seq_buf_alloc(), however.
Other GFP_KERNEL high-order allocations that are <=
PAGE_ALLOC_COSTLY_ORDER will simply loop forever in the page allocator and
oom kill processes as a result.

We don't want to kill processes so that we can allocate contiguous memory
in situations when contiguous memory isn't necessary.

This patch does the kmalloc() allocation with __GFP_NORETRY for high-order
allocations. This still utilizes memory compaction and direct reclaim in
the allocation path, the only difference is that it will fail immediately
instead of oom kill processes when out of memory.

[[email protected]: add comment]
Signed-off-by: David Rientjes <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/seq_file.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/seq_file.c b/fs/seq_file.c
index 6e050e26af43..96ae14abce98 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -36,7 +36,11 @@ static void *seq_buf_alloc(unsigned long size)
{
void *buf;

- buf = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);
+ /*
+ * __GFP_NORETRY to avoid oom-killings with high-order allocations -
+ * it's better to fall back to vmalloc() than to kill things.
+ */
+ buf = kmalloc(size, GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN);
if (!buf && size > PAGE_SIZE)
buf = vmalloc(size);
return buf;
--
2.8.1

2016-04-22 11:06:34

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 45/78] drm/radeon: add a dpm quirk for all R7 370 parts

From: Alex Deucher <[email protected]>

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

===============

commit 0e5585dc870af947fab2af96a88c2d8b4270247c upstream.

Higher mclk values are not stable due to a bug somewhere.
Limit them for now.

Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/si_dpm.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 34527c050062..393217886d98 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -3008,6 +3008,10 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
ps->performance_levels[i].sclk = max_sclk;
}
}
+ /* limit mclk on all R7 370 parts for stability */
+ if (rdev->pdev->device == 0x6811 &&
+ rdev->pdev->revision == 0x81)
+ max_mclk = 120000;

/* XXX validate the min clocks required for display */

--
2.8.1

2016-04-22 11:12:33

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 62/78] cdc_ncm: do not call usbnet_link_change from cdc_ncm_bind

From: Bjørn Mork <[email protected]>

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

===============

commit 4d06dd537f95683aba3651098ae288b7cbff8274 upstream.

usbnet_link_change will call schedule_work and should be
avoided if bind is failing. Otherwise we will end up with
scheduled work referring to a netdev which has gone away.

Instead of making the call conditional, we can just defer
it to usbnet_probe, using the driver_info flag made for
this purpose.

Fixes: 8a34b0ae8778 ("usbnet: cdc_ncm: apply usbnet_link_change")
Reported-by: Andrey Konovalov <[email protected]>
Suggested-by: Linus Torvalds <[email protected]>
Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/cdc_ncm.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 74581cbcafa7..6ee9665e20b2 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -598,24 +598,13 @@ EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting);

static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
{
- int ret;
-
/* MBIM backwards compatible function? */
cdc_ncm_select_altsetting(dev, intf);
if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
return -ENODEV;

/* NCM data altsetting is always 1 */
- ret = cdc_ncm_bind_common(dev, intf, 1);
-
- /*
- * We should get an event when network connection is "connected" or
- * "disconnected". Set network connection in "disconnected" state
- * (carrier is OFF) during attach, so the IP network stack does not
- * start IPv6 negotiation and more.
- */
- usbnet_link_change(dev, 0, 0);
- return ret;
+ return cdc_ncm_bind_common(dev, intf, 1);
}

static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remainder, size_t max)
@@ -1161,7 +1150,8 @@ static void cdc_ncm_disconnect(struct usb_interface *intf)

static const struct driver_info cdc_ncm_info = {
.description = "CDC NCM",
- .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET,
+ .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
+ | FLAG_LINK_INTR,
.bind = cdc_ncm_bind,
.unbind = cdc_ncm_unbind,
.check_connect = cdc_ncm_check_connect,
@@ -1175,7 +1165,7 @@ static const struct driver_info cdc_ncm_info = {
static const struct driver_info wwan_info = {
.description = "Mobile Broadband Network Device",
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
- | FLAG_WWAN,
+ | FLAG_LINK_INTR | FLAG_WWAN,
.bind = cdc_ncm_bind,
.unbind = cdc_ncm_unbind,
.check_connect = cdc_ncm_check_connect,
@@ -1189,7 +1179,7 @@ static const struct driver_info wwan_info = {
static const struct driver_info wwan_noarp_info = {
.description = "Mobile Broadband Network Device (NO ARP)",
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET
- | FLAG_WWAN | FLAG_NOARP,
+ | FLAG_LINK_INTR | FLAG_WWAN | FLAG_NOARP,
.bind = cdc_ncm_bind,
.unbind = cdc_ncm_unbind,
.check_connect = cdc_ncm_check_connect,
--
2.8.1

2016-04-22 11:12:54

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 59/78] ext4: fix NULL pointer dereference in ext4_mark_inode_dirty()

From: Eryu Guan <[email protected]>

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

===============

commit 5e1021f2b6dff1a86a468a1424d59faae2bc63c1 upstream.

ext4_reserve_inode_write() in ext4_mark_inode_dirty() could fail on
error (e.g. EIO) and iloc.bh can be NULL in this case. But the error is
ignored in the following "if" condition and ext4_expand_extra_isize()
might be called with NULL iloc.bh set, which triggers NULL pointer
dereference.

This is uncovered by commit 8b4953e13f4c ("ext4: reserve code points for
the project quota feature"), which enlarges the ext4_inode size, and
run the following script on new kernel but with old mke2fs:

#/bin/bash
mnt=/mnt/ext4
devname=ext4-error
dev=/dev/mapper/$devname
fsimg=/home/fs.img

trap cleanup 0 1 2 3 9 15

cleanup()
{
umount $mnt >/dev/null 2>&1
dmsetup remove $devname
losetup -d $backend_dev
rm -f $fsimg
exit 0
}

rm -f $fsimg
fallocate -l 1g $fsimg
backend_dev=`losetup -f --show $fsimg`
devsize=`blockdev --getsz $backend_dev`

good_tab="0 $devsize linear $backend_dev 0"
error_tab="0 $devsize error $backend_dev 0"

dmsetup create $devname --table "$good_tab"

mkfs -t ext4 $dev
mount -t ext4 -o errors=continue,strictatime $dev $mnt

dmsetup load $devname --table "$error_tab" && dmsetup resume $devname
echo 3 > /proc/sys/vm/drop_caches
ls -l $mnt
exit 0

[ Patch changed to simplify the function a tiny bit. -- Ted ]

Signed-off-by: Eryu Guan <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ext4/inode.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1ee06f9cdde1..cf5070bb8695 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4974,6 +4974,8 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
might_sleep();
trace_ext4_mark_inode_dirty(inode, _RET_IP_);
err = ext4_reserve_inode_write(handle, inode, &iloc);
+ if (err)
+ return err;
if (ext4_handle_valid(handle) &&
EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&
!ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {
@@ -5004,9 +5006,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
}
}
}
- if (!err)
- err = ext4_mark_iloc_dirty(handle, inode, &iloc);
- return err;
+ return ext4_mark_iloc_dirty(handle, inode, &iloc);
}

/*
--
2.8.1

2016-04-22 11:12:53

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 60/78] usb: gadget: f_midi: Fixed a bug when buflen was smaller than wMaxPacketSize

From: "Felipe F. Tonello" <[email protected]>

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

===============

commit 03d27ade4941076b34c823d63d91dc895731a595 upstream.

buflen by default (256) is smaller than wMaxPacketSize (512) in high-speed
devices.

That caused the OUT endpoint to freeze if the host send any data packet of
length greater than 256 bytes.

This is an example dump of what happended on that enpoint:
HOST: [DATA][Length=260][...]
DEVICE: [NAK]
HOST: [PING]
DEVICE: [NAK]
HOST: [PING]
DEVICE: [NAK]
...
HOST: [PING]
DEVICE: [NAK]

This patch fixes this problem by setting the minimum usb_request's buffer size
for the OUT endpoint as its wMaxPacketSize.

Acked-by: Michal Nazarewicz <[email protected]>
Signed-off-by: Felipe F. Tonello <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
Cc: Oliver Neukum <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/gadget/f_midi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c
index 263e721c2694..e7f1b967a5bb 100644
--- a/drivers/usb/gadget/f_midi.c
+++ b/drivers/usb/gadget/f_midi.c
@@ -365,7 +365,9 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
/* allocate a bunch of read buffers and queue them all at once. */
for (i = 0; i < midi->qlen && err == 0; i++) {
struct usb_request *req =
- alloc_ep_req(midi->out_ep, midi->buflen);
+ alloc_ep_req(midi->out_ep,
+ max_t(unsigned, midi->buflen,
+ bulk_out_desc.wMaxPacketSize));
if (req == NULL)
return -ENOMEM;

--
2.8.1

2016-04-22 11:06:31

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 46/78] xen/events: introduce test_and_set_mask()

From: Wei Liu <[email protected]>

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

===============

commit 3f70fa828249e3f37883be98f5b4d08e947f55b0 upstream.

In preparation for adding event channel port ops, add
test_and_set_mask().

Signed-off-by: Wei Liu <[email protected]>
Signed-off-by: David Vrabel <[email protected]>
Reviewed-by: Konrad Rzeszutek Wilk <[email protected]>
Reviewed-by: Boris Ostrovsky <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/xen/events.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 767fe735abd7..bd12a6660fe3 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -370,6 +370,12 @@ static inline int test_evtchn(int port)
return sync_test_bit(port, BM(&s->evtchn_pending[0]));
}

+static inline int test_and_set_mask(int port)
+{
+ struct shared_info *s = HYPERVISOR_shared_info;
+ return sync_test_and_set_bit(port, BM(&s->evtchn_mask[0]));
+}
+

/**
* notify_remote_via_irq - send event to remote end of event channel via irq
@@ -1515,7 +1521,6 @@ void rebind_evtchn_irq(int evtchn, int irq)
/* Rebind an evtchn so that it gets delivered to a specific cpu */
static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
{
- struct shared_info *s = HYPERVISOR_shared_info;
struct evtchn_bind_vcpu bind_vcpu;
int evtchn = evtchn_from_irq(irq);
int masked;
@@ -1538,7 +1543,7 @@ static int rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
* Mask the event while changing the VCPU binding to prevent
* it being delivered on an unexpected VCPU.
*/
- masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask));
+ masked = test_and_set_mask(evtchn);

/*
* If this fails, it usually just indicates that we're dealing with a
@@ -1570,7 +1575,7 @@ int resend_irq_on_evtchn(unsigned int irq)
if (!VALID_EVTCHN(evtchn))
return 1;

- masked = sync_test_and_set_bit(evtchn, BM(s->evtchn_mask));
+ masked = test_and_set_mask(evtchn);
sync_set_bit(evtchn, BM(s->evtchn_pending));
if (!masked)
unmask_evtchn(evtchn);
--
2.8.1

2016-04-22 11:13:45

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 58/78] jme: Fix device PM wakeup API usage

From: Guo-Fu Tseng <[email protected]>

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

===============

commit 81422e672f8181d7ad1ee6c60c723aac649f538f upstream.

According to Documentation/power/devices.txt

The driver should not use device_set_wakeup_enable() which is the policy
for user to decide.

Using device_init_wakeup() to initialize dev->power.should_wakeup and
dev->power.can_wakeup on driver initialization.

And use device_may_wakeup() on suspend to decide if WoL function should
be enabled on NIC.

Reported-by: Diego Viola <[email protected]>
Signed-off-by: Guo-Fu Tseng <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/jme.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 3291bf72e998..54112f9d6209 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1935,7 +1935,7 @@ jme_wait_link(struct jme_adapter *jme)
static void
jme_powersave_phy(struct jme_adapter *jme)
{
- if (jme->reg_pmcs) {
+ if (jme->reg_pmcs && device_may_wakeup(&jme->pdev->dev)) {
jme_set_100m_half(jme);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
@@ -2627,8 +2627,6 @@ jme_set_wol(struct net_device *netdev,
if (wol->wolopts & WAKE_MAGIC)
jme->reg_pmcs |= PMCS_MFEN;

- device_set_wakeup_enable(&jme->pdev->dev, !!(jme->reg_pmcs));
-
return 0;
}

@@ -3153,7 +3151,7 @@ jme_init_one(struct pci_dev *pdev,
jme->mii_if.mdio_write = jme_mdio_write;

jme_clear_pm_disable_wol(jme);
- device_set_wakeup_enable(&pdev->dev, true);
+ device_init_wakeup(&pdev->dev, true);

jme_set_phyfifo_5level(jme);
jme->pcirev = pdev->revision;
--
2.8.1

2016-04-22 11:14:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 56/78] usbvision: fix crash on detecting device with invalid configuration

From: Vladis Dronov <[email protected]>

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

===============

commit fa52bd506f274b7619955917abfde355e3d19ffe upstream.

The usbvision driver crashes when a specially crafted usb device with invalid
number of interfaces or endpoints is detected. This fix adds checks that the
device has proper configuration expected by the driver.

Reported-by: Ralf Spenneberg <[email protected]>
Signed-off-by: Vladis Dronov <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/usb/usbvision/usbvision-video.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 632a3f117c88..d4a222ea8197 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1548,9 +1548,23 @@ static int usbvision_probe(struct usb_interface *intf,

if (usbvision_device_data[model].interface >= 0)
interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
- else
+ else if (ifnum < dev->actconfig->desc.bNumInterfaces)
interface = &dev->actconfig->interface[ifnum]->altsetting[0];
+ else {
+ dev_err(&intf->dev, "interface %d is invalid, max is %d\n",
+ ifnum, dev->actconfig->desc.bNumInterfaces - 1);
+ ret = -ENODEV;
+ goto err_usb;
+ }
+
+ if (interface->desc.bNumEndpoints < 2) {
+ dev_err(&intf->dev, "interface %d has %d endpoints, but must"
+ " have minimum 2\n", ifnum, interface->desc.bNumEndpoints);
+ ret = -ENODEV;
+ goto err_usb;
+ }
endpoint = &interface->endpoint[1].desc;
+
if (!usb_endpoint_xfer_isoc(endpoint)) {
dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
__func__, ifnum);
--
2.8.1

2016-04-22 11:14:06

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 55/78] usbvision: fix leak of usb_dev on failure paths in usbvision_probe()

From: Alexey Khoroshilov <[email protected]>

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

===============

commit afd270d1a45043cef14341bcceff62ed50e8dc9a upstream.

There is no usb_put_dev() on failure paths in usbvision_probe().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/media/usb/usbvision/usbvision-video.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 3cf12da58787..632a3f117c88 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1524,7 +1524,7 @@ static int usbvision_probe(struct usb_interface *intf,
const struct usb_host_interface *interface;
struct usb_usbvision *usbvision = NULL;
const struct usb_endpoint_descriptor *endpoint;
- int model, i;
+ int model, i, ret;

PDEBUG(DBG_PROBE, "VID=%#04x, PID=%#04x, ifnum=%u",
dev->descriptor.idVendor,
@@ -1533,7 +1533,8 @@ static int usbvision_probe(struct usb_interface *intf,
model = devid->driver_info;
if (model < 0 || model >= usbvision_device_data_size) {
PDEBUG(DBG_PROBE, "model out of bounds %d", model);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_usb;
}
printk(KERN_INFO "%s: %s found\n", __func__,
usbvision_device_data[model].model_string);
@@ -1555,18 +1556,21 @@ static int usbvision_probe(struct usb_interface *intf,
__func__, ifnum);
dev_err(&intf->dev, "%s: Endpoint attributes %d",
__func__, endpoint->bmAttributes);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_usb;
}
if (usb_endpoint_dir_out(endpoint)) {
dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
__func__, ifnum);
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_usb;
}

usbvision = usbvision_alloc(dev, intf);
if (usbvision == NULL) {
dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_usb;
}

if (dev->descriptor.bNumConfigurations > 1)
@@ -1585,8 +1589,8 @@ static int usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
dev_err(&intf->dev, "usbvision: out of memory!\n");
- usbvision_release(usbvision);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto err_pkt;
}

for (i = 0; i < usbvision->num_alt; i++) {
@@ -1621,6 +1625,12 @@ static int usbvision_probe(struct usb_interface *intf,

PDEBUG(DBG_PROBE, "success");
return 0;
+
+err_pkt:
+ usbvision_release(usbvision);
+err_usb:
+ usb_put_dev(dev);
+ return ret;
}


--
2.8.1

2016-04-22 11:14:42

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 54/78] drm/radeon: hold reference to fences in radeon_sa_bo_new (3.17 and older)

From: Nicolai Hähnle <[email protected]>

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

===============

[Backport of upstream commit f6ff4f67cdf8455d0a4226eeeaf5af17c37d05eb, with
an additional NULL pointer guard that is required for kernels 3.17 and older.

To be precise, any kernel that does *not* have commit 954605ca3 "drm/radeon:
use common fence implementation for fences, v4" requires this additional
NULL pointer guard.]

An arbitrary amount of time can pass between spin_unlock and
radeon_fence_wait_any, so we need to ensure that nobody frees the
fences from under us.

Based on the analogous fix for amdgpu.

Signed-off-by: Nicolai Hähnle <[email protected]>
Reviewed-by: Christian König <[email protected]> (v1 + fix)
Tested-by: Lutz Euler <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/gpu/drm/radeon/radeon_sa.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c
index f0bac68254b7..8962411b5f2b 100644
--- a/drivers/gpu/drm/radeon/radeon_sa.c
+++ b/drivers/gpu/drm/radeon/radeon_sa.c
@@ -349,8 +349,15 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
/* see if we can skip over some allocations */
} while (radeon_sa_bo_next_hole(sa_manager, fences, tries));

+ for (i = 0; i < RADEON_NUM_RINGS; ++i) {
+ if (fences[i])
+ radeon_fence_ref(fences[i]);
+ }
+
spin_unlock(&sa_manager->wq.lock);
r = radeon_fence_wait_any(rdev, fences, false);
+ for (i = 0; i < RADEON_NUM_RINGS; ++i)
+ radeon_fence_unref(&fences[i]);
spin_lock(&sa_manager->wq.lock);
/* if we have nothing to wait for block */
if (r == -ENOENT && block) {
--
2.8.1

2016-04-22 11:14:41

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 53/78] HID: usbhid: fix inconsistent reset/resume/reset-resume behavior

From: Alan Stern <[email protected]>

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

===============

commit 972e6a993f278b416a8ee3ec65475724fc36feb2 upstream.

The usbhid driver has inconsistently duplicated code in its post-reset,
resume, and reset-resume pathways.

reset-resume doesn't check HID_STARTED before trying to
restart the I/O queues.

resume fails to clear the HID_SUSPENDED flag if HID_STARTED
isn't set.

resume calls usbhid_restart_queues() with usbhid->lock held
and the others call it without holding the lock.

The first item in particular causes a problem following a reset-resume
if the driver hasn't started up its I/O. URB submission fails because
usbhid->urbin is NULL, and this triggers an unending reset-retry loop.

This patch fixes the problem by creating a new subroutine,
hid_restart_io(), to carry out all the common activities. It also
adds some checks that were missing in the original code:

After a reset, there's no need to clear any halted endpoints.

After a resume, if a reset is pending there's no need to
restart any I/O until the reset is finished.

After a resume, if the interrupt-IN endpoint is halted there's
no need to submit the input URB until the halt has been
cleared.

Signed-off-by: Alan Stern <[email protected]>
Reported-by: Daniel Fraga <[email protected]>
Tested-by: Daniel Fraga <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/hid/usbhid/hid-core.c | 73 ++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 183a3e9b1ccc..f623ef0f695d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -941,14 +941,6 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
return ret;
}

-static void usbhid_restart_queues(struct usbhid_device *usbhid)
-{
- if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
- usbhid_restart_out_queue(usbhid);
- if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
- usbhid_restart_ctrl_queue(usbhid);
-}
-
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
@@ -1380,6 +1372,37 @@ static void hid_cease_io(struct usbhid_device *usbhid)
usb_kill_urb(usbhid->urbout);
}

+static void hid_restart_io(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+ int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl);
+ int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl);
+
+ spin_lock_irq(&usbhid->lock);
+ clear_bit(HID_SUSPENDED, &usbhid->iofl);
+ usbhid_mark_busy(usbhid);
+
+ if (clear_halt || reset_pending)
+ schedule_work(&usbhid->reset_work);
+ usbhid->retry_delay = 0;
+ spin_unlock_irq(&usbhid->lock);
+
+ if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl))
+ return;
+
+ if (!clear_halt) {
+ if (hid_start_in(hid) < 0)
+ hid_io_error(hid);
+ }
+
+ spin_lock_irq(&usbhid->lock);
+ if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
+ usbhid_restart_out_queue(usbhid);
+ if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
+ usbhid_restart_ctrl_queue(usbhid);
+ spin_unlock_irq(&usbhid->lock);
+}
+
/* Treat USB reset pretty much the same as suspend/resume */
static int hid_pre_reset(struct usb_interface *intf)
{
@@ -1429,14 +1452,14 @@ static int hid_post_reset(struct usb_interface *intf)
return 1;
}

+ /* No need to do another reset or clear a halted endpoint */
spin_lock_irq(&usbhid->lock);
clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+ clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
spin_unlock_irq(&usbhid->lock);
hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
- status = hid_start_in(hid);
- if (status < 0)
- hid_io_error(hid);
- usbhid_restart_queues(usbhid);
+
+ hid_restart_io(hid);

return 0;
}
@@ -1459,25 +1482,9 @@ void usbhid_put_power(struct hid_device *hid)
#ifdef CONFIG_PM
static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
{
- struct usbhid_device *usbhid = hid->driver_data;
- int status;
-
- spin_lock_irq(&usbhid->lock);
- clear_bit(HID_SUSPENDED, &usbhid->iofl);
- usbhid_mark_busy(usbhid);
-
- if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
- test_bit(HID_RESET_PENDING, &usbhid->iofl))
- schedule_work(&usbhid->reset_work);
- usbhid->retry_delay = 0;
-
- usbhid_restart_queues(usbhid);
- spin_unlock_irq(&usbhid->lock);
-
- status = hid_start_in(hid);
- if (status < 0)
- hid_io_error(hid);
+ int status = 0;

+ hid_restart_io(hid);
if (driver_suspended && hid->driver && hid->driver->resume)
status = hid->driver->resume(hid);
return status;
@@ -1546,12 +1553,8 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
static int hid_resume(struct usb_interface *intf)
{
struct hid_device *hid = usb_get_intfdata (intf);
- struct usbhid_device *usbhid = hid->driver_data;
int status;

- if (!test_bit(HID_STARTED, &usbhid->iofl))
- return 0;
-
status = hid_resume_common(hid, true);
dev_dbg(&intf->dev, "resume status %d\n", status);
return 0;
@@ -1560,10 +1563,8 @@ static int hid_resume(struct usb_interface *intf)
static int hid_reset_resume(struct usb_interface *intf)
{
struct hid_device *hid = usb_get_intfdata(intf);
- struct usbhid_device *usbhid = hid->driver_data;
int status;

- clear_bit(HID_SUSPENDED, &usbhid->iofl);
status = hid_post_reset(intf);
if (status >= 0 && hid->driver && hid->driver->reset_resume) {
int ret = hid->driver->reset_resume(hid);
--
2.8.1

2016-04-22 11:15:15

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 52/78] perf: Cure event->pending_disable race

From: Peter Zijlstra <[email protected]>

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

===============

commit 28a967c3a2f99fa3b5f762f25cb2a319d933571b upstream.

Because event_sched_out() checks event->pending_disable _before_
actually disabling the event, it can happen that the event fires after
it checks but before it gets disabled.

This would leave event->pending_disable set and the queued irq_work
will try and process it.

However, if the event trigger was during schedule(), the event might
have been de-scheduled by the time the irq_work runs, and
perf_event_disable_local() will fail.

Fix this by checking event->pending_disable _after_ we call
event->pmu->del(). This depends on the latter being a compiler
barrier, such that the compiler does not lift the load and re-creates
the problem.

Tested-by: Alexander Shishkin <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Alexander Shishkin <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
kernel/events/core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index b9c4a60f5137..0b3c09a3f7b6 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1389,14 +1389,14 @@ event_sched_out(struct perf_event *event,
if (event->state != PERF_EVENT_STATE_ACTIVE)
return;

+ event->tstamp_stopped = tstamp;
+ event->pmu->del(event, 0);
+ event->oncpu = -1;
event->state = PERF_EVENT_STATE_INACTIVE;
if (event->pending_disable) {
event->pending_disable = 0;
event->state = PERF_EVENT_STATE_OFF;
}
- event->tstamp_stopped = tstamp;
- event->pmu->del(event, 0);
- event->oncpu = -1;

if (!is_software_event(event))
cpuctx->active_oncpu--;
--
2.8.1

2016-04-22 11:15:59

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 51/78] ext4: add lockdep annotations for i_data_sem

From: Theodore Ts'o <[email protected]>

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

===============

commit daf647d2dd58cec59570d7698a45b98e580f2076 upstream.

With the internal Quota feature, mke2fs creates empty quota inodes and
quota usage tracking is enabled as soon as the file system is mounted.
Since quotacheck is no longer preallocating all of the blocks in the
quota inode that are likely needed to be written to, we are now seeing
a lockdep false positive caused by needing to allocate a quota block
from inside ext4_map_blocks(), while holding i_data_sem for a data
inode. This results in this complaint:

Possible unsafe locking scenario:

CPU0 CPU1
---- ----
lock(&ei->i_data_sem);
lock(&s->s_dquot.dqio_mutex);
lock(&ei->i_data_sem);
lock(&s->s_dquot.dqio_mutex);

Google-Bug-Id: 27907753

Signed-off-by: Theodore Ts'o <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
fs/ext4/ext4.h | 23 +++++++++++++++++++++++
fs/ext4/move_extent.c | 11 +++++++++--
fs/ext4/super.c | 25 +++++++++++++++++++++++--
3 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 11c7cb060a55..66d2dc9ef561 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -846,6 +846,29 @@ do { \
#include "extents_status.h"

/*
+ * Lock subclasses for i_data_sem in the ext4_inode_info structure.
+ *
+ * These are needed to avoid lockdep false positives when we need to
+ * allocate blocks to the quota inode during ext4_map_blocks(), while
+ * holding i_data_sem for a normal (non-quota) inode. Since we don't
+ * do quota tracking for the quota inode, this avoids deadlock (as
+ * well as infinite recursion, since it isn't turtles all the way
+ * down...)
+ *
+ * I_DATA_SEM_NORMAL - Used for most inodes
+ * I_DATA_SEM_OTHER - Used by move_inode.c for the second normal inode
+ * where the second inode has larger inode number
+ * than the first
+ * I_DATA_SEM_QUOTA - Used for quota inodes only
+ */
+enum {
+ I_DATA_SEM_NORMAL = 0,
+ I_DATA_SEM_OTHER,
+ I_DATA_SEM_QUOTA,
+};
+
+
+/*
* fourth extended file system inode data in memory
*/
struct ext4_inode_info {
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 7fa4d855dbd5..7a8a18e22476 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -154,10 +154,10 @@ ext4_double_down_write_data_sem(struct inode *first, struct inode *second)
{
if (first < second) {
down_write(&EXT4_I(first)->i_data_sem);
- down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
+ down_write_nested(&EXT4_I(second)->i_data_sem, I_DATA_SEM_OTHER);
} else {
down_write(&EXT4_I(second)->i_data_sem);
- down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
+ down_write_nested(&EXT4_I(first)->i_data_sem, I_DATA_SEM_OTHER);

}
}
@@ -1114,6 +1114,13 @@ mext_check_arguments(struct inode *orig_inode,
return -EINVAL;
}

+ if (IS_NOQUOTA(orig_inode) || IS_NOQUOTA(donor_inode)) {
+ ext4_debug("ext4 move extent: The argument files should "
+ "not be quota files [ino:orig %lu, donor %lu]\n",
+ orig_inode->i_ino, donor_inode->i_ino);
+ return -EBUSY;
+ }
+
/* Ext4 move extent supports only extent based file */
if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
ext4_debug("ext4 move extent: orig file is not extents "
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 49f45464518f..ab5829f298e7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5090,6 +5090,20 @@ static int ext4_quota_on_mount(struct super_block *sb, int type)
EXT4_SB(sb)->s_jquota_fmt, type);
}

+static void lockdep_set_quota_inode(struct inode *inode, int subclass)
+{
+ struct ext4_inode_info *ei = EXT4_I(inode);
+
+ /* The first argument of lockdep_set_subclass has to be
+ * *exactly* the same as the argument to init_rwsem() --- in
+ * this case, in init_once() --- or lockdep gets unhappy
+ * because the name of the lock is set using the
+ * stringification of the argument to init_rwsem().
+ */
+ (void) ei; /* shut up clang warning if !CONFIG_LOCKDEP */
+ lockdep_set_subclass(&ei->i_data_sem, subclass);
+}
+
/*
* Standard function to be called on quota_on
*/
@@ -5129,8 +5143,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
if (err)
return err;
}
-
- return dquot_quota_on(sb, type, format_id, path);
+ lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA);
+ err = dquot_quota_on(sb, type, format_id, path);
+ if (err)
+ lockdep_set_quota_inode(path->dentry->d_inode,
+ I_DATA_SEM_NORMAL);
+ return err;
}

static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
@@ -5156,8 +5174,11 @@ static int ext4_quota_enable(struct super_block *sb, int type, int format_id,

/* Don't account quota for quota files to avoid recursion */
qf_inode->i_flags |= S_NOQUOTA;
+ lockdep_set_quota_inode(qf_inode, I_DATA_SEM_QUOTA);
err = dquot_enable(qf_inode, type, format_id, flags);
iput(qf_inode);
+ if (err)
+ lockdep_set_quota_inode(qf_inode, I_DATA_SEM_NORMAL);

return err;
}
--
2.8.1

2016-04-22 11:16:27

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 49/78] usb: renesas_usbhs: avoid NULL pointer derefernce in usbhsf_pkt_handler()

From: Yoshihiro Shimoda <[email protected]>

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

===============

commit 894f2fc44f2f3f48c36c973b1123f6ab298be160 upstream.

When unexpected situation happened (e.g. tx/rx irq happened while
DMAC is used), the usbhsf_pkt_handler() was possible to cause NULL
pointer dereference like the followings:

Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 80000007 [#1] SMP ARM
Modules linked in: usb_f_acm u_serial g_serial libcomposite
CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.5.0-rc6-00842-gac57066-dirty #63
Hardware name: Generic R8A7790 (Flattened Device Tree)
task: c0729c00 ti: c0724000 task.ti: c0724000
PC is at 0x0
LR is at usbhsf_pkt_handler+0xac/0x118
pc : [<00000000>] lr : [<c03257e0>] psr: 60000193
sp : c0725db8 ip : 00000000 fp : c0725df4
r10: 00000001 r9 : 00000193 r8 : ef3ccab4
r7 : ef3cca10 r6 : eea4586c r5 : 00000000 r4 : ef19ceb4
r3 : 00000000 r2 : 0000009c r1 : c0725dc4 r0 : ef19ceb4

This patch adds a condition to avoid the dereference.

Fixes: e73a989 ("usb: renesas_usbhs: add DMAEngine support")
Signed-off-by: Yoshihiro Shimoda <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/renesas_usbhs/fifo.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 047f5a30772c..1550c103f8a3 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -166,7 +166,8 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type)
goto __usbhs_pkt_handler_end;
}

- ret = func(pkt, &is_done);
+ if (likely(func))
+ ret = func(pkt, &is_done);

if (is_done)
__usbhsf_pkt_del(pkt);
--
2.8.1

2016-04-22 11:16:26

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 50/78] usb: renesas_usbhs: disable TX IRQ before starting TX DMAC transfer

From: Yoshihiro Shimoda <[email protected]>

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

===============

commit 6490865c67825277b29638e839850882600b48ec upstream.

This patch adds a code to surely disable TX IRQ of the pipe before
starting TX DMAC transfer. Otherwise, a lot of unnecessary TX IRQs
may happen in rare cases when DMAC is used.

Fixes: e73a989 ("usb: renesas_usbhs: add DMAEngine support")
Signed-off-by: Yoshihiro Shimoda <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/usb/renesas_usbhs/fifo.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 1550c103f8a3..13170ed3c392 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -946,6 +946,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)

pkt->trans = len;

+ usbhsf_tx_irq_ctrl(pipe, 0);
INIT_WORK(&pkt->work, xfer_work);
schedule_work(&pkt->work);

--
2.8.1

2016-04-22 11:17:30

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 48/78] mac80211: fix unnecessary frame drops in mesh fwding

From: Michal Kazior <[email protected]>

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

===============

commit cf44012810ccdd8fd947518e965cb04b7b8498be upstream.

The ieee80211_queue_stopped() expects hw queue
number but it was given raw WMM AC number instead.

This could cause frame drops and problems with
traffic in some cases - most notably if driver
doesn't map AC numbers to queue numbers 1:1 and
uses ieee80211_stop_queues() and
ieee80211_wake_queue() only without ever calling
ieee80211_wake_queues().

On ath10k it was possible to hit this problem in
the following case:

1. wlan0 uses queue 0
(ath10k maps queues per vif)
2. offchannel uses queue 15
3. queues 1-14 are unused
4. ieee80211_stop_queues()
5. ieee80211_wake_queue(q=0)
6. ieee80211_wake_queue(q=15)
(other queues are not woken up because both
driver and mac80211 know other queues are
unused)
7. ieee80211_rx_h_mesh_fwding()
8. ieee80211_select_queue_80211() returns 2
9. ieee80211_queue_stopped(q=2) returns true
10. frame is dropped (oops!)

Fixes: d3c1597b8d1b ("mac80211: fix forwarded mesh frame queue mapping")
Signed-off-by: Michal Kazior <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/mac80211/rx.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 198fd6e1f6d4..834a41830778 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2058,7 +2058,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
__le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
- u16 q, hdrlen;
+ u16 ac, q, hdrlen;

hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -2128,7 +2128,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
ether_addr_equal(sdata->vif.addr, hdr->addr3))
return RX_CONTINUE;

- q = ieee80211_select_queue_80211(sdata, skb, hdr);
+ ac = ieee80211_select_queue_80211(sdata, skb, hdr);
+ q = sdata->vif.hw_queue[ac];
if (ieee80211_queue_stopped(&local->hw, q)) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion);
return RX_DROP_MONITOR;
--
2.8.1

2016-04-22 11:17:47

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 41/78] parisc: Fix kernel crash with reversed copy_from_user()

From: Helge Deller <[email protected]>

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

===============

commit ef72f3110d8b19f4c098a0bff7ed7d11945e70c6 upstream.

The kernel module testcase (lib/test_user_copy.c) exhibited a kernel
crash on parisc if the parameters for copy_from_user were reversed
("illegal reversed copy_to_user" testcase).

Fix this potential crash by checking the fault handler if the faulting
address is in the exception table.

Signed-off-by: Helge Deller <[email protected]>
Cc: Kees Cook <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/parisc/kernel/traps.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 1cd1d0c83b6d..cf87b94be7f3 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -806,6 +806,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs)

if (fault_space == 0 && !in_atomic())
{
+ /* Clean up and return if in exception table. */
+ if (fixup_exception(regs))
+ return;
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
parisc_terminate("Kernel Fault", regs, code, fault_address);
}
--
2.8.1

2016-04-22 11:17:46

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 42/78] ALSA: timer: Use mod_timer() for rearming the system timer

From: Takashi Iwai <[email protected]>

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

===============

commit 4a07083ed613644c96c34a7dd2853dc5d7c70902 upstream.

ALSA system timer backend stops the timer via del_timer() without sync
and leaves del_timer_sync() at the close instead. This is because of
the restriction by the design of ALSA timer: namely, the stop callback
may be called from the timer handler, and calling the sync shall lead
to a hangup. However, this also triggers a kernel BUG() when the
timer is rearmed immediately after stopping without sync:
kernel BUG at kernel/time/timer.c:966!
Call Trace:
<IRQ>
[<ffffffff8239c94e>] snd_timer_s_start+0x13e/0x1a0
[<ffffffff8239e1f4>] snd_timer_interrupt+0x504/0xec0
[<ffffffff8122fca0>] ? debug_check_no_locks_freed+0x290/0x290
[<ffffffff8239ec64>] snd_timer_s_function+0xb4/0x120
[<ffffffff81296b72>] call_timer_fn+0x162/0x520
[<ffffffff81296add>] ? call_timer_fn+0xcd/0x520
[<ffffffff8239ebb0>] ? snd_timer_interrupt+0xec0/0xec0
....

It's the place where add_timer() checks the pending timer. It's clear
that this may happen after the immediate restart without sync in our
cases.

So, the workaround here is just to use mod_timer() instead of
add_timer(). This looks like a band-aid fix, but it's a right move,
as snd_timer_interrupt() takes care of the continuous rearm of timer.

Reported-by: Jiri Slaby <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
sound/core/timer.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index d90d8f4b85fe..38742e826900 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1012,8 +1012,8 @@ static int snd_timer_s_start(struct snd_timer * timer)
njiff += timer->sticks - priv->correction;
priv->correction = 0;
}
- priv->last_expires = priv->tlist.expires = njiff;
- add_timer(&priv->tlist);
+ priv->last_expires = njiff;
+ mod_timer(&priv->tlist, njiff);
return 0;
}

--
2.8.1

2016-04-22 11:18:27

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 38/78] USB: qmi_wwan: Add quirk for Quectel EC20 Mini PCIe module

From: Petr Štetiar <[email protected]>

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

===============

commit b3d8cf019fb9dd28389b08da7bf54ffabf453ed3 upstream.

This device has same vendor and product IDs as G2K devices, but it has
different number of interfaces(4 vs 5) and also different interface
layout where EC20 has QMI on interface 4 instead of 0.

lsusb output:

Bus 002 Device 003: ID 05c6:9215 Qualcomm, Inc. Acer Gobi 2000
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x05c6 Qualcomm, Inc.
idProduct 0x9215 Acer Gobi 2000 Wireless Modem
bcdDevice 2.32
iManufacturer 1 Quectel
iProduct 2 Quectel LTE Module
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 209
bNumInterfaces 5
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 500mA

Signed-off-by: Petr Štetiar <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 3e146ee2f2a9..18101e3fcd04 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -817,6 +817,7 @@ static const struct usb_device_id products[] = {
{QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */
{QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
+ {QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */
{QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */
{QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */
{QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */
@@ -848,9 +849,23 @@ static const struct usb_device_id products[] = {
};
MODULE_DEVICE_TABLE(usb, products);

+static bool quectel_ec20_detected(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ if (dev->actconfig &&
+ le16_to_cpu(dev->descriptor.idVendor) == 0x05c6 &&
+ le16_to_cpu(dev->descriptor.idProduct) == 0x9215 &&
+ dev->actconfig->desc.bNumInterfaces == 5)
+ return true;
+
+ return false;
+}
+
static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id *prod)
{
struct usb_device_id *id = (struct usb_device_id *)prod;
+ struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;

/* Workaround to enable dynamic IDs. This disables usbnet
* blacklisting functionality. Which, if required, can be
@@ -862,6 +877,12 @@ static int qmi_wwan_probe(struct usb_interface *intf, const struct usb_device_id
id->driver_info = (unsigned long)&qmi_wwan_info;
}

+ /* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */
+ if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) {
+ dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n");
+ return -ENODEV;
+ }
+
return usbnet_probe(intf, id);
}

--
2.8.1

2016-04-22 11:18:26

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 39/78] hwmon: (max1111) Return -ENODEV from max1111_read_channel if not instantiated

From: Guenter Roeck <[email protected]>

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

===============

commit 3c2e2266a5bd2d1cef258e6e54dca1d99946379f upstream.

arm:pxa_defconfig can result in the following crash if the max1111 driver
is not instantiated.

Unhandled fault: page domain fault (0x01b) at 0x00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: : 1b [#1] PREEMPT ARM
Modules linked in:
CPU: 0 PID: 300 Comm: kworker/0:1 Not tainted 4.5.0-01301-g1701f680407c #10
Hardware name: SHARP Akita
Workqueue: events sharpsl_charge_toggle
task: c390a000 ti: c391e000 task.ti: c391e000
PC is at max1111_read_channel+0x20/0x30
LR is at sharpsl_pm_pxa_read_max1111+0x2c/0x3c
pc : [<c03aaab0>] lr : [<c0024b50>] psr: 20000013
...
[<c03aaab0>] (max1111_read_channel) from [<c0024b50>]
(sharpsl_pm_pxa_read_max1111+0x2c/0x3c)
[<c0024b50>] (sharpsl_pm_pxa_read_max1111) from [<c00262e0>]
(spitzpm_read_devdata+0x5c/0xc4)
[<c00262e0>] (spitzpm_read_devdata) from [<c0024094>]
(sharpsl_check_battery_temp+0x78/0x110)
[<c0024094>] (sharpsl_check_battery_temp) from [<c0024f9c>]
(sharpsl_charge_toggle+0x48/0x110)
[<c0024f9c>] (sharpsl_charge_toggle) from [<c004429c>]
(process_one_work+0x14c/0x48c)
[<c004429c>] (process_one_work) from [<c0044618>] (worker_thread+0x3c/0x5d4)
[<c0044618>] (worker_thread) from [<c004a238>] (kthread+0xd0/0xec)
[<c004a238>] (kthread) from [<c000a670>] (ret_from_fork+0x14/0x24)

This can occur because the SPI controller driver (SPI_PXA2XX) is built as
module and thus not necessarily loaded. While building SPI_PXA2XX into the
kernel would make the problem disappear, it appears prudent to ensure that
the driver is instantiated before accessing its data structures.

Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/hwmon/max1111.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index eda077de8a9f..f787f04a0d1a 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -85,6 +85,9 @@ static struct max1111_data *the_max1111;

int max1111_read_channel(int channel)
{
+ if (!the_max1111 || !the_max1111->spi)
+ return -ENODEV;
+
return max1111_read(&the_max1111->spi->dev, channel);
}
EXPORT_SYMBOL(max1111_read_channel);
@@ -260,6 +263,9 @@ static int max1111_remove(struct spi_device *spi)
{
struct max1111_data *data = spi_get_drvdata(spi);

+#ifdef CONFIG_SHARPSL_PM
+ the_max1111 = NULL;
+#endif
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group);
sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
--
2.8.1

2016-04-22 11:18:25

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 40/78] parisc: Avoid function pointers for kernel exception routines

From: Helge Deller <[email protected]>

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

===============

commit e3893027a300927049efc1572f852201eb785142 upstream.

We want to avoid the kernel module loader to create function pointers
for the kernel fixup routines of get_user() and put_user(). Changing
the external reference from function type to int type fixes this.

This unbreaks exception handling for get_user() and put_user() when
called from a kernel module.

Signed-off-by: Helge Deller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
arch/parisc/kernel/parisc_ksyms.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 568b2c61ea02..3cad8aadc69e 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -47,11 +47,11 @@ EXPORT_SYMBOL(__cmpxchg_u64);
EXPORT_SYMBOL(lclear_user);
EXPORT_SYMBOL(lstrnlen_user);

-/* Global fixups */
-extern void fixup_get_user_skip_1(void);
-extern void fixup_get_user_skip_2(void);
-extern void fixup_put_user_skip_1(void);
-extern void fixup_put_user_skip_2(void);
+/* Global fixups - defined as int to avoid creation of function pointers */
+extern int fixup_get_user_skip_1;
+extern int fixup_get_user_skip_2;
+extern int fixup_put_user_skip_1;
+extern int fixup_put_user_skip_2;
EXPORT_SYMBOL(fixup_get_user_skip_1);
EXPORT_SYMBOL(fixup_get_user_skip_2);
EXPORT_SYMBOL(fixup_put_user_skip_1);
--
2.8.1

2016-04-22 11:19:06

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 37/78] ipv6: Count in extension headers in skb->network_header

From: Jakub Sitnicki <[email protected]>

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

===============

[ Upstream commit 3ba3458fb9c050718b95275a3310b74415e767e2 ]

When sending a UDPv6 message longer than MTU, account for the length
of fragmentable IPv6 extension headers in skb->network_header offset.
Same as we do in alloc_new_skb path in __ip6_append_data().

This ensures that later on __ip6_make_skb() will make space in
headroom for fragmentable extension headers:

/* move skb->data to ip header from ext header */
if (skb->data < skb_network_header(skb))
__skb_pull(skb, skb_network_offset(skb));

Prevents a splat due to skb_under_panic:

skbuff: skb_under_panic: text:ffffffff8143397b len:2126 put:14 \
head:ffff880005bacf50 data:ffff880005bacf4a tail:0x48 end:0xc0 dev:lo
------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:104!
invalid opcode: 0000 [#1] KASAN
CPU: 0 PID: 160 Comm: reproducer Not tainted 4.6.0-rc2 #65
[...]
Call Trace:
[<ffffffff813eb7b9>] skb_push+0x79/0x80
[<ffffffff8143397b>] eth_header+0x2b/0x100
[<ffffffff8141e0d0>] neigh_resolve_output+0x210/0x310
[<ffffffff814eab77>] ip6_finish_output2+0x4a7/0x7c0
[<ffffffff814efe3a>] ip6_output+0x16a/0x280
[<ffffffff815440c1>] ip6_local_out+0xb1/0xf0
[<ffffffff814f1115>] ip6_send_skb+0x45/0xd0
[<ffffffff81518836>] udp_v6_send_skb+0x246/0x5d0
[<ffffffff8151985e>] udpv6_sendmsg+0xa6e/0x1090
[...]

Reported-by: Ji Jianwen <[email protected]>
Signed-off-by: Jakub Sitnicki <[email protected]>
Acked-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv6/ip6_output.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 855957271830..8b144bf50189 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1038,9 +1038,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
void *from, int length, int hh_len, int fragheaderlen,
- int transhdrlen, int mtu,unsigned int flags,
- struct rt6_info *rt)
-
+ int exthdrlen, int transhdrlen, int mtu,
+ unsigned int flags, struct rt6_info *rt)
{
struct sk_buff *skb;
struct frag_hdr fhdr;
@@ -1064,7 +1063,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
skb_put(skb,fragheaderlen + transhdrlen);

/* initialize network header pointer */
- skb_reset_network_header(skb);
+ skb_set_network_header(skb, exthdrlen);

/* initialize protocol header pointer */
skb->transport_header = skb->network_header + fragheaderlen;
@@ -1269,7 +1268,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
(rt->dst.dev->features & NETIF_F_UFO) &&
(sk->sk_type == SOCK_DGRAM)) {
err = ip6_ufo_append_data(sk, getfrag, from, length,
- hh_len, fragheaderlen,
+ hh_len, fragheaderlen, exthdrlen,
transhdrlen, mtu, flags, rt);
if (err)
goto error;
--
2.8.1

2016-04-22 11:06:20

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 03/78] sctp: lack the check for ports in sctp_v6_cmp_addr

From: Xin Long <[email protected]>

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

===============

[ Upstream commit 40b4f0fd74e46c017814618d67ec9127ff20f157 ]

As the member .cmp_addr of sctp_af_inet6, sctp_v6_cmp_addr should also check
the port of addresses, just like sctp_v4_cmp_addr, cause it's invoked by
sctp_cmp_addr_exact().

Now sctp_v6_cmp_addr just check the port when two addresses have different
family, and lack the port check for two ipv6 addresses. that will make
sctp_hash_cmp() cannot work well.

so fix it by adding ports comparison in sctp_v6_cmp_addr().

Signed-off-by: Xin Long <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/sctp/ipv6.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index a4b6365464bb..2092fb263dd0 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -517,6 +517,8 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
}
return 0;
}
+ if (addr1->v6.sin6_port != addr2->v6.sin6_port)
+ return 0;
if (!ipv6_addr_equal(&addr1->v6.sin6_addr, &addr2->v6.sin6_addr))
return 0;
/* If this is a linklocal address, compare the scope_id. */
--
2.8.1

2016-04-22 11:19:37

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 35/78] ipv6: l2tp: fix a potential issue in l2tp_ip6_recv

From: Haishuang Yan <[email protected]>

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

===============

[ Upstream commit be447f305494e019dfc37ea4cdf3b0e4200b4eba ]

pskb_may_pull() can change skb->data, so we have to load ptr/optr at the
right place.

Signed-off-by: Haishuang Yan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/l2tp/l2tp_ip6.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 3b61ddd6e4a6..eadfb3031ed2 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -135,12 +135,11 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
struct l2tp_tunnel *tunnel = NULL;
int length;

- /* Point to L2TP header */
- optr = ptr = skb->data;
-
if (!pskb_may_pull(skb, 4))
goto discard;

+ /* Point to L2TP header */
+ optr = ptr = skb->data;
session_id = ntohl(*((__be32 *) ptr));
ptr += 4;

@@ -168,6 +167,9 @@ static int l2tp_ip6_recv(struct sk_buff *skb)
if (!pskb_may_pull(skb, length))
goto discard;

+ /* Point to L2TP header */
+ optr = ptr = skb->data;
+ ptr += 4;
pr_debug("%s: ip recv\n", tunnel->name);
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
}
--
2.8.1

2016-04-22 11:19:32

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 36/78] ip6_tunnel: set rtnl_link_ops before calling register_netdevice

From: Thadeu Lima de Souza Cascardo <[email protected]>

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

===============

[ Upstream commit b6ee376cb0b7fb4e7e07d6cd248bd40436fb9ba6 ]

When creating an ip6tnl tunnel with ip tunnel, rtnl_link_ops is not set
before ip6_tnl_create2 is called. When register_netdevice is called, there
is no linkinfo attribute in the NEWLINK message because of that.

Setting rtnl_link_ops before calling register_netdevice fixes that.

Fixes: 0b112457229d ("ip6tnl: add support of link creation via rtnl")
Signed-off-by: Thadeu Lima de Souza Cascardo <[email protected]>
Acked-by: Nicolas Dichtel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv6/ip6_tunnel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 8883795462fe..cfdb663e0259 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -267,12 +267,12 @@ static int ip6_tnl_create2(struct net_device *dev)

t = netdev_priv(dev);

+ dev->rtnl_link_ops = &ip6_link_ops;
err = register_netdevice(dev);
if (err < 0)
goto out;

strcpy(t->parms.name, dev->name);
- dev->rtnl_link_ops = &ip6_link_ops;

dev_hold(dev);
ip6_tnl_link(ip6n, t);
--
2.8.1

2016-04-22 11:20:52

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 32/78] ppp: take reference on channels netns

From: Guillaume Nault <[email protected]>

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

===============

[ Upstream commit 1f461dcdd296eecedaffffc6bae2bfa90bd7eb89 ]

Let channels hold a reference on their network namespace.
Some channel types, like ppp_async and ppp_synctty, can have their
userspace controller running in a different namespace. Therefore they
can't rely on them to preclude their netns from being removed from
under them.

==================================================================
BUG: KASAN: use-after-free in ppp_unregister_channel+0x372/0x3a0 at
addr ffff880064e217e0
Read of size 8 by task syz-executor/11581
=============================================================================
BUG net_namespace (Not tainted): kasan: bad access detected
-----------------------------------------------------------------------------

Disabling lock debugging due to kernel taint
INFO: Allocated in copy_net_ns+0x6b/0x1a0 age=92569 cpu=3 pid=6906
[< none >] ___slab_alloc+0x4c7/0x500 kernel/mm/slub.c:2440
[< none >] __slab_alloc+0x4c/0x90 kernel/mm/slub.c:2469
[< inline >] slab_alloc_node kernel/mm/slub.c:2532
[< inline >] slab_alloc kernel/mm/slub.c:2574
[< none >] kmem_cache_alloc+0x23a/0x2b0 kernel/mm/slub.c:2579
[< inline >] kmem_cache_zalloc kernel/include/linux/slab.h:597
[< inline >] net_alloc kernel/net/core/net_namespace.c:325
[< none >] copy_net_ns+0x6b/0x1a0 kernel/net/core/net_namespace.c:360
[< none >] create_new_namespaces+0x2f6/0x610 kernel/kernel/nsproxy.c:95
[< none >] copy_namespaces+0x297/0x320 kernel/kernel/nsproxy.c:150
[< none >] copy_process.part.35+0x1bf4/0x5760 kernel/kernel/fork.c:1451
[< inline >] copy_process kernel/kernel/fork.c:1274
[< none >] _do_fork+0x1bc/0xcb0 kernel/kernel/fork.c:1723
[< inline >] SYSC_clone kernel/kernel/fork.c:1832
[< none >] SyS_clone+0x37/0x50 kernel/kernel/fork.c:1826
[< none >] entry_SYSCALL_64_fastpath+0x16/0x7a kernel/arch/x86/entry/entry_64.S:185

INFO: Freed in net_drop_ns+0x67/0x80 age=575 cpu=2 pid=2631
[< none >] __slab_free+0x1fc/0x320 kernel/mm/slub.c:2650
[< inline >] slab_free kernel/mm/slub.c:2805
[< none >] kmem_cache_free+0x2a0/0x330 kernel/mm/slub.c:2814
[< inline >] net_free kernel/net/core/net_namespace.c:341
[< none >] net_drop_ns+0x67/0x80 kernel/net/core/net_namespace.c:348
[< none >] cleanup_net+0x4e5/0x600 kernel/net/core/net_namespace.c:448
[< none >] process_one_work+0x794/0x1440 kernel/kernel/workqueue.c:2036
[< none >] worker_thread+0xdb/0xfc0 kernel/kernel/workqueue.c:2170
[< none >] kthread+0x23f/0x2d0 kernel/drivers/block/aoe/aoecmd.c:1303
[< none >] ret_from_fork+0x3f/0x70 kernel/arch/x86/entry/entry_64.S:468
INFO: Slab 0xffffea0001938800 objects=3 used=0 fp=0xffff880064e20000
flags=0x5fffc0000004080
INFO: Object 0xffff880064e20000 @offset=0 fp=0xffff880064e24200

CPU: 1 PID: 11581 Comm: syz-executor Tainted: G B 4.4.0+
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
00000000ffffffff ffff8800662c7790 ffffffff8292049d ffff88003e36a300
ffff880064e20000 ffff880064e20000 ffff8800662c77c0 ffffffff816f2054
ffff88003e36a300 ffffea0001938800 ffff880064e20000 0000000000000000
Call Trace:
[< inline >] __dump_stack kernel/lib/dump_stack.c:15
[<ffffffff8292049d>] dump_stack+0x6f/0xa2 kernel/lib/dump_stack.c:50
[<ffffffff816f2054>] print_trailer+0xf4/0x150 kernel/mm/slub.c:654
[<ffffffff816f875f>] object_err+0x2f/0x40 kernel/mm/slub.c:661
[< inline >] print_address_description kernel/mm/kasan/report.c:138
[<ffffffff816fb0c5>] kasan_report_error+0x215/0x530 kernel/mm/kasan/report.c:236
[< inline >] kasan_report kernel/mm/kasan/report.c:259
[<ffffffff816fb4de>] __asan_report_load8_noabort+0x3e/0x40 kernel/mm/kasan/report.c:280
[< inline >] ? ppp_pernet kernel/include/linux/compiler.h:218
[<ffffffff83ad71b2>] ? ppp_unregister_channel+0x372/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392
[< inline >] ppp_pernet kernel/include/linux/compiler.h:218
[<ffffffff83ad71b2>] ppp_unregister_channel+0x372/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392
[< inline >] ? ppp_pernet kernel/drivers/net/ppp/ppp_generic.c:293
[<ffffffff83ad6f26>] ? ppp_unregister_channel+0xe6/0x3a0 kernel/drivers/net/ppp/ppp_generic.c:2392
[<ffffffff83ae18f3>] ppp_asynctty_close+0xa3/0x130 kernel/drivers/net/ppp/ppp_async.c:241
[<ffffffff83ae1850>] ? async_lcp_peek+0x5b0/0x5b0 kernel/drivers/net/ppp/ppp_async.c:1000
[<ffffffff82c33239>] tty_ldisc_close.isra.1+0x99/0xe0 kernel/drivers/tty/tty_ldisc.c:478
[<ffffffff82c332c0>] tty_ldisc_kill+0x40/0x170 kernel/drivers/tty/tty_ldisc.c:744
[<ffffffff82c34943>] tty_ldisc_release+0x1b3/0x260 kernel/drivers/tty/tty_ldisc.c:772
[<ffffffff82c1ef21>] tty_release+0xac1/0x13e0 kernel/drivers/tty/tty_io.c:1901
[<ffffffff82c1e460>] ? release_tty+0x320/0x320 kernel/drivers/tty/tty_io.c:1688
[<ffffffff8174de36>] __fput+0x236/0x780 kernel/fs/file_table.c:208
[<ffffffff8174e405>] ____fput+0x15/0x20 kernel/fs/file_table.c:244
[<ffffffff813595ab>] task_work_run+0x16b/0x200 kernel/kernel/task_work.c:115
[< inline >] exit_task_work kernel/include/linux/task_work.h:21
[<ffffffff81307105>] do_exit+0x8b5/0x2c60 kernel/kernel/exit.c:750
[<ffffffff813fdd20>] ? debug_check_no_locks_freed+0x290/0x290 kernel/kernel/locking/lockdep.c:4123
[<ffffffff81306850>] ? mm_update_next_owner+0x6f0/0x6f0 kernel/kernel/exit.c:357
[<ffffffff813215e6>] ? __dequeue_signal+0x136/0x470 kernel/kernel/signal.c:550
[<ffffffff8132067b>] ? recalc_sigpending_tsk+0x13b/0x180 kernel/kernel/signal.c:145
[<ffffffff81309628>] do_group_exit+0x108/0x330 kernel/kernel/exit.c:880
[<ffffffff8132b9d4>] get_signal+0x5e4/0x14f0 kernel/kernel/signal.c:2307
[< inline >] ? kretprobe_table_lock kernel/kernel/kprobes.c:1113
[<ffffffff8151d355>] ? kprobe_flush_task+0xb5/0x450 kernel/kernel/kprobes.c:1158
[<ffffffff8115f7d3>] do_signal+0x83/0x1c90 kernel/arch/x86/kernel/signal.c:712
[<ffffffff8151d2a0>] ? recycle_rp_inst+0x310/0x310 kernel/include/linux/list.h:655
[<ffffffff8115f750>] ? setup_sigcontext+0x780/0x780 kernel/arch/x86/kernel/signal.c:165
[<ffffffff81380864>] ? finish_task_switch+0x424/0x5f0 kernel/kernel/sched/core.c:2692
[< inline >] ? finish_lock_switch kernel/kernel/sched/sched.h:1099
[<ffffffff81380560>] ? finish_task_switch+0x120/0x5f0 kernel/kernel/sched/core.c:2678
[< inline >] ? context_switch kernel/kernel/sched/core.c:2807
[<ffffffff85d794e9>] ? __schedule+0x919/0x1bd0 kernel/kernel/sched/core.c:3283
[<ffffffff81003901>] exit_to_usermode_loop+0xf1/0x1a0 kernel/arch/x86/entry/common.c:247
[< inline >] prepare_exit_to_usermode kernel/arch/x86/entry/common.c:282
[<ffffffff810062ef>] syscall_return_slowpath+0x19f/0x210 kernel/arch/x86/entry/common.c:344
[<ffffffff85d88022>] int_ret_from_sys_call+0x25/0x9f kernel/arch/x86/entry/entry_64.S:281
Memory state around the buggy address:
ffff880064e21680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880064e21700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff880064e21780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff880064e21800: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff880064e21880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

Fixes: 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2")
Reported-by: Baozeng Ding <[email protected]>
Signed-off-by: Guillaume Nault <[email protected]>
Reviewed-by: Cyrill Gorcunov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ppp/ppp_generic.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index a2d7d5f066f1..14a8d2958698 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2220,7 +2220,7 @@ int ppp_register_net_channel(struct net *net, struct ppp_channel *chan)

pch->ppp = NULL;
pch->chan = chan;
- pch->chan_net = net;
+ pch->chan_net = get_net(net);
chan->ppp = pch;
init_ppp_file(&pch->file, CHANNEL);
pch->file.hdrlen = chan->hdrlen;
@@ -2317,6 +2317,8 @@ ppp_unregister_channel(struct ppp_channel *chan)
spin_lock_bh(&pn->all_channels_lock);
list_del(&pch->list);
spin_unlock_bh(&pn->all_channels_lock);
+ put_net(pch->chan_net);
+ pch->chan_net = NULL;

pch->file.dead = 1;
wake_up_interruptible(&pch->file.rwait);
--
2.8.1

2016-04-22 11:20:51

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 33/78] xfrm: Fix crash observed during device unregistration and decryption

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

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

===============

[ Upstream commit 071d36bf21bcc837be00cea55bcef8d129e7f609 ]

A crash is observed when a decrypted packet is processed in receive
path. get_rps_cpus() tries to dereference the skb->dev fields but it
appears that the device is freed from the poison pattern.

[<ffffffc000af58ec>] get_rps_cpu+0x94/0x2f0
[<ffffffc000af5f94>] netif_rx_internal+0x140/0x1cc
[<ffffffc000af6094>] netif_rx+0x74/0x94
[<ffffffc000bc0b6c>] xfrm_input+0x754/0x7d0
[<ffffffc000bc0bf8>] xfrm_input_resume+0x10/0x1c
[<ffffffc000ba6eb8>] esp_input_done+0x20/0x30
[<ffffffc0000b64c8>] process_one_work+0x244/0x3fc
[<ffffffc0000b7324>] worker_thread+0x2f8/0x418
[<ffffffc0000bb40c>] kthread+0xe0/0xec

-013|get_rps_cpu(
| dev = 0xFFFFFFC08B688000,
| skb = 0xFFFFFFC0C76AAC00 -> (
| dev = 0xFFFFFFC08B688000 -> (
| name =
"......................................................
| name_hlist = (next = 0xAAAAAAAAAAAAAAAA, pprev =
0xAAAAAAAAAAA

Following are the sequence of events observed -

- Encrypted packet in receive path from netdevice is queued
- Encrypted packet queued for decryption (asynchronous)
- Netdevice brought down and freed
- Packet is decrypted and returned through callback in esp_input_done
- Packet is queued again for process in network stack using netif_rx

Since the device appears to have been freed, the dereference of
skb->dev in get_rps_cpus() leads to an unhandled page fault
exception.

Fix this by holding on to device reference when queueing packets
asynchronously and releasing the reference on call back return.

v2: Make the change generic to xfrm as mentioned by Steffen and
update the title to xfrm

Suggested-by: Herbert Xu <[email protected]>
Signed-off-by: Jerome Stanislaus <[email protected]>
Signed-off-by: Subash Abhinov Kasiviswanathan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/xfrm/xfrm_input.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 88843996f935..fd74c636e255 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -196,6 +196,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;

skb_dst_force(skb);
+ dev_hold(skb->dev);

nexthdr = x->type->input(x, skb);

@@ -203,6 +204,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
return 0;

resume:
+ dev_put(skb->dev);
+
spin_lock(&x->lock);
if (nexthdr <= 0) {
if (nexthdr == -EBADMSG) {
--
2.8.1

2016-04-22 11:20:49

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 34/78] ipv4: l2tp: fix a potential issue in l2tp_ip_recv

From: Haishuang Yan <[email protected]>

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

===============

[ Upstream commit 5745b8232e942abd5e16e85fa9b27cc21324acf0 ]

pskb_may_pull() can change skb->data, so we have to load ptr/optr at the
right place.

Signed-off-by: Haishuang Yan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/l2tp/l2tp_ip.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index da1a1cee1a08..07f8b97f9ae9 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -123,12 +123,11 @@ static int l2tp_ip_recv(struct sk_buff *skb)
struct l2tp_tunnel *tunnel = NULL;
int length;

- /* Point to L2TP header */
- optr = ptr = skb->data;
-
if (!pskb_may_pull(skb, 4))
goto discard;

+ /* Point to L2TP header */
+ optr = ptr = skb->data;
session_id = ntohl(*((__be32 *) ptr));
ptr += 4;

@@ -156,6 +155,9 @@ static int l2tp_ip_recv(struct sk_buff *skb)
if (!pskb_may_pull(skb, length))
goto discard;

+ /* Point to L2TP header */
+ optr = ptr = skb->data;
+ ptr += 4;
pr_debug("%s: ip recv\n", tunnel->name);
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length);
}
--
2.8.1

2016-04-22 11:06:18

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 02/78] net: jme: fix suspend/resume on JMC260

From: Diego Viola <[email protected]>

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

===============

[ Upstream commit ee50c130c82175eaa0820c96b6d3763928af2241 ]

The JMC260 network card fails to suspend/resume because the call to
jme_start_irq() was too early, moving the call to jme_start_irq() after
the call to jme_reset_link() makes it work.

Prior this change suspend/resume would fail unless /sys/power/pm_async=0
was explicitly specified.

Relevant bug report: https://bugzilla.kernel.org/show_bug.cgi?id=112351

Signed-off-by: Diego Viola <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/jme.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 23de82a9da82..2602fb324157 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -3289,13 +3289,14 @@ jme_resume(struct device *dev)
jme_reset_phy_processor(jme);
jme_phy_calibration(jme);
jme_phy_setEA(jme);
- jme_start_irq(jme);
netif_device_attach(netdev);

atomic_inc(&jme->link_changing);

jme_reset_link(jme);

+ jme_start_irq(jme);
+
return 0;
}

--
2.8.1

2016-04-22 11:21:41

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 31/78] qlge: Fix receive packets drop.

From: Manish Chopra <[email protected]>

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

===============

[ Upstream commit 2c9a266afefe137bff06bbe0fc48b4d3b3cb348c ]

When running small packets [length < 256 bytes] traffic, packets were
being dropped due to invalid data in those packets which were
delivered by the driver upto the stack. Using pci_dma_sync_single_for_cpu
ensures copying latest and updated data into skb from the receive buffer.

Signed-off-by: Sony Chacko <[email protected]>
Signed-off-by: Manish Chopra <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/qlogic/qlge/qlge_main.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 2553cf4503b9..151478a59e30 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -1620,7 +1620,18 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev,
return;
}
skb_reserve(new_skb, NET_IP_ALIGN);
+
+ pci_dma_sync_single_for_cpu(qdev->pdev,
+ dma_unmap_addr(sbq_desc, mapaddr),
+ dma_unmap_len(sbq_desc, maplen),
+ PCI_DMA_FROMDEVICE);
+
memcpy(skb_put(new_skb, length), skb->data, length);
+
+ pci_dma_sync_single_for_device(qdev->pdev,
+ dma_unmap_addr(sbq_desc, mapaddr),
+ dma_unmap_len(sbq_desc, maplen),
+ PCI_DMA_FROMDEVICE);
skb = new_skb;

/* Frame error, so drop the packet. */
--
2.8.1

2016-04-22 11:21:40

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 22/78] usbnet: cleanup after bind() in probe()

From: Oliver Neukum <[email protected]>

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

===============

[ Upstream commit 1666984c8625b3db19a9abc298931d35ab7bc64b ]

In case bind() works, but a later error forces bailing
in probe() in error cases work and a timer may be scheduled.
They must be killed. This fixes an error case related to
the double free reported in
http://www.spinics.net/lists/netdev/msg367669.html
and needs to go on top of Linus' fix to cdc-ncm.

Signed-off-by: Oliver Neukum <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/usbnet.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 3b7b7b2eba1b..4abd4579ba0c 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1719,6 +1719,13 @@ out3:
if (info->unbind)
info->unbind (dev, udev);
out1:
+ /* subdrivers must undo all they did in bind() if they
+ * fail it, but we may fail later and a deferred kevent
+ * may trigger an error resubmitting itself and, worse,
+ * schedule a timer. So we kill it all just in case.
+ */
+ cancel_work_sync(&dev->kevent);
+ del_timer_sync(&dev->delay);
free_netdev(net);
out:
return status;
--
2.8.1

2016-04-22 11:22:36

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 29/78] ath9k: fix buffer overrun for ar9287

From: Arnd Bergmann <[email protected]>

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

===============

[ Upstream commit 83d6f1f15f8cce844b0a131cbc63e444620e48b5 ]

Code that was added back in 2.6.38 has an obvious overflow
when accessing a static array, and at the time it was added
only a code comment was put in front of it as a reminder
to have it reviewed properly.

This has not happened, but gcc-6 now points to the specific
overflow:

drivers/net/wireless/ath/ath9k/eeprom.c: In function 'ath9k_hw_get_gain_boundaries_pdadcs':
drivers/net/wireless/ath/ath9k/eeprom.c:483:44: error: array subscript is above array bounds [-Werror=array-bounds]
maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
~~~~~~~~~~~~~~~~~~~~~~~~~^~~

It turns out that the correct array length exists in the local
'intercepts' variable of this function, so we can just use that
instead of hardcoding '4', so this patch changes all three
instances to use that variable. The other two instances were
already correct, but it's more consistent this way.

Signed-off-by: Arnd Bergmann <[email protected]>
Fixes: 940cd2c12ebf ("ath9k_hw: merge the ar9287 version of ath9k_hw_get_gain_boundaries_pdadcs")
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/wireless/ath/ath9k/eeprom.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 971d770722cf..2ac05486424b 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -408,10 +408,9 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,

if (match) {
if (AR_SREV_9287(ah)) {
- /* FIXME: array overrun? */
for (i = 0; i < numXpdGains; i++) {
minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
- maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
+ maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1];
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
data_9287[idxL].pwrPdg[i],
data_9287[idxL].vpdPdg[i],
@@ -421,7 +420,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
} else if (eeprom_4k) {
for (i = 0; i < numXpdGains; i++) {
minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
- maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
+ maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1];
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
data_4k[idxL].pwrPdg[i],
data_4k[idxL].vpdPdg[i],
@@ -431,7 +430,7 @@ void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
} else {
for (i = 0; i < numXpdGains; i++) {
minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
- maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
+ maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1];
ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
data_def[idxL].pwrPdg[i],
data_def[idxL].vpdPdg[i],
--
2.8.1

2016-04-22 11:22:35

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 18/78] qmi_wwan: Added support for Gemalto's Cinterion PHxx WWAN interface

From: Schemmel Hans-Christoph <[email protected]>

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

===============

commit bd9e33508c5e1eb5d807d11d7bfc52125fcdb04e upstream.

Added support for Gemalto's Cinterion PHxx WWAN interfaces
by adding QMI_FIXED_INTF with Cinterion's VID and PID.

PHxx can have:
2 RmNet Interfaces (PID 0x0082) or
1 RmNet + 1 USB Audio interface (PID 0x0083).

Signed-off-by: Hans-Christoph Schemmel <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 9ec45ee06dc7..221dd71a6a88 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -767,6 +767,9 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */
{QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */
{QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */
+ {QMI_FIXED_INTF(0x1e2d, 0x0082, 4)}, /* Cinterion PHxx,PXxx (2 RmNet) */
+ {QMI_FIXED_INTF(0x1e2d, 0x0082, 5)}, /* Cinterion PHxx,PXxx (2 RmNet) */
+ {QMI_FIXED_INTF(0x1e2d, 0x0083, 4)}, /* Cinterion PHxx,PXxx (1 RmNet + USB Audio)*/
{QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
--
2.8.1

2016-04-22 11:22:34

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 30/78] net: mvneta: enable change MAC address when interface is up

From: Dmitri Epshtein <[email protected]>

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

===============

[ Upstream commit 928b6519afeb2a5e2dc61154380b545ed66c476a ]

Function eth_prepare_mac_addr_change() is called as part of MAC
address change. This function check if interface is running.
To enable change MAC address when interface is running:
IFF_LIVE_ADDR_CHANGE flag must be set to dev->priv_flags field

Fixes: c5aff18204da ("net: mvneta: driver for Marvell Armada 370/XP
network unit")
Cc: [email protected]
Signed-off-by: Dmitri Epshtein <[email protected]>
Signed-off-by: Gregory CLEMENT <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/marvell/mvneta.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index d3b8c8af5d5b..5902e6a93167 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2861,7 +2861,7 @@ static int mvneta_probe(struct platform_device *pdev)
dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM;
dev->vlan_features |= NETIF_F_SG | NETIF_F_IP_CSUM;
- dev->priv_flags |= IFF_UNICAST_FLT;
+ dev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE;

err = register_netdev(dev);
if (err < 0) {
--
2.8.1

2016-04-22 11:28:24

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 28/78] farsync: fix off-by-one bug in fst_add_one

From: Arnd Bergmann <[email protected]>

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

===============

[ Upstream commit e725a66c0202b5f36c2f9d59d26a65c53bbf21f7 ]

gcc-6 finds an out of bounds access in the fst_add_one function
when calculating the end of the mmio area:

drivers/net/wan/farsync.c: In function 'fst_add_one':
drivers/net/wan/farsync.c:418:53: error: index 2 denotes an offset greater than size of 'u8[2][8192] {aka unsigned char[2][8192]}' [-Werror=array-bounds]
#define BUF_OFFSET(X) (BFM_BASE + offsetof(struct buf_window, X))
^
include/linux/compiler-gcc.h:158:21: note: in definition of macro '__compiler_offsetof'
__builtin_offsetof(a, b)
^
drivers/net/wan/farsync.c:418:37: note: in expansion of macro 'offsetof'
#define BUF_OFFSET(X) (BFM_BASE + offsetof(struct buf_window, X))
^~~~~~~~
drivers/net/wan/farsync.c:2519:36: note: in expansion of macro 'BUF_OFFSET'
+ BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
^~~~~~~~~~

The warning is correct, but not critical because this appears
to be a write-only variable that is set by each WAN driver but
never accessed afterwards.

I'm taking the minimal fix here, using the correct pointer by
pointing 'mem_end' to the last byte inside of the register area
as all other WAN drivers do, rather than the first byte outside of
it. An alternative would be to just remove the mem_end member
entirely.

Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/wan/farsync.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index bcfff0d62de4..2dfa1478d7d1 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2545,7 +2545,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->mem_start = card->phys_mem
+ BUF_OFFSET ( txBuffer[i][0][0]);
dev->mem_end = card->phys_mem
- + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]);
+ + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER - 1][LEN_RX_BUFFER - 1]);
dev->base_addr = card->pci_conf;
dev->irq = card->irq;

--
2.8.1

2016-04-22 11:28:41

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 27/78] mlx4: add missing braces in verify_qp_parameters

From: Arnd Bergmann <[email protected]>

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

===============

[ Upstream commit baefd7015cdb304ce6c94f9679d0486c71954766 ]

The implementation of QP paravirtualization back in linux-3.7 included
some code that looks very dubious, and gcc-6 has grown smart enough
to warn about it:

drivers/net/ethernet/mellanox/mlx4/resource_tracker.c: In function 'verify_qp_parameters':
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c:3154:5: error: statement is indented as if it were guarded by... [-Werror=misleading-indentation]
if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) {
^~
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c:3144:4: note: ...this 'if' clause, but it is not
if (slave != mlx4_master_func_num(dev))

>From looking at the context, I'm reasonably sure that the indentation
is correct but that it should have contained curly braces from the
start, as the update_gid() function in the same patch correctly does.

Signed-off-by: Arnd Bergmann <[email protected]>
Fixes: 54679e148287 ("mlx4: Implement QP paravirtualization and maintain phys_pkey_cache for smp_snoop")
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index cdbe63712d2d..c1c33839baf7 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2331,7 +2331,7 @@ static int verify_qp_parameters(struct mlx4_dev *dev,
case QP_TRANS_RTS2RTS:
case QP_TRANS_SQD2SQD:
case QP_TRANS_SQD2RTS:
- if (slave != mlx4_master_func_num(dev))
+ if (slave != mlx4_master_func_num(dev)) {
/* slaves have only gid index 0 */
if (optpar & MLX4_QP_OPTPAR_PRIMARY_ADDR_PATH)
if (qp_ctx->pri_path.mgid_index)
@@ -2339,6 +2339,7 @@ static int verify_qp_parameters(struct mlx4_dev *dev,
if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH)
if (qp_ctx->alt_path.mgid_index)
return -EINVAL;
+ }
break;
default:
break;
--
2.8.1

2016-04-22 11:28:40

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 17/78] qmi_wwan: add Sierra Wireless EM74xx device ID

From: Bjørn Mork <[email protected]>

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

===============

commit bf13c94ccb33c3182efc92ce4989506a0f541243 upstream.

The MC74xx and EM74xx modules use different IDs by default, according
to the Lenovo EM7455 driver for Windows.

Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index c00fa6546c95..9ec45ee06dc7 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -747,8 +747,10 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
- {QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx/EM74xx */
- {QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx/EM74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9079, 8)}, /* Sierra Wireless EM74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
--
2.8.1

2016-04-22 11:29:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 26/78] net: Fix use after free in the recvmmsg exit path

From: Arnaldo Carvalho de Melo <[email protected]>

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

===============

[ Upstream commit 34b88a68f26a75e4fded796f1a49c40f82234b7d ]

The syzkaller fuzzer hit the following use-after-free:

Call Trace:
[<ffffffff8175ea0e>] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:295
[<ffffffff851cc31a>] __sys_recvmmsg+0x6fa/0x7f0 net/socket.c:2261
[< inline >] SYSC_recvmmsg net/socket.c:2281
[<ffffffff851cc57f>] SyS_recvmmsg+0x16f/0x180 net/socket.c:2270
[<ffffffff86332bb6>] entry_SYSCALL_64_fastpath+0x16/0x7a
arch/x86/entry/entry_64.S:185

And, as Dmitry rightly assessed, that is because we can drop the
reference and then touch it when the underlying recvmsg calls return
some packets and then hit an error, which will make recvmmsg to set
sock->sk->sk_err, oops, fix it.

Reported-and-Tested-by: Dmitry Vyukov <[email protected]>
Cc: Alexander Potapenko <[email protected]>
Cc: Eric Dumazet <[email protected]>
Cc: Kostya Serebryany <[email protected]>
Cc: Sasha Levin <[email protected]>
Fixes: a2e2725541fa ("net: Introduce recvmmsg socket syscall")
http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/socket.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 00634623573f..64c47cd62e14 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2389,31 +2389,31 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
break;
}

-out_put:
- fput_light(sock->file, fput_needed);
-
if (err == 0)
- return datagrams;
+ goto out_put;

- if (datagrams != 0) {
+ if (datagrams == 0) {
+ datagrams = err;
+ goto out_put;
+ }
+
+ /*
+ * We may return less entries than requested (vlen) if the
+ * sock is non block and there aren't enough datagrams...
+ */
+ if (err != -EAGAIN) {
/*
- * We may return less entries than requested (vlen) if the
- * sock is non block and there aren't enough datagrams...
+ * ... or if recvmsg returns an error after we
+ * received some datagrams, where we record the
+ * error to return on the next call or if the
+ * app asks about it using getsockopt(SO_ERROR).
*/
- if (err != -EAGAIN) {
- /*
- * ... or if recvmsg returns an error after we
- * received some datagrams, where we record the
- * error to return on the next call or if the
- * app asks about it using getsockopt(SO_ERROR).
- */
- sock->sk->sk_err = -err;
- }
-
- return datagrams;
+ sock->sk->sk_err = -err;
}
+out_put:
+ fput_light(sock->file, fput_needed);

- return err;
+ return datagrams;
}

SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg,
--
2.8.1

2016-04-22 11:06:15

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 01/78] tunnel: Clear IPCB(skb)->opt before dst_link_failure called

From: Bernie Harris <[email protected]>

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

===============

[ Upstream commit 5146d1f151122e868e594c7b45115d64825aee5f ]

IPCB may contain data from previous layers (in the observed case the
qdisc layer). In the observed scenario, the data was misinterpreted as
ip header options, which later caused the ihl to be set to an invalid
value (<5). This resulted in an infinite loop in the mips implementation
of ip_fast_csum.

This patch clears IPCB(skb)->opt before dst_link_failure can be called for
various types of tunnels. This change only applies to encapsulated ipv4
packets.

The code introduced in 11c21a30 which clears all of IPCB has been removed
to be consistent with these changes, and instead the opt field is cleared
unconditionally in ip_tunnel_xmit. The change in ip_tunnel_xmit applies to
SIT, GRE, and IPIP tunnels.

The relevant vti, l2tp, and pptp functions already contain similar code for
clearing the IPCB.

[js] backport to 3.12: no udp_tunnel there

Signed-off-by: Bernie Harris <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv4/ip_tunnel.c | 3 ++-
net/ipv6/ip6_gre.c | 2 ++
net/ipv6/ip6_tunnel.c | 2 ++
3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 6913e2fdc12c..d47c7ea98324 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -540,6 +540,8 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,

inner_iph = (const struct iphdr *)skb_inner_network_header(skb);

+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
dst = tnl_params->daddr;
if (dst == 0) {
/* NBMA tunnel */
@@ -623,7 +625,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
tunnel->err_count--;

- memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
dst_link_failure(skb);
} else
tunnel->err_count = 0;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index f719c51369fc..737af492ed75 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -787,6 +787,8 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
__u32 mtu;
int err;

+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
encap_limit = t->parms.encap_limit;

diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index f8a70a120e75..8883795462fe 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1063,6 +1063,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
__u32 mtu;
int err;

+ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+
if ((t->parms.proto != IPPROTO_IPIP && t->parms.proto != 0) ||
!ip6_tnl_xmit_ctl(t))
return -1;
--
2.8.1

2016-04-22 11:32:26

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 23/78] udp6: fix UDP/IPv6 encap resubmit path

From: Bill Sommerfeld <[email protected]>

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

===============

[ Upstream commit 59dca1d8a6725a121dae6c452de0b2611d5865dc ]

IPv4 interprets a negative return value from a protocol handler as a
request to redispatch to a new protocol. In contrast, IPv6 interprets a
negative value as an error, and interprets a positive value as a request
for redispatch.

UDP for IPv6 was unaware of this difference. Change __udp6_lib_rcv() to
return a positive value for redispatch. Note that the socket's
encap_rcv hook still needs to return a negative value to request
dispatch, and in the case of IPv6 packets, adjust IP6CB(skb)->nhoff to
identify the byte containing the next protocol.

Signed-off-by: Bill Sommerfeld <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
net/ipv6/udp.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 94ca4172b38e..26e1648ca228 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -848,11 +848,9 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
ret = udpv6_queue_rcv_skb(sk, skb);
sock_put(sk);

- /* a return value > 0 means to resubmit the input, but
- * it wants the return to be -protocol, or 0
- */
+ /* a return value > 0 means to resubmit the input */
if (ret > 0)
- return -ret;
+ return ret;

return 0;
}
--
2.8.1

2016-04-22 11:32:24

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 24/78] sh_eth: fix NULL pointer dereference in sh_eth_ring_format()

From: Sergei Shtylyov <[email protected]>

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

===============

[ Upstream commit c1b7fca65070bfadca94dd53a4e6b71cd4f69715 ]

In a low memory situation, if netdev_alloc_skb() fails on a first RX ring
loop iteration in sh_eth_ring_format(), 'rxdesc' is still NULL. Avoid
kernel oops by adding the 'rxdesc' check after the loop.

Reported-by: Wolfram Sang <[email protected]>
Signed-off-by: Sergei Shtylyov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/ethernet/renesas/sh_eth.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index bee6e49c5542..d4ecb2fff4e4 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -1069,7 +1069,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);

/* Mark the last entry as wrapping the ring. */
- rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
+ if (rxdesc)
+ rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);

memset(mdp->tx_ring, 0, tx_ringsize);

--
2.8.1

2016-04-22 11:32:23

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 25/78] macvtap: always pass ethernet header in linear

From: Willem de Bruijn <[email protected]>

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

===============

[ Upstream commit 8e2ad4113ce4671686740f808ff2795395c39eef ]

The stack expects link layer headers in the skb linear section.
Macvtap can create skbs with llheader in frags in edge cases:
when (IFF_VNET_HDR is off or vnet_hdr.hdr_len < ETH_HLEN) and
prepad + len > PAGE_SIZE and vnet_hdr.flags has no or bad csum.

Add checks to ensure linear is always at least ETH_HLEN.
At this point, len is already ensured to be >= ETH_HLEN.

For backwards compatiblity, rounds up short vnet_hdr.hdr_len.
This differs from tap and packet, which return an error.

Fixes b9fb9ee07e67 ("macvtap: add GSO/csum offload support")
Signed-off-by: Willem de Bruijn <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/macvtap.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index ee53a9d06e8e..98ce4feb9a79 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -688,6 +688,8 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
if (copylen > good_linear)
copylen = good_linear;
+ else if (copylen < ETH_HLEN)
+ copylen = ETH_HLEN;
linear = copylen;
if (iov_pages(iv, vnet_hdr_len + copylen, count)
<= MAX_SKB_FRAGS)
@@ -696,10 +698,11 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,

if (!zerocopy) {
copylen = len;
- if (vnet_hdr.hdr_len > good_linear)
+ linear = vnet_hdr.hdr_len;
+ if (linear > good_linear)
linear = good_linear;
- else
- linear = vnet_hdr.hdr_len;
+ else if (linear < ETH_HLEN)
+ linear = ETH_HLEN;
}

skb = macvtap_alloc_skb(&q->sk, MACVTAP_RESERVE, copylen,
--
2.8.1

2016-04-22 11:06:11

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 04/78] qmi_wwan: add "D-Link DWM-221 B1" device id

From: Bjørn Mork <[email protected]>

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

===============

commit e84810c7b85a2d7897797b3ad3e879168a8e032a upstream.

Thomas reports:
"Windows:

00 diagnostics
01 modem
02 at-port
03 nmea
04 nic

Linux:

T: Bus=02 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 4 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=2001 ProdID=7e19 Rev=02.32
S: Manufacturer=Mobile Connect
S: Product=Mobile Connect
S: SerialNumber=0123456789ABCDEF
C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option
I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I: If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage"

Reported-by: Thomas Schäfer <[email protected]>
Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 0eb410b637de..6d9c216e5c24 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -729,6 +729,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */
{QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */
{QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */
+ {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */
{QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
--
2.8.1

2016-04-22 11:33:06

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 06/78] net: qmi_wwan: add additional Sierra Wireless QMI devices

From: Aleksander Morgado <[email protected]>

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

===============

commit 9a793e71ebd6fc4a2649f33811589a9c4fe7f4e8 upstream.

A set of new VID/PIDs retrieved from the out-of-tree GobiNet/GobiSerial
Sierra Wireless drivers.

Signed-off-by: Aleksander Morgado <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 775b5263b256..6788f7891a4f 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -741,8 +741,12 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
{QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
{QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */
+ {QMI_FIXED_INTF(0x1199, 0x9053, 8)}, /* Sierra Wireless Modem */
+ {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */
+ {QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
+ {QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
--
2.8.1

2016-04-22 11:33:04

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 21/78] cdc_ncm: toggle altsetting to force reset before setup

From: Bjørn Mork <[email protected]>

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

===============

[ Upstream commit 48906f62c96cc2cd35753e59310cb70eb08cc6a5 ]

Some devices will silently fail setup unless they are reset first.
This is necessary even if the data interface is already in
altsetting 0, which it will be when the device is probed for the
first time. Briefly toggling the altsetting forces a function
reset regardless of the initial state.

This fixes a setup problem observed on a number of Huawei devices,
appearing to operate in NTB-32 mode even if we explicitly set them
to NTB-16 mode.

Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/cdc_ncm.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 43afde8f48d2..74581cbcafa7 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -464,7 +464,11 @@ advance:

iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;

- /* reset data interface */
+ /* Reset data interface. Some devices will not reset properly
+ * unless they are configured first. Toggle the altsetting to
+ * force a reset
+ */
+ usb_set_interface(dev->udev, iface_no, data_altsetting);
temp = usb_set_interface(dev->udev, iface_no, 0);
if (temp)
goto error2;
--
2.8.1

2016-04-22 11:34:07

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 19/78] qmi_wwan/cdc_ether: move Novatel E371 (1410:9011) to qmi_wwan

From: Yegor Yefremov <[email protected]>

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

===============

commit 7b5939ba591e9affbe4f336935b0985fd250a2b3 upstream.

This device provides QMI and ethernet functionality via a standard CDC
ethernet descriptor. But when driven by cdc_ether, the QMI
functionality is unavailable because only cdc_ether can claim the USB
interface. Thus blacklist the device in cdc_ether and add its IDs to
qmi_wwan, which enables both QMI and ethernet simultaneously.

Signed-off-by: Yegor Yefremov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/cdc_ether.c | 7 +++++++
drivers/net/usb/qmi_wwan.c | 7 +++++++
2 files changed, 14 insertions(+)

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 2023f3ea891e..756bb3a8e02c 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -626,6 +626,13 @@ static const struct usb_device_id products[] = {
.driver_info = 0,
},

+/* Novatel Expedite E371 - handled by qmi_wwan */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(NOVATEL_VENDOR_ID, 0x9011, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+ .driver_info = 0,
+},
+
/* AnyDATA ADU960S - handled by qmi_wwan */
{
USB_DEVICE_AND_INTERFACE_INFO(0x16d5, 0x650a, USB_CLASS_COMM,
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 221dd71a6a88..3e146ee2f2a9 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -487,6 +487,13 @@ static const struct usb_device_id products[] = {
USB_CDC_PROTO_NONE),
.driver_info = (unsigned long)&qmi_wwan_info,
},
+ { /* Novatel Expedite E371 */
+ USB_DEVICE_AND_INTERFACE_INFO(0x1410, 0x9011,
+ USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET,
+ USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long)&qmi_wwan_info,
+ },
{ /* Dell Wireless 5800 (Novatel E362) */
USB_DEVICE_AND_INTERFACE_INFO(0x413C, 0x8195,
USB_CLASS_COMM,
--
2.8.1

2016-04-22 11:34:32

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 16/78] Add Dell Wireless 5809e Gobi 4G HSPA+ Mobile Broadband Card (rev3) to qmi_wwan

From: Patrik Halfar <[email protected]>

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

===============

commit fb5eb24cdd5cdb83be77d3e4b2f16e92e06bd9e9 upstream.

New revison of Dell Wireless 5809e Gobi 4G HSPA+ Mobile Broadband Card has new idProduct

Bus 002 Device 006: ID 413c:81b3 Dell Computer Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x413c Dell Computer Corp.
idProduct 0x81b3
bcdDevice 0.06
iManufacturer 1 Sierra Wireless, Incorporated
iProduct 2 Dell Wireless 5809e Gobi™ 4G HSPA+ Mobile Broadband Card
iSerial 3
bNumConfigurations 2

Signed-off-by: Patrik Halfar <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 0e6f3fcae062..c00fa6546c95 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -771,6 +771,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
{QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */
{QMI_FIXED_INTF(0x1e0e, 0x9001, 5)}, /* SIMCom 7230E */
--
2.8.1

2016-04-22 11:06:09

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 05/78] net: qmi_wwan: add Netgear AirCard 341U

From: Aleksander Morgado <[email protected]>

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

===============

commit 4324be1e0bab67194a263be263b7e48c176d43c7 upstream.

Signed-off-by: Aleksander Morgado <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 6d9c216e5c24..775b5263b256 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -741,6 +741,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
{QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
{QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */
+ {QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
--
2.8.1

2016-04-22 11:34:47

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 15/78] net: qmi_wwan: Add SIMCom 7230E

From: Kristian Evensen <[email protected]>

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

===============

commit 18715b261541f35ccede9b8686ee3ebaac697d38 upstream.

SIMCom 7230E is a QMI LTE module with support for most "normal" bands.
Manual testing has showed that only interface five works.

Cc: Bjørn Mork <[email protected]>
Signed-off-by: Kristian Evensen <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 4c7ef4f48536..0e6f3fcae062 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -773,6 +773,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
{QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */
+ {QMI_FIXED_INTF(0x1e0e, 0x9001, 5)}, /* SIMCom 7230E */

/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
--
2.8.1

2016-04-22 11:35:15

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 10/78] net: qmi_wwan: add HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module

From: David Ward <[email protected]>

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

===============

commit a8079092c1bbf9aec3756b35256c7816b8845af7 upstream.

This is an HP-branded Sierra Wireless EM7355:
https://bugzilla.redhat.com/show_bug.cgi?id=1223646#c2

Signed-off-by: David Ward <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index be1e3f2ebd7e..f343bfca1068 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -769,6 +769,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */

/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
--
2.8.1

2016-04-22 11:35:14

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 13/78] net: qmi_wwan: remove 1199:9070 device id

From: Bjørn Mork <[email protected]>

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

===============

commit 544c8f6507303e921979ac99f46f00a88b42b6e8 upstream.

This turned out to be a bootloader device ID. No need for
that in this driver. It will only provide a single serial
function.

Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index a516b7ee02bf..abff536ebcf2 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -747,8 +747,6 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
- {QMI_FIXED_INTF(0x1199, 0x9070, 8)}, /* Sierra Wireless MC74xx/EM74xx */
- {QMI_FIXED_INTF(0x1199, 0x9070, 10)}, /* Sierra Wireless MC74xx/EM74xx */
{QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx/EM74xx */
{QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx/EM74xx */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
--
2.8.1

2016-04-22 11:35:12

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 11/78] net: qmi_wwan: Sierra Wireless MC73xx -> Sierra Wireless MC7304/MC7354

From: David Ward <[email protected]>

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

===============

commit e704059272aae2aaa5e5ce7a76e4c27c492e947e upstream.

Other Sierra Wireless MC73xx devices exist, with different USB IDs.

Cc: Bjørn Mork <[email protected]>
Signed-off-by: David Ward <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index f343bfca1068..6408090bc169 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -734,8 +734,8 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */
{QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */
{QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */
- {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */
- {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC7304/MC7354 */
+ {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC7304/MC7354 */
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
{QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
{QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
--
2.8.1

2016-04-22 11:35:10

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 12/78] qmi_wwan: add Sierra Wireless MC74xx/EM74xx

From: Bjørn Mork <[email protected]>

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

===============

commit 0db65fcfcded76fe4f74e3ca9f4e2baf67b683ef upstream.

New device IDs shamelessly lifted from the vendor driver.

Signed-off-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 6408090bc169..a516b7ee02bf 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -747,6 +747,10 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9057, 8)},
{QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */
+ {QMI_FIXED_INTF(0x1199, 0x9070, 8)}, /* Sierra Wireless MC74xx/EM74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9070, 10)}, /* Sierra Wireless MC74xx/EM74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9071, 8)}, /* Sierra Wireless MC74xx/EM74xx */
+ {QMI_FIXED_INTF(0x1199, 0x9071, 10)}, /* Sierra Wireless MC74xx/EM74xx */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
--
2.8.1

2016-04-22 11:35:08

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 14/78] net: qmi_wwan: Add WeTelecom-WPD600N

From: Kristian Evensen <[email protected]>

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

===============

commit e439bd4a4fdeb29488f48f14845ad35607e6302c upstream.

The WeTelecom-WPD600N is an LTE module that, in addition to supporting most
"normal" bands, also supports LTE over 450MHz. Manual testing showed that
only interface number three replies to QMI messages.

Cc: Bjørn Mork <[email protected]>
Signed-off-by: Kristian Evensen <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index abff536ebcf2..4c7ef4f48536 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -772,6 +772,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */
+ {QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */

/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
--
2.8.1

2016-04-22 11:37:15

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 09/78] qmi_wwan: Add support for Dell Wireless 5809e 4G Modem

From: Pieter Hollants <[email protected]>

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

===============

commit 2070c48cf2b78af89ba529c00992eaaa18df8ef7 upstream.

Added the USB IDs 0x413c:0x81b1 for the "Dell Wireless 5809e Gobi(TM) 4G
LTE Mobile Broadband Card", a Dell-branded Sierra Wireless EM7305 LTE
card in M.2 form factor, used eg. in Dell's Latitude E7540 Notebook
series.

Signed-off-by: Pieter Hollants <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 6a7767e1ff39..be1e3f2ebd7e 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -768,6 +768,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
{QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
+ {QMI_FIXED_INTF(0x413c, 0x81b1, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */

/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
--
2.8.1

2016-04-22 11:37:41

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 07/78] net: qmi_wwan: interface #11 in Sierra Wireless MC73xx is not QMI

From: Aleksander Morgado <[email protected]>

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

===============

commit fc0d6e9cd0aefbe5de5ebafb1805f2c59539725b upstream.

This interface is unusable, as the cdc-wdm character device doesn't reply to
any QMI command. Also, the out-of-tree Sierra Wireless GobiNet driver fully
skips it.

Signed-off-by: Aleksander Morgado <[email protected]>
Acked-by: Bjørn Mork <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 6788f7891a4f..04b857b91185 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -736,7 +736,6 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */
{QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */
{QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */
- {QMI_FIXED_INTF(0x1199, 0x68c0, 11)}, /* Sierra Wireless MC73xx */
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
{QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
{QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
--
2.8.1

2016-04-22 11:37:40

by Jiri Slaby

[permalink] [raw]
Subject: [PATCH 3.12 08/78] qmi_wwan: add the second QMI/network interface for Sierra Wireless MC7305/MC7355

From: Reinhard Speyerer <[email protected]>

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

===============

commit e3426ca7bc2957ee072f61360c2b81b4adb629ad upstream.

Sierra Wireless MC7305/MC7355 with USB ID 1199:9041 also provide a
second QMI/network interface like the MC73xx with USB ID 1199:68c0 on
USB interface #10 when used in the appropriate USB configuration.
Add the corresponding QMI_FIXED_INTF entry to the qmi_wwan driver.

Please note that the second QMI/network interface is not working for
early MC73xx firmware versions like 01.08.x as the device does not
respond to QMI messages on the second /dev/cdc-wdm port.

Signed-off-by: Reinhard Speyerer <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Jiri Slaby <[email protected]>
---
drivers/net/usb/qmi_wwan.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 04b857b91185..6a7767e1ff39 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -739,6 +739,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */
{QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */
{QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */
+ {QMI_FIXED_INTF(0x1199, 0x9041, 10)}, /* Sierra Wireless MC7305/MC7355 */
{QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */
{QMI_FIXED_INTF(0x1199, 0x9053, 8)}, /* Sierra Wireless Modem */
{QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */
--
2.8.1

2016-04-22 22:26:24

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/78] 3.12.59-stable review

On Fri, Apr 22, 2016 at 01:05:47PM +0200, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.59 release.
> There are 78 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 Tue Apr 26 13:05:33 CEST 2016.
> Anything received after that time might be too late.
>
Build results:
total: 125 pass: 125 fail: 0
Qemu test results:
total: 84 pass: 84 fail: 0

Details are available at http://kerneltests.org/builders.

Guenter

2016-04-25 14:17:07

by Shuah Khan

[permalink] [raw]
Subject: Re: [PATCH 3.12 00/78] 3.12.59-stable review

On 04/22/2016 05:05 AM, Jiri Slaby wrote:
> This is the start of the stable review cycle for the 3.12.59 release.
> There are 78 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 Tue Apr 26 13:05:33 CEST 2016.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> http://kernel.org/pub/linux/kernel/people/jirislaby/stable-review/patch-3.12.59-rc1.xz
> and the diffstat can be found below.
>

Compiled and booted on my test system. No dmesg regressions.

thanks,
-- Shuah