Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 3.10 007/180] netfilter: x_tables: validate targets of jumps

48 views
Skip to first unread message

Willy Tarreau

unread,
Aug 21, 2016, 11:40:05 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 36472341017529e2b12573093cc0f68719300997 upstream.

When we see a jump also check that the offset gets us to beginning of
a rule (an ipt_entry).

The extra overhead is negible, even with absurd cases.

300k custom rules, 300k jumps to 'next' user chain:
[ plus one jump from INPUT to first userchain ]:

Before:
real 0m24.874s
user 0m7.532s
sys 0m16.076s

After:
real 0m27.464s
user 0m7.436s
sys 0m18.840s

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/netfilter/arp_tables.c | 16 ++++++++++++++++
net/ipv4/netfilter/ip_tables.c | 16 ++++++++++++++++
net/ipv6/netfilter/ip6_tables.c | 16 ++++++++++++++++
3 files changed, 48 insertions(+)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7460b7b..b2adc4b 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -358,6 +358,18 @@ static inline bool unconditional(const struct arpt_entry *e)
memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
}

+static bool find_jump_target(const struct xt_table_info *t,
+ const struct arpt_entry *target)
+{
+ struct arpt_entry *iter;
+
+ xt_entry_foreach(iter, t->entries, t->size) {
+ if (iter == target)
+ return true;
+ }
+ return false;
+}
+
/* Figures out from what hook each rule can be called: returns 0 if
* there are loops. Puts hook bitmask in comefrom.
*/
@@ -451,6 +463,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
/* This a jump; chase it. */
duprintf("Jump rule %u -> %u\n",
pos, newpos);
+ e = (struct arpt_entry *)
+ (entry0 + newpos);
+ if (!find_jump_target(newinfo, e))
+ return 0;
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 8fc22ee..eea26fc 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -434,6 +434,18 @@ ipt_do_table(struct sk_buff *skb,
#endif
}

+static bool find_jump_target(const struct xt_table_info *t,
+ const struct ipt_entry *target)
+{
+ struct ipt_entry *iter;
+
+ xt_entry_foreach(iter, t->entries, t->size) {
+ if (iter == target)
+ return true;
+ }
+ return false;
+}
+
/* Figures out from what hook each rule can be called: returns 0 if
there are loops. Puts hook bitmask in comefrom. */
static int
@@ -531,6 +543,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
/* This a jump; chase it. */
duprintf("Jump rule %u -> %u\n",
pos, newpos);
+ e = (struct ipt_entry *)
+ (entry0 + newpos);
+ if (!find_jump_target(newinfo, e))
+ return 0;
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 63f7876..5eeec96 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -444,6 +444,18 @@ ip6t_do_table(struct sk_buff *skb,
#endif
}

+static bool find_jump_target(const struct xt_table_info *t,
+ const struct ip6t_entry *target)
+{
+ struct ip6t_entry *iter;
+
+ xt_entry_foreach(iter, t->entries, t->size) {
+ if (iter == target)
+ return true;
+ }
+ return false;
+}
+
/* Figures out from what hook each rule can be called: returns 0 if
there are loops. Puts hook bitmask in comefrom. */
static int
@@ -541,6 +553,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
/* This a jump; chase it. */
duprintf("Jump rule %u -> %u\n",
pos, newpos);
+ e = (struct ip6t_entry *)
+ (entry0 + newpos);
+ if (!find_jump_target(newinfo, e))
+ return 0;
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:06 AM8/21/16
to
From: Ursula Braun <ubr...@linux.vnet.ibm.com>

commit 7831b4ff0d926e0deeaabef9db8800ed069a2757 upstream.

A qeth_card contains a napi_struct linked to the net_device during
device probing. This struct must be deleted when removing the qeth
device, otherwise Panic on oops can occur when qeth devices are
repeatedly removed and added.

Fixes: a1c3ed4c9ca ("qeth: NAPI support for l2 and l3 discipline")
Cc: sta...@vger.kernel.org # v2.6.37+
Signed-off-by: Ursula Braun <ubr...@linux.vnet.ibm.com>
Tested-by: Alexander Klein <AL...@de.ibm.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/s390/net/qeth_l2_main.c | 1 +
drivers/s390/net/qeth_l3_main.c | 1 +
2 files changed, 2 insertions(+)

diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index ec8ccda..0090de4 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -898,6 +898,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
qeth_l2_set_offline(cgdev);

if (card->dev) {
+ netif_napi_del(&card->napi);
unregister_netdev(card->dev);
card->dev = NULL;
}
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index c1b0b27..7366bef 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3333,6 +3333,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
qeth_l3_set_offline(cgdev);

if (card->dev) {
+ netif_napi_del(&card->napi);
unregister_netdev(card->dev);
card->dev = NULL;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:06 AM8/21/16
to
From: James Hogan <james...@imgtec.com>

commit 8985d50382359e5bf118fdbefc859d0dbf6cebc7 upstream.

kvm_mips_handle_mapped_seg_tlb_fault() calculates the guest frame number
based on the guest TLB EntryLo values, however it is not range checked
to ensure it lies within the guest_pmap. If the physical memory the
guest refers to is out of range then dump the guest TLB and emit an
internal error.

Fixes: 858dd5d45733 ("KVM/MIPS32: MMU/TLB operations for the Guest.")
Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Paolo Bonzini <pbon...@redhat.com>
Cc: "Radim Krčmář" <rkr...@redhat.com>
Cc: Ralf Baechle <ra...@linux-mips.org>
Cc: linux...@linux-mips.org
Cc: k...@vger.kernel.org
Signed-off-by: Radim Krčmář <rkr...@redhat.com>
[james...@imgtec.com: Backport to v3.10.y - v3.15.y]
Signed-off-by: James Hogan <james...@imgtec.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/kvm/kvm_tlb.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c
index 1e6b1f1..8aba2e5 100644
--- a/arch/mips/kvm/kvm_tlb.c
+++ b/arch/mips/kvm/kvm_tlb.c
@@ -397,6 +397,7 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
struct kvm *kvm = vcpu->kvm;
pfn_t pfn0, pfn1;
+ gfn_t gfn0, gfn1;
long tlb_lo[2];

tlb_lo[0] = tlb->tlb_lo0;
@@ -410,14 +411,24 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
VPN2_MASK & (PAGE_MASK << 1)))
tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >> PAGE_SHIFT) & 1] = 0;

- if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT) < 0)
+ gfn0 = mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT;
+ gfn1 = mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT;
+ if (gfn0 >= kvm->arch.guest_pmap_npages ||
+ gfn1 >= kvm->arch.guest_pmap_npages) {
+ kvm_err("%s: Invalid gfn: [%#llx, %#llx], EHi: %#lx\n",
+ __func__, gfn0, gfn1, tlb->tlb_hi);
+ kvm_mips_dump_guest_tlbs(vcpu);
+ return -1;
+ }
+
+ if (kvm_mips_map_page(kvm, gfn0) < 0)
return -1;

- if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT) < 0)
+ if (kvm_mips_map_page(kvm, gfn1) < 0)
return -1;

- pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT];
- pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT];
+ pfn0 = kvm->arch.guest_pmap[gfn0];
+ pfn1 = kvm->arch.guest_pmap[gfn1];

if (hpa0)
*hpa0 = pfn0 << PAGE_SHIFT;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:06 AM8/21/16
to
From: "dan.ca...@oracle.com" <dan.ca...@oracle.com>

commit e33d085d11e54bc9fb07b2555cd104d8e7b3089b upstream.

'!' has higher precedence than comparisons so the original condition
is equivalent to "if (xspi->remaining_bytes == 0)". This makes the
static checkers complain.

xspi->remaining_bytes is signed and from looking at the code
briefly, I think it might be able to go negative. I suspect that
going negative may cause a bug, but I don't have the hardware and
can't test.

Signed-off-by: Dan Carpenter <dan.ca...@oracle.com>
Signed-off-by: Mark Brown <bro...@linaro.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/spi/spi-xilinx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 34d18dc..109a535 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -315,7 +315,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
}

/* See if there is more data to send */
- if (!xspi->remaining_bytes > 0)
+ if (xspi->remaining_bytes <= 0)
break;
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:06 AM8/21/16
to
From: Iosif Harutyunov <iharu...@SonicWALL.com>

commit 714fb87e8bc05ff78255afc0dca981e8c5242785 upstream.

Install the UBI device object before we arm sysfs.
Otherwise udev tries to read sysfs attributes before UBI is ready and
udev rules will not match.

Cc: <sta...@vger.kernel.org>
Signed-off-by: Iosif Harutyunov <iharu...@sonicwall.com>
[rw: massaged commit message]
Signed-off-by: Richard Weinberger <ric...@nod.at>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/mtd/ubi/build.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index a561335..03331c1 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -997,6 +997,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
goto out_detach;
}

+ /* Make device "available" before it becomes accessible via sysfs */
+ ubi_devices[ubi_num] = ubi;
+
err = uif_init(ubi, &ref);
if (err)
goto out_detach;
@@ -1041,7 +1044,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
wake_up_process(ubi->bgt_thread);
spin_unlock(&ubi->wl_lock);

- ubi_devices[ubi_num] = ubi;
ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL);
return ubi_num;

@@ -1052,6 +1054,7 @@ out_uif:
ubi_assert(ref);
uif_close(ubi);
out_detach:
+ ubi_devices[ubi_num] = NULL;
ubi_wl_close(ubi);
ubi_free_internal_volumes(ubi);
vfree(ubi->vtbl);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:06 AM8/21/16
to
From: Vignesh R <vign...@ti.com>

commit a246b8198f776a16d1d3a3bbfc2d437bad766b29 upstream.

NBANK() macro assumes that ngpios is a multiple of 8(BANK_SZ) and
hence results in 0 banks for PCA9536 which has just 4 gpios. This is
wrong as PCA9356 has 1 bank with 4 gpios. This results in uninitialized
PCA953X_INVERT register. Fix this by using DIV_ROUND_UP macro in
NBANK().

Cc: sta...@vger.kernel.org
Signed-off-by: Vignesh R <vign...@ti.com>
Signed-off-by: Linus Walleij <linus....@linaro.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/gpio/gpio-pca953x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 426c51d..ac11e45 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -75,7 +75,7 @@ MODULE_DEVICE_TABLE(i2c, pca953x_id);
#define MAX_BANK 5
#define BANK_SZ 8

-#define NBANK(chip) (chip->gpio_chip.ngpio / BANK_SZ)
+#define NBANK(chip) DIV_ROUND_UP(chip->gpio_chip.ngpio, BANK_SZ)

struct pca953x_chip {
unsigned gpio_start;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:06 AM8/21/16
to
From: Cyril Bur <cyri...@gmail.com>

commit 8e96a87c5431c256feb65bcfc5aec92d9f7839b6 upstream.

Userspace can quite legitimately perform an exec() syscall with a
suspended transaction. exec() does not return to the old process, rather
it load a new one and starts that, the expectation therefore is that the
new process starts not in a transaction. Currently exec() is not treated
any differently to any other syscall which creates problems.

Firstly it could allow a new process to start with a suspended
transaction for a binary that no longer exists. This means that the
checkpointed state won't be valid and if the suspended transaction were
ever to be resumed and subsequently aborted (a possibility which is
exceedingly likely as exec()ing will likely doom the transaction) the
new process will jump to invalid state.

Secondly the incorrect attempt to keep the transactional state while
still zeroing state for the new process creates at least two TM Bad
Things. The first triggers on the rfid to return to userspace as
start_thread() has given the new process a 'clean' MSR but the suspend
will still be set in the hardware MSR. The second TM Bad Thing triggers
in __switch_to() as the processor is still transactionally suspended but
__switch_to() wants to zero the TM sprs for the new process.

This is an example of the outcome of calling exec() with a suspended
transaction. Note the first 700 is likely the first TM bad thing
decsribed earlier only the kernel can't report it as we've loaded
userspace registers. c000000000009980 is the rfid in
fast_exception_return()

Bad kernel stack pointer 3fffcfa1a370 at c000000000009980
Oops: Bad kernel stack pointer, sig: 6 [#1]
CPU: 0 PID: 2006 Comm: tm-execed Not tainted
NIP: c000000000009980 LR: 0000000000000000 CTR: 0000000000000000
REGS: c00000003ffefd40 TRAP: 0700 Not tainted
MSR: 8000000300201031 <SF,ME,IR,DR,LE,TM[SE]> CR: 00000000 XER: 00000000
CFAR: c0000000000098b4 SOFTE: 0
PACATMSCRATCH: b00000010000d033
GPR00: 0000000000000000 00003fffcfa1a370 0000000000000000 0000000000000000
GPR04: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR12: 00003fff966611c0 0000000000000000 0000000000000000 0000000000000000
NIP [c000000000009980] fast_exception_return+0xb0/0xb8
LR [0000000000000000] (null)
Call Trace:
Instruction dump:
f84d0278 e9a100d8 7c7b03a6 e84101a0 7c4ff120 e8410170 7c5a03a6 e8010070
e8410080 e8610088 e8810090 e8210078 <4c000024> 48000000 e8610178 88ed023b

Kernel BUG at c000000000043e80 [verbose debug info unavailable]
Unexpected TM Bad Thing exception at c000000000043e80 (msr 0x201033)
Oops: Unrecoverable exception, sig: 6 [#2]
CPU: 0 PID: 2006 Comm: tm-execed Tainted: G D
task: c0000000fbea6d80 ti: c00000003ffec000 task.ti: c0000000fb7ec000
NIP: c000000000043e80 LR: c000000000015a24 CTR: 0000000000000000
REGS: c00000003ffef7e0 TRAP: 0700 Tainted: G D
MSR: 8000000300201033 <SF,ME,IR,DR,RI,LE,TM[SE]> CR: 28002828 XER: 00000000
CFAR: c000000000015a20 SOFTE: 0
PACATMSCRATCH: b00000010000d033
GPR00: 0000000000000000 c00000003ffefa60 c000000000db5500 c0000000fbead000
GPR04: 8000000300001033 2222222222222222 2222222222222222 00000000ff160000
GPR08: 0000000000000000 800000010000d033 c0000000fb7e3ea0 c00000000fe00004
GPR12: 0000000000002200 c00000000fe00000 0000000000000000 0000000000000000
GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
GPR20: 0000000000000000 0000000000000000 c0000000fbea7410 00000000ff160000
GPR24: c0000000ffe1f600 c0000000fbea8700 c0000000fbea8700 c0000000fbead000
GPR28: c000000000e20198 c0000000fbea6d80 c0000000fbeab680 c0000000fbea6d80
NIP [c000000000043e80] tm_restore_sprs+0xc/0x1c
LR [c000000000015a24] __switch_to+0x1f4/0x420
Call Trace:
Instruction dump:
7c800164 4e800020 7c0022a6 f80304a8 7c0222a6 f80304b0 7c0122a6 f80304b8
4e800020 e80304a8 7c0023a6 e80304b0 <7c0223a6> e80304b8 7c0123a6 4e800020

This fixes CVE-2016-5828.

Fixes: bc2a9408fa65 ("powerpc: Hook in new transactional memory code")
Cc: sta...@vger.kernel.org # v3.9+
Signed-off-by: Cyril Bur <cyri...@gmail.com>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/powerpc/kernel/process.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index d55357e..a5e339806 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1088,6 +1088,16 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
current->thread.regs = regs - 1;
}

+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ /*
+ * Clear any transactional state, we're exec()ing. The cause is
+ * not important as there will never be a recheckpoint so it's not
+ * user visible.
+ */
+ if (MSR_TM_SUSPENDED(mfmsr()))
+ tm_reclaim_current(0);
+#endif
+
memset(regs->gpr, 0, sizeof(regs->gpr));
regs->ctr = 0;
regs->link = 0;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit f24e230d257af1ad7476c6e81a8dc3127a74204e 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.

Base chains enforce absolute verdict.

User defined chains are supposed to end with an unconditional return,
xtables userspace adds them automatically.

But if such return is missing we will move to non-existent next rule.

CVE-2016-3134

Reported-by: Ben Hawkes <haw...@google.com>
Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Chas Williams <3ch...@gmail.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/netfilter/arp_tables.c | 8 +++++---
net/ipv4/netfilter/ip_tables.c | 4 ++++
net/ipv6/netfilter/ip6_tables.c | 4 ++++
3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 456fc6e..7460b7b 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -430,6 +430,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
size = e->next_offset;
e = (struct arpt_entry *)
(entry0 + pos + size);
+ if (pos + size >= newinfo->size)
+ return 0;
e->counters.pcnt = pos;
pos += size;
} else {
@@ -452,6 +454,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;
+ if (newpos >= newinfo->size)
+ return 0;
}
e = (struct arpt_entry *)
(entry0 + newpos);
@@ -675,10 +679,8 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
}
}

- if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) {
- duprintf("Looping hook\n");
+ if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
return -ELOOP;
- }

/* Finally, each sanity check must pass */
i = 0;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a5bd3c8..8fc22ee 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -511,6 +511,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
size = e->next_offset;
e = (struct ipt_entry *)
(entry0 + pos + size);
+ if (pos + size >= newinfo->size)
+ return 0;
e->counters.pcnt = pos;
pos += size;
} else {
@@ -532,6 +534,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;
+ if (newpos >= newinfo->size)
+ return 0;
}
e = (struct ipt_entry *)
(entry0 + newpos);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index fb8a146..63f7876 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -521,6 +521,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
size = e->next_offset;
e = (struct ip6t_entry *)
(entry0 + pos + size);
+ if (pos + size >= newinfo->size)
+ return 0;
e->counters.pcnt = pos;
pos += size;
} else {
@@ -542,6 +544,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;
+ if (newpos >= newinfo->size)
+ return 0;
}
e = (struct ip6t_entry *)
(entry0 + newpos);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Nicolai Stange <nics...@gmail.com>

commit b5cb316cdf3a3f5f6125412b0f6065185240cfdc upstream.

Currently, in mb_find_order_for_block(), there's a loop like the following:

while (order <= e4b->bd_blkbits + 1) {
...
bb += 1 << (e4b->bd_blkbits - order);
}

Note that the updated bb is used in the loop's next iteration only.

However, at the last iteration, that is at order == e4b->bd_blkbits + 1,
the shift count becomes negative (c.f. C99 6.5.7(3)) and UBSAN reports

UBSAN: Undefined behaviour in fs/ext4/mballoc.c:1281:11
shift exponent -1 is negative
[...]
Call Trace:
[<ffffffff818c4d35>] dump_stack+0xbc/0x117
[<ffffffff818c4c79>] ? _atomic_dec_and_lock+0x169/0x169
[<ffffffff819411bb>] ubsan_epilogue+0xd/0x4e
[<ffffffff81941cbc>] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
[<ffffffff81941ac1>] ? __ubsan_handle_load_invalid_value+0x158/0x158
[<ffffffff816e93a0>] ? ext4_mb_generate_from_pa+0x590/0x590
[<ffffffff816502c8>] ? ext4_read_block_bitmap_nowait+0x598/0xe80
[<ffffffff816e7b7e>] mb_find_order_for_block+0x1ce/0x240
[...]

Unless compilers start to do some fancy transformations (which at least
GCC 6.0.0 doesn't currently do), the issue is of cosmetic nature only: the
such calculated value of bb is never used again.

Silence UBSAN by introducing another variable, bb_incr, holding the next
increment to apply to bb and adjust that one by right shifting it by one
position per loop iteration.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=114701
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112161

Cc: sta...@vger.kernel.org
Signed-off-by: Nicolai Stange <nics...@gmail.com>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/ext4/mballoc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 61ee016..b2e9940 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -1232,6 +1232,7 @@ static void ext4_mb_unload_buddy(struct ext4_buddy *e4b)
static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
{
int order = 1;
+ int bb_incr = 1 << (e4b->bd_blkbits - 1);
void *bb;

BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
@@ -1244,7 +1245,8 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
/* this block is part of buddy of order 'order' */
return order;
}
- bb += 1 << (e4b->bd_blkbits - order);
+ bb += bb_incr;
+ bb_incr >>= 1;
order++;
}
return 0;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit ce683e5f9d045e5d67d1312a42b359cb2ab2a13c upstream.

We're currently asserting that targetoff + targetsize <= nextoff.

Extend it to also check that targetoff is >= sizeof(xt_entry).
Since this is generic code, add an argument pointing to the start of the
match/target, we can then derive the base structure size from the delta.

We also need the e->elems pointer in a followup change to validate matches.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
include/linux/netfilter/x_tables.h | 4 ++--
net/ipv4/netfilter/arp_tables.c | 5 +++--
net/ipv4/netfilter/ip_tables.c | 5 +++--
net/ipv6/netfilter/ip6_tables.c | 5 +++--
net/netfilter/x_tables.c | 17 +++++++++++++++--
5 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 8dfd3dd..8bb7706 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -239,7 +239,7 @@ extern void xt_unregister_match(struct xt_match *target);
extern int xt_register_matches(struct xt_match *match, unsigned int n);
extern void xt_unregister_matches(struct xt_match *match, unsigned int n);

-int xt_check_entry_offsets(const void *base,
+int xt_check_entry_offsets(const void *base, const char *elems,
unsigned int target_offset,
unsigned int next_offset);

@@ -437,7 +437,7 @@ extern void xt_compat_target_from_user(struct xt_entry_target *t,
void **dstptr, unsigned int *size);
extern int xt_compat_target_to_user(const struct xt_entry_target *t,
void __user **dstptr, unsigned int *size);
-int xt_compat_check_entry_offsets(const void *base,
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
unsigned int target_offset,
unsigned int next_offset);

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 73b3ab9..bb329cb 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -577,7 +577,8 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
if (!arp_checkentry(&e->arp))
return -EINVAL;

- err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+ err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+ e->next_offset);
if (err)
return err;

@@ -1239,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
if (!arp_checkentry(&e->arp))
return -EINVAL;

- ret = xt_compat_check_entry_offsets(e, e->target_offset,
+ ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
e->next_offset);
if (ret)
return ret;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 946e91a..29f3092 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -737,7 +737,8 @@ check_entry_size_and_hooks(struct ipt_entry *e,
if (!ip_checkentry(&e->ip))
return -EINVAL;

- err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+ err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+ e->next_offset);
if (err)
return err;

@@ -1504,7 +1505,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
if (!ip_checkentry(&e->ip))
return -EINVAL;

- ret = xt_compat_check_entry_offsets(e,
+ ret = xt_compat_check_entry_offsets(e, e->elems,
e->target_offset, e->next_offset);
if (ret)
return ret;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 5f98e7d..df9947d 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -748,7 +748,8 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
if (!ip6_checkentry(&e->ipv6))
return -EINVAL;

- err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
+ err = xt_check_entry_offsets(e, e->elems, e->target_offset,
+ e->next_offset);
if (err)
return err;

@@ -1516,7 +1517,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
if (!ip6_checkentry(&e->ipv6))
return -EINVAL;

- ret = xt_compat_check_entry_offsets(e,
+ ret = xt_compat_check_entry_offsets(e, e->elems,
e->target_offset, e->next_offset);
if (ret)
return ret;
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 37f7eda..ea14746 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -565,14 +565,17 @@ struct compat_xt_standard_target {
compat_uint_t verdict;
};

-/* see xt_check_entry_offsets */
-int xt_compat_check_entry_offsets(const void *base,
+int xt_compat_check_entry_offsets(const void *base, const char *elems,
unsigned int target_offset,
unsigned int next_offset)
{
+ long size_of_base_struct = elems - (const char *)base;
const struct compat_xt_entry_target *t;
const char *e = base;

+ if (target_offset < size_of_base_struct)
+ return -EINVAL;
+
if (target_offset + sizeof(*t) > next_offset)
return -EINVAL;

@@ -596,12 +599,16 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets);
* xt_check_entry_offsets - validate arp/ip/ip6t_entry
*
* @base: pointer to arp/ip/ip6t_entry
+ * @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems
* @target_offset: the arp/ip/ip6_t->target_offset
* @next_offset: the arp/ip/ip6_t->next_offset
*
* validates that target_offset and next_offset are sane.
* Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
*
+ * This function does not validate the targets or matches themselves, it
+ * only tests that all the offsets and sizes are correct.
+ *
* The arp/ip/ip6t_entry structure @base must have passed following tests:
* - it must point to a valid memory location
* - base to base + next_offset must be accessible, i.e. not exceed allocated
@@ -610,12 +617,18 @@ EXPORT_SYMBOL(xt_compat_check_entry_offsets);
* Return: 0 on success, negative errno on failure.
*/
int xt_check_entry_offsets(const void *base,
+ const char *elems,
unsigned int target_offset,
unsigned int next_offset)
{
+ long size_of_base_struct = elems - (const char *)base;
const struct xt_entry_target *t;
const char *e = base;

+ /* target start is within the ip/ip6/arpt_entry struct */
+ if (target_offset < size_of_base_struct)
+ return -EINVAL;
+
if (target_offset + sizeof(*t) > next_offset)
return -EINVAL;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Alex Deucher <alexande...@amd.com>

commit 05082b8bbd1a0ffc74235449c4b8930a8c240f85 upstream.

When executing in a PCI passthrough based virtuzliation environment, the
hypervisor will usually attempt to send a PCIe bus reset signal to the
ASIC when the VM reboots. In this scenario, the card is not correctly
initialized, but we still consider it to be posted. Therefore, in a
passthrough based environemnt we should always post the card to guarantee
it is in a good state for driver initialization.

Ported from amdgpu commit:
amdgpu: fix asic initialization for virtualized environments

Cc: Andres Rodriguez <andres.r...@amd.com>
Cc: Alex Williamson <alex.wi...@redhat.com>
Signed-off-by: Alex Deucher <alexande...@amd.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/gpu/drm/radeon/radeon_device.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 8df1525..e9db3f8 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -449,6 +449,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
/*
* GPU helpers function.
*/
+
+/**
+ * radeon_device_is_virtual - check if we are running is a virtual environment
+ *
+ * Check if the asic has been passed through to a VM (all asics).
+ * Used at driver startup.
+ * Returns true if virtual or false if not.
+ */
+static bool radeon_device_is_virtual(void)
+{
+#ifdef CONFIG_X86
+ return boot_cpu_has(X86_FEATURE_HYPERVISOR);
+#else
+ return false;
+#endif
+}
+
/**
* radeon_card_posted - check if the hw has already been initialized
*
@@ -462,6 +479,10 @@ bool radeon_card_posted(struct radeon_device *rdev)
{
uint32_t reg;

+ /* for pass through, always force asic_init */
+ if (radeon_device_is_virtual())
+ return false;
+
/* required for EFI mode on macbook2,1 which uses an r5xx asic */
if (efi_enabled(EFI_BOOT) &&
(rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Andi Kleen <a...@linux.intel.com>

commit 54c2f3fdb941204cad136024c7b854b7ad112ab6 upstream.

Signed-off-by: Andi Kleen <a...@linux.intel.com>
Link: http://lkml.kernel.org/r/1375740170-7446-12-...@firstfloor.org
Signed-off-by: H. Peter Anvin <h...@linux.intel.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/kernel/apm_32.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 53a4e27..3ab0343 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -392,7 +392,7 @@ static struct cpuidle_device apm_cpuidle_device;
/*
* Local variables
*/
-static struct {
+__visible struct {
unsigned long offset;
unsigned short segment;
} apm_bios_entry;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Mike Snitzer <sni...@redhat.com>

commit 99f3c90d0d85708e7401a81ce3314e50bf7f2819 upstream.

When the corrupt_bio_byte feature was introduced it caused READ bios to
no longer be errored with -EIO during the down_interval. This had to do
with the complexity of needing to submit READs if the corrupt_bio_byte
feature was used.

Fix it so READ bios are properly errored with -EIO; doing so early in
flakey_map() as long as there isn't a match for the corrupt_bio_byte
feature.

Fixes: a3998799fb4df ("dm flakey: add corrupt_bio_byte feature")
Reported-by: Akira Hayakawa <ruby...@gmail.com>
Signed-off-by: Mike Snitzer <sni...@redhat.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/md/dm-flakey.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index 7fcf21c..a9a47cd 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -286,10 +286,16 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
pb->bio_submitted = true;

/*
- * Map reads as normal.
+ * Map reads as normal only if corrupt_bio_byte set.
*/
- if (bio_data_dir(bio) == READ)
- goto map_bio;
+ if (bio_data_dir(bio) == READ) {
+ /* If flags were specified, only corrupt those that match. */
+ if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) &&
+ all_corrupt_bio_flags_match(bio, fc))
+ goto map_bio;
+ else
+ return -EIO;
+ }

/*
* Drop writes?
@@ -327,12 +333,13 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)

/*
* Corrupt successful READs while in down state.
- * If flags were specified, only corrupt those that match.
*/
- if (fc->corrupt_bio_byte && !error && pb->bio_submitted &&
- (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) &&
- all_corrupt_bio_flags_match(bio, fc))
- corrupt_bio_data(bio, fc);
+ if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) {
+ if (fc->corrupt_bio_byte)
+ corrupt_bio_data(bio, fc);
+ else
+ return -EIO;
+ }

return error;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Tomáš Trnka <ttr...@mail.muni.cz>

commit c0cb8bf3a8e4bd82e640862cdd8891400405cb89 upstream.

The length of the GSS MIC token need not be a multiple of four bytes.
It is then padded by XDR to a multiple of 4 B, but unwrap_integ_data()
would previously only trim mic.len + 4 B. The remaining up to three
bytes would then trigger a check in nfs4svc_decode_compoundargs(),
leading to a "garbage args" error and mount failure:

nfs4svc_decode_compoundargs: compound not properly padded!
nfsd: failed to decode arguments!

This would prevent older clients using the pre-RFC 4121 MIC format
(37-byte MIC including a 9-byte OID) from mounting exports from v3.9+
servers using krb5i.

The trimming was introduced by commit 4c190e2f913f ("sunrpc: trim off
trailing checksum before returning decrypted or integrity authenticated
buffer").

Fixes: 4c190e2f913f "unrpc: trim off trailing checksum..."
Signed-off-by: Tomáš Trnka <ttr...@mail.muni.cz>
Cc: sta...@vger.kernel.org
Acked-by: Jeff Layton <jla...@poochiereds.net>
Signed-off-by: J. Bruce Fields <bfi...@redhat.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/sunrpc/auth_gss/svcauth_gss.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 29b4ba9..62663a0 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -859,8 +859,8 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g
goto out;
if (svc_getnl(&buf->head[0]) != seq)
goto out;
- /* trim off the mic at the end before returning */
- xdr_buf_trim(buf, mic.len + 4);
+ /* trim off the mic and padding at the end before returning */
+ xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
stat = 0;
out:
kfree(mic.data);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:07 AM8/21/16
to
From: Martin Willi <mar...@strongswan.org>

commit 62397da50bb20a6b812c949ef465d7e69fe54bb6 upstream.

A wmediumd that does not send this attribute causes a NULL pointer
dereference, as the attribute is accessed even if it does not exist.

The attribute was required but never checked ever since userspace frame
forwarding has been introduced. The issue gets more problematic once we
allow wmediumd registration from user namespaces.

Fixes: 7882513bacb1 ("mac80211_hwsim driver support userspace frame tx/rx")
Signed-off-by: Martin Willi <mar...@strongswan.org>
Signed-off-by: Johannes Berg <johann...@intel.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/net/wireless/mac80211_hwsim.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index cb34c78..735c266 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1931,6 +1931,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
!info->attrs[HWSIM_ATTR_FLAGS] ||
!info->attrs[HWSIM_ATTR_COOKIE] ||
+ !info->attrs[HWSIM_ATTR_SIGNAL] ||
!info->attrs[HWSIM_ATTR_TX_INFO])
goto out;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:08 AM8/21/16
to
From: Masami Hiramatsu <mhir...@kernel.org>

commit dcfc47248d3f7d28df6f531e6426b933de94370d upstream.

Fix kprobe_fault_handler() to clear the TF (trap flag) bit of
the flags register in the case of a fault fixup on single-stepping.

If we put a kprobe on the instruction which caused a
page fault (e.g. actual mov instructions in copy_user_*),
that fault happens on the single-stepping buffer. In this
case, kprobes resets running instance so that the CPU can
retry execution on the original ip address.

However, current code forgets to reset the TF bit. Since this
fault happens with TF bit set for enabling single-stepping,
when it retries, it causes a debug exception and kprobes
can not handle it because it already reset itself.

On the most of x86-64 platform, it can be easily reproduced
by using kprobe tracer. E.g.

# cd /sys/kernel/debug/tracing
# echo p copy_user_enhanced_fast_string+5 > kprobe_events
# echo 1 > events/kprobes/enable

And you'll see a kernel panic on do_debug(), since the debug
trap is not handled by kprobes.

To fix this problem, we just need to clear the TF bit when
resetting running kprobe.

Signed-off-by: Masami Hiramatsu <mhir...@kernel.org>
Reviewed-by: Ananth N Mavinakayanahalli <ana...@linux.vnet.ibm.com>
Acked-by: Steven Rostedt <ros...@goodmis.org>
Cc: Alexander Shishkin <alexander...@linux.intel.com>
Cc: Andy Lutomirski <lu...@kernel.org>
Cc: Arnaldo Carvalho de Melo <ac...@redhat.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brg...@gmail.com>
Cc: Denys Vlasenko <dvla...@redhat.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Stephane Eranian <era...@google.com>
Cc: Thomas Gleixner <tg...@linutronix.de>
Cc: Vince Weaver <vincent...@maine.edu>
Cc: syst...@sourceware.org
Cc: sta...@vger.kernel.org # All the way back to ancient kernels
Link: http://lkml.kernel.org/r/20160611140648.25885.37482.stgit@devbox
[ Updated the comments. ]
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/kernel/kprobes/core.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 0c6c07c..766aa3b 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -908,7 +908,19 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
* normal page fault.
*/
regs->ip = (unsigned long)cur->addr;
+ /*
+ * Trap flag (TF) has been set here because this fault
+ * happened where the single stepping will be done.
+ * So clear it by resetting the current kprobe:
+ */
+ regs->flags &= ~X86_EFLAGS_TF;
+
+ /*
+ * If the TF flag was set before the kprobe hit,
+ * don't touch it:
+ */
regs->flags |= kcb->kprobe_old_flags;
+
if (kcb->kprobe_status == KPROBE_REENTER)
restore_previous_kprobe(kcb);
else
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:08 AM8/21/16
to
From: Ping Cheng <ping...@gmail.com>

commit 12afb34400eb2b301f06b2aa3535497d14faee59 upstream.

Somehow the patch that added two-finger touch support forgot to update
W8001_MAX_LENGTH from 11 to 13.

Signed-off-by: Ping Cheng <pi...@wacom.com>
Reviewed-by: Peter Hutterer <peter.h...@who-t.net>
Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry....@gmail.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/input/touchscreen/wacom_w8001.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 9a83be6..abba112 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -28,7 +28,7 @@ MODULE_AUTHOR("Jaya Kumar <jayakum...@gmail.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

-#define W8001_MAX_LENGTH 11
+#define W8001_MAX_LENGTH 13
#define W8001_LEAD_MASK 0x80
#define W8001_LEAD_BYTE 0x80
#define W8001_TAB_MASK 0x40
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:08 AM8/21/16
to
From: Alan Stern <st...@rowland.harvard.edu>

commit e50293ef9775c5f1cf3fcc093037dd6a8c5684ea upstream.

Commit 8520f38099cc ("USB: change hub initialization sleeps to
delayed_work") changed the hub_activate() routine to make part of it
run in a workqueue. However, the commit failed to take a reference to
the usb_hub structure or to lock the hub interface while doing so. As
a result, if a hub is plugged in and quickly unplugged before the work
routine can run, the routine will try to access memory that has been
deallocated. Or, if the hub is unplugged while the routine is
running, the memory may be deallocated while it is in active use.

This patch fixes the problem by taking a reference to the usb_hub at
the start of hub_activate() and releasing it at the end (when the work
is finished), and by locking the hub interface while the work routine
is running. It also adds a check at the start of the routine to see
if the hub has already been disconnected, in which nothing should be
done.

CVE-2015-8816

Signed-off-by: Alan Stern <st...@rowland.harvard.edu>
Reported-by: Alexandru Cornea <alexandr...@intel.com>
Tested-by: Alexandru Cornea <alexandr...@intel.com>
Fixes: 8520f38099cc ("USB: change hub initialization sleeps to delayed_work")
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
[ luis: backported to 3.16:
- Added forward declaration of hub_release() which mainline had with commit
32a6958998c5 ("usb: hub: convert khubd into workqueue") ]
Signed-off-by: Luis Henriques <luis.he...@canonical.com>
Signed-off-by: Charles (Chas) Williams <ciwi...@brocade.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/usb/core/hub.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 8eb2de6..4e5156d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -113,6 +113,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 100

+static void hub_release(struct kref *kref);
static int usb_reset_and_verify_device(struct usb_device *udev);

static inline char *portspeed(struct usb_hub *hub, int portstatus)
@@ -1024,10 +1025,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
unsigned delay;

/* Continue a partial initialization */
- if (type == HUB_INIT2)
- goto init2;
- if (type == HUB_INIT3)
+ if (type == HUB_INIT2 || type == HUB_INIT3) {
+ device_lock(hub->intfdev);
+
+ /* Was the hub disconnected while we were waiting? */
+ if (hub->disconnected) {
+ device_unlock(hub->intfdev);
+ kref_put(&hub->kref, hub_release);
+ return;
+ }
+ if (type == HUB_INIT2)
+ goto init2;
goto init3;
+ }
+ kref_get(&hub->kref);

/* The superspeed hub except for root hub has to use Hub Depth
* value as an offset into the route string to locate the bits
@@ -1224,6 +1235,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
schedule_delayed_work(&hub->init_work,
msecs_to_jiffies(delay));
+ device_unlock(hub->intfdev);
return; /* Continues at init3: below */
} else {
msleep(delay);
@@ -1244,6 +1256,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
/* Allow autosuspend if it was suppressed */
if (type <= HUB_INIT3)
usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
+
+ if (type == HUB_INIT2 || type == HUB_INIT3)
+ device_unlock(hub->intfdev);
+
+ kref_put(&hub->kref, hub_release);
}

/* Implement the continuations for the delays above */
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:08 AM8/21/16
to
From: Andrew Goodbody <andrew....@cambrionix.com>

commit f3eec0cf784e0d6c47822ca6b66df3d5812af7e6 upstream.

shared_fifo endpoints would only get a previous tx state cleared
out, the rx state was only cleared for non shared_fifo endpoints
Change this so that the rx state is cleared for all endpoints.
This addresses an issue that resulted in rx packets being dropped
silently.

Signed-off-by: Andrew Goodbody <andrew....@cambrionix.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Bin Liu <b-...@ti.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/usb/musb/musb_host.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index cdadbe6..c6cc520 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -581,14 +581,13 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
musb_writew(ep->regs, MUSB_TXCSR, 0);

/* scrub all previous state, clearing toggle */
- } else {
- csr = musb_readw(ep->regs, MUSB_RXCSR);
- if (csr & MUSB_RXCSR_RXPKTRDY)
- WARNING("rx%d, packet/%d ready?\n", ep->epnum,
- musb_readw(ep->regs, MUSB_RXCOUNT));
-
- musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
}
+ csr = musb_readw(ep->regs, MUSB_RXCSR);
+ if (csr & MUSB_RXCSR_RXPKTRDY)
+ WARNING("rx%d, packet/%d ready?\n", ep->epnum,
+ musb_readw(ep->regs, MUSB_RXCOUNT));
+
+ musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);

/* target addr and (for multipoint) hub addr/port */
if (musb->is_multipoint) {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:09 AM8/21/16
to
From: Vegard Nossum <vegard...@oracle.com>

commit 554a5ccc4e4a20c5f3ec859de0842db4b4b9c77e upstream.

If we hit this error when mounted with errors=continue or
errors=remount-ro:

EXT4-fs error (device loop0): ext4_mb_mark_diskspace_used:2940: comm ext4.exe: Allocating blocks 5090-6081 which overlap fs metadata

then ext4_mb_new_blocks() will call ext4_mb_release_context() and try to
continue. However, ext4_mb_release_context() is the wrong thing to call
here since we are still actually using the allocation context.

Instead, just error out. We could retry the allocation, but there is a
possibility of getting stuck in an infinite loop instead, so this seems
safer.

[ Fixed up so we don't return EAGAIN to userspace. --tytso ]

Fixes: 8556e8f3b6 ("ext4: Don't allow new groups to be added during block allocation")
Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Cc: Aneesh Kumar K.V <aneesh...@linux.vnet.ibm.com>
Cc: sta...@vger.kernel.org
[wt: 3.10 doesn't have EFSCORRUPTED, but XFS uses EUCLEAN as does 3.14
on this patch so use this instead]

Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/ext4/mballoc.c | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 4d73946..08b4495 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2876,7 +2876,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
"fs metadata", block, block+len);
/* File system mounted not to panic on error
- * Fix the bitmap and repeat the block allocation
+ * Fix the bitmap and return EUCLEAN
* We leak some of the blocks here.
*/
ext4_lock_group(sb, ac->ac_b_ex.fe_group);
@@ -2885,7 +2885,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
if (!err)
- err = -EAGAIN;
+ err = -EUCLEAN;
goto out_err;
}

@@ -4452,18 +4452,7 @@ repeat:
}
if (likely(ac->ac_status == AC_STATUS_FOUND)) {
*errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
- if (*errp == -EAGAIN) {
- /*
- * drop the reference that we took
- * in ext4_mb_use_best_found
- */
- ext4_mb_release_context(ac);
- ac->ac_b_ex.fe_group = 0;
- ac->ac_b_ex.fe_start = 0;
- ac->ac_b_ex.fe_len = 0;
- ac->ac_status = AC_STATUS_CONTINUE;
- goto repeat;
- } else if (*errp) {
+ if (*errp) {
ext4_discard_allocated_blocks(ac);
goto errout;
} else {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:10 AM8/21/16
to
From: Alex Deucher <alexande...@amd.com>

commit 3edc38a0facef45ee22af8afdce3737f421f36ab upstream.

Some of the checks didn't handle frev 2 tables properly.

Signed-off-by: Alex Deucher <alexande...@amd.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/gpu/drm/radeon/radeon_atombios.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index f3cce23..f4b9b1c 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -1144,7 +1144,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
le16_to_cpu(firmware_info->info.usReferenceClock);
p1pll->reference_div = 0;

- if (crev < 2)
+ if ((frev < 2) && (crev < 2))
p1pll->pll_out_min =
le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
else
@@ -1153,7 +1153,7 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
p1pll->pll_out_max =
le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);

- if (crev >= 4) {
+ if (((frev < 2) && (crev >= 4)) || (frev >= 2)) {
p1pll->lcd_pll_out_min =
le16_to_cpu(firmware_info->info_14.usLcdMinPixelClockPLL_Output) * 100;
if (p1pll->lcd_pll_out_min == 0)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:10 AM8/21/16
to
From: Matthias Schiffer <msch...@universe-factory.net>

commit f5b556c94c8490d42fea79d7b4ae0ecbc291e69d upstream.

This makes the ath79 bootconsole behave the same way as the generic 8250
bootconsole.

Also waiting for TEMT (transmit buffer is empty) instead of just THRE
(transmit buffer is not full) ensures that all characters have been
transmitted before the real serial driver starts reconfiguring the serial
controller (which would sometimes result in garbage being transmitted.)
This change does not cause a visible performance loss.

In addition, this seems to fix a hang observed in certain configurations on
many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver.

A more complete follow-up patch will disable 8250 autoconfig for ath79
altogether (the serial controller is detected as a 16550A, which is not
fully compatible with the ath79 serial, and the autoconfig may lead to
undefined behavior on ath79.)

Cc: <sta...@vger.kernel.org>
Signed-off-by: Matthias Schiffer <msch...@universe-factory.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/ath79/early_printk.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
index b955faf..d1adc59 100644
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
} while (1);
}

+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
static void prom_putchar_ar71xx(unsigned char ch)
{
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));

- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
__raw_writel(ch, base + UART_TX * 4);
- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
}

static void prom_putchar_ar933x(unsigned char ch)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:10 AM8/21/16
to
From: Yuchung Cheng <ych...@google.com>

commit ce3cf4ec0305919fc69a972f6c2b2efd35d36abc upstream.

The v6 tcp stats scan do not provide TLP and ER timer information
correctly like the v4 version . This patch fixes that.

Fixes: 6ba8a3b19e76 ("tcp: Tail loss probe (TLP)")
Fixes: eed530b6c676 ("tcp: early retransmit")
Signed-off-by: Yuchung Cheng <ych...@google.com>
Signed-off-by: Neal Cardwell <ncar...@google.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv6/tcp_ipv6.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4659b8a..41c026f 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1767,7 +1767,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
destp = ntohs(inet->inet_dport);
srcp = ntohs(inet->inet_sport);

- if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
+ if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
+ icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
+ icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
timer_active = 1;
timer_expires = icsk->icsk_timeout;
} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:10 AM8/21/16
to
From: Xiubo Li <lix...@cmss.chinamobile.com>

commit caf1ff26e1aa178133df68ac3d40815fed2187d9 upstream.

These days, we experienced one guest crash with 8 cores and 3 disks,
with qemu error logs as bellow:

qemu-system-x86_64: /build/qemu-2.0.0/kvm-all.c:984:
kvm_irqchip_commit_routes: Assertion `ret == 0' failed.

And then we found one patch(bdf026317d) in qemu tree, which said
could fix this bug.

Execute the following script will reproduce the BUG quickly:

irq_affinity.sh
========================================================================

vda_irq_num=25
vdb_irq_num=27
while [ 1 ]
do
for irq in {1,2,4,8,10,20,40,80}
do
echo $irq > /proc/irq/$vda_irq_num/smp_affinity
echo $irq > /proc/irq/$vdb_irq_num/smp_affinity
dd if=/dev/vda of=/dev/zero bs=4K count=100 iflag=direct
dd if=/dev/vdb of=/dev/zero bs=4K count=100 iflag=direct
done
done
========================================================================

The following qemu log is added in the qemu code and is displayed when
this bug reproduced:

kvm_irqchip_commit_routes: max gsi: 1008, nr_allocated_irq_routes: 1024,
irq_routes->nr: 1024, gsi_count: 1024.

That's to say when irq_routes->nr == 1024, there are 1024 routing entries,
but in the kernel code when routes->nr >= 1024, will just return -EINVAL;

The nr is the number of the routing entries which is in of
[1 ~ KVM_MAX_IRQ_ROUTES], not the index in [0 ~ KVM_MAX_IRQ_ROUTES - 1].

This patch fix the BUG above.

Cc: sta...@vger.kernel.org
Signed-off-by: Xiubo Li <lix...@cmss.chinamobile.com>
Signed-off-by: Wei Tang <tan...@cmss.chinamobile.com>
Signed-off-by: Zhang Zhuoyu <zhang...@cmss.chinamobile.com>
Signed-off-by: Paolo Bonzini <pbon...@redhat.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
virt/kvm/kvm_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 4f865e1..f71c4ad 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2447,7 +2447,7 @@ static long kvm_vm_ioctl(struct file *filp,
if (copy_from_user(&routing, argp, sizeof(routing)))
goto out;
r = -EINVAL;
- if (routing.nr >= KVM_MAX_IRQ_ROUTES)
+ if (routing.nr > KVM_MAX_IRQ_ROUTES)
goto out;
if (routing.flags)
goto out;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:10 AM8/21/16
to
From: Yoshihiro Shimoda <yoshihiro....@renesas.com>

commit 15e4292a2d21e9997fdb2b8c014cc461b3f268f0 upstream.

This patch fixes an issue that the CFIFOSEL register value is possible
to be changed by usbhsg_ep_enable() wrongly. And then, a data transfer
using CFIFO may not work correctly.

For example:
# modprobe g_multi file=usb-storage.bin
# ifconfig usb0 192.168.1.1 up
(During the USB host is sending file to the mass storage)
# ifconfig usb0 down

In this case, since the u_ether.c may call usb_ep_enable() in
eth_stop(), if the renesas_usbhs driver is also using CFIFO for
mass storage, the mass storage may not work correctly.

So, this patch adds usbhs_lock() and usbhs_unlock() calling in
usbhsg_ep_enable() to protect CFIFOSEL register. This is because:
- CFIFOSEL.CURPIPE = 0 is also needed for the pipe configuration
- The CFIFOSEL (fifo->sel) is already protected by usbhs_lock()

Fixes: 97664a207bc2 ("usb: renesas_usbhs: shrink spin lock area")
Cc: <sta...@vger.kernel.org> # v3.1+
Signed-off-by: Yoshihiro Shimoda <yoshihiro....@renesas.com>
Signed-off-by: Felipe Balbi <felipe...@linux.intel.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/usb/renesas_usbhs/mod_gadget.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index ed4949f..64223a9 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -558,6 +558,9 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
struct usbhs_pipe *pipe;
int ret = -EIO;
+ unsigned long flags;
+
+ usbhs_lock(priv, flags);

/*
* if it already have pipe,
@@ -566,7 +569,8 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
if (uep->pipe) {
usbhs_pipe_clear(uep->pipe);
usbhs_pipe_sequence_data0(uep->pipe);
- return 0;
+ ret = 0;
+ goto usbhsg_ep_enable_end;
}

pipe = usbhs_pipe_malloc(priv,
@@ -594,6 +598,9 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
ret = 0;
}

+usbhsg_ep_enable_end:
+ usbhs_unlock(priv, flags);
+
return ret;
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:11 AM8/21/16
to
From: Vegard Nossum <vegard...@oracle.com>

commit 7bc9491645118c9461bd21099c31755ff6783593 upstream.

Although the extent tree depth of 5 should enough be for the worst
case of 2*32 extents of length 1, the extent tree code does not
currently to merge nodes which are less than half-full with a sibling
node, or to shrink the tree depth if possible. So it's possible, at
least in theory, for the tree depth to be greater than 5. However,
even in the worst case, a tree depth of 32 is highly unlikely, and if
the file system is maliciously corrupted, an insanely large eh_depth
can cause memory allocation failures that will trigger kernel warnings
(here, eh_depth = 65280):

JBD2: ext4.exe wants too many credits credits:195849 rsv_credits:0 max:256
------------[ cut here ]------------
WARNING: CPU: 0 PID: 50 at fs/jbd2/transaction.c:293 start_this_handle+0x569/0x580
CPU: 0 PID: 50 Comm: ext4.exe Not tainted 4.7.0-rc5+ #508
Stack:
604a8947 625badd8 0002fd09 00000000
60078643 00000000 62623910 601bf9bc
62623970 6002fc84 626239b0 900000125
Call Trace:
[<6001c2dc>] show_stack+0xdc/0x1a0
[<601bf9bc>] dump_stack+0x2a/0x2e
[<6002fc84>] __warn+0x114/0x140
[<6002fdff>] warn_slowpath_null+0x1f/0x30
[<60165829>] start_this_handle+0x569/0x580
[<60165d4e>] jbd2__journal_start+0x11e/0x220
[<60146690>] __ext4_journal_start_sb+0x60/0xa0
[<60120a81>] ext4_truncate+0x131/0x3a0
[<60123677>] ext4_setattr+0x757/0x840
[<600d5d0f>] notify_change+0x16f/0x2a0
[<600b2b16>] do_truncate+0x76/0xc0
[<600c3e56>] path_openat+0x806/0x1300
[<600c55c9>] do_filp_open+0x89/0xf0
[<600b4074>] do_sys_open+0x134/0x1e0
[<600b4140>] SyS_open+0x20/0x30
[<6001ea68>] handle_syscall+0x88/0x90
[<600295fd>] userspace+0x3fd/0x500
[<6001ac55>] fork_handler+0x85/0x90

---[ end trace 08b0b88b6387a244 ]---

[ Commit message modified and the extent tree depath check changed
from 5 to 32 -- tytso ]

Cc: Darrick J. Wong <darric...@oracle.com>
Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/ext4/extents.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index df633bb..f9fe359 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -454,6 +454,10 @@ static int __ext4_ext_check(const char *function, unsigned int line,
error_msg = "invalid extent entries";
goto corrupted;
}
+ if (unlikely(depth > 32)) {
+ error_msg = "too large eh_depth";
+ goto corrupted;
+ }
/* Verify checksum on non-root extent tree nodes */
if (ext_depth(inode) != depth &&
!ext4_extent_block_csum_verify(inode, eh)) {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:11 AM8/21/16
to
From: Dmitri Epshtein <di...@marvell.com>

commit 06708f81528725148473c0869d6af5f809c6824b upstream.

Commit aebea2ba0f74 ("net: mvneta: fix Tx interrupt delay") intended to
set coalescing threshold to a value guaranteeing interrupt generation
per each sent packet, so that buffers can be released with no delay.

In fact setting threshold to '1' was wrong, because it causes interrupt
every two packets. According to the documentation a reason behind it is
following - interrupt occurs once sent buffers counter reaches a value,
which is higher than one specified in MVNETA_TXQ_SIZE_REG(q). This
behavior was confirmed during tests. Also when testing the SoC working
as a NAS device, better performance was observed with int-per-packet,
as it strongly depends on the fact that all transmitted packets are
released immediately.

This commit enables NETA controller work in interrupt per sent packet mode
by setting coalescing threshold to 0.

Signed-off-by: Dmitri Epshtein <di...@marvell.com>
Signed-off-by: Marcin Wojtas <m...@semihalf.com>
Cc: <sta...@vger.kernel.org> # v3.10+
Fixes aebea2ba0f74 ("net: mvneta: fix Tx interrupt delay")
Acked-by: Willy Tarreau <w...@1wt.eu>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
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 d5643c1..df3af29 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -210,7 +210,7 @@
/* Various constants */

/* Coalescing */
-#define MVNETA_TXDONE_COAL_PKTS 1
+#define MVNETA_TXDONE_COAL_PKTS 0 /* interrupt per packet */
#define MVNETA_RX_COAL_PKTS 32
#define MVNETA_RX_COAL_USEC 100

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:12 AM8/21/16
to
From: Jeff Mahoney <je...@suse.com>

commit 78c4e172412de5d0456dc00d2b34050aa0b683b5 upstream.

This reverts commit 2f36db71009304b3f0b95afacd8eba1f9f046b87.

It fixed a local root exploit but also introduced a dependency on
the lower file system implementing an mmap operation just to open a file,
which is a bit of a heavy hammer. The right fix is to have mmap depend
on the existence of the mmap handler instead.

Signed-off-by: Jeff Mahoney <je...@suse.com>
Signed-off-by: Tyler Hicks <tyh...@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/ecryptfs/kthread.c | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
index 9b661a4..f1ea610 100644
--- a/fs/ecryptfs/kthread.c
+++ b/fs/ecryptfs/kthread.c
@@ -25,7 +25,6 @@
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/mount.h>
-#include <linux/file.h>
#include "ecryptfs_kernel.h"

struct ecryptfs_open_req {
@@ -148,7 +147,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
(*lower_file) = dentry_open(&req.path, flags, cred);
if (!IS_ERR(*lower_file))
- goto have_file;
+ goto out;
if ((flags & O_ACCMODE) == O_RDONLY) {
rc = PTR_ERR((*lower_file));
goto out;
@@ -166,16 +165,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
mutex_unlock(&ecryptfs_kthread_ctl.mux);
wake_up(&ecryptfs_kthread_ctl.wait);
wait_for_completion(&req.done);
- if (IS_ERR(*lower_file)) {
+ if (IS_ERR(*lower_file))
rc = PTR_ERR(*lower_file);
- goto out;
- }
-have_file:
- if ((*lower_file)->f_op->mmap == NULL) {
- fput(*lower_file);
- *lower_file = NULL;
- rc = -EMEDIUMTYPE;
- }
out:
return rc;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:12 AM8/21/16
to
From: Steve French <smfr...@gmail.com>

commit 4fcd1813e6404dd4420c7d12fb483f9320f0bf93 upstream.

Azure server blocks clients that open a socket and don't do anything on it.
In our reconnect scenarios, we can reconnect the tcp session and
detect the socket is available but we defer the negprot and SMB3 session
setup and tree connect reconnection until the next i/o is requested, but
this looks suspicous to some servers who expect SMB3 negprog and session
setup soon after a socket is created.

In the echo thread, reconnect SMB3 sessions and tree connections
that are disconnected. A later patch will replay persistent (and
resilient) handle opens.

Signed-off-by: Steve French <steve....@primarydata.com>
Acked-by: Pavel Shilovsky <pshil...@samba.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/cifs/connect.c | 4 +++-
fs/cifs/smb2pdu.c | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d05a300..7c33afd 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -408,7 +408,9 @@ cifs_echo_request(struct work_struct *work)
* server->ops->need_neg() == true. Also, no need to ping if
* we got a response recently.
*/
- if (!server->ops->need_neg || server->ops->need_neg(server) ||
+
+ if (server->tcpStatus == CifsNeedReconnect ||
+ server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
(server->ops->can_echo && !server->ops->can_echo(server)) ||
time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
goto requeue_echo;
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index eb0de4c..9dd8c96 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1250,6 +1250,33 @@ SMB2_echo(struct TCP_Server_Info *server)

cifs_dbg(FYI, "In echo request\n");

+ if (server->tcpStatus == CifsNeedNegotiate) {
+ struct list_head *tmp, *tmp2;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+
+ cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each(tmp, &server->smb_ses_list) {
+ ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+ list_for_each(tmp2, &ses->tcon_list) {
+ tcon = list_entry(tmp2, struct cifs_tcon,
+ tcon_list);
+ /* add check for persistent handle reconnect */
+ if (tcon && tcon->need_reconnect) {
+ spin_unlock(&cifs_tcp_ses_lock);
+ rc = smb2_reconnect(SMB2_ECHO, tcon);
+ spin_lock(&cifs_tcp_ses_lock);
+ }
+ }
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+ }
+
+ /* if no session, renegotiate failed above */
+ if (server->tcpStatus == CifsNeedNegotiate)
+ return -EIO;
+
rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
if (rc)
return rc;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:14 AM8/21/16
to
From: Richard Weinberger <ric...@nod.at>

commit 1118dce773d84f39ebd51a9fe7261f9169cb056e upstream.

Export these symbols such that UBIFS can implement
->migratepage.

Signed-off-by: Richard Weinberger <ric...@nod.at>
Acked-by: Christoph Hellwig <h...@lst.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
[wt: also add the prototype to include/linux/migrate.h]

Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
include/linux/migrate.h | 3 +++
mm/migrate.c | 2 ++
2 files changed, 5 insertions(+)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index a405d3dc..e986927 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -55,6 +55,9 @@ extern int migrate_vmas(struct mm_struct *mm,
extern void migrate_page_copy(struct page *newpage, struct page *page);
extern int migrate_huge_page_move_mapping(struct address_space *mapping,
struct page *newpage, struct page *page);
+extern int migrate_page_move_mapping(struct address_space *mapping,
+ struct page *newpage, struct page *page,
+ struct buffer_head *head, enum migrate_mode mode);
#else

static inline void putback_lru_pages(struct list_head *l) {}
diff --git a/mm/migrate.c b/mm/migrate.c
index a61500f..2ee28c2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -412,6 +412,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,

return MIGRATEPAGE_SUCCESS;
}
+EXPORT_SYMBOL(migrate_page_move_mapping);

/*
* The expected number of remaining references is the same as that
@@ -503,6 +504,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)
if (PageWriteback(newpage))
end_page_writeback(newpage);
}
+EXPORT_SYMBOL(migrate_page_copy);

/************************************************************
* Migration functions
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:15 AM8/21/16
to
This is the start of the stable review cycle for the 3.10.103 release.
All patches will be posted as a response to this one. If anyone has any
issue with these being applied, please let me know. If anyone thinks some
important patches are missing and should be added prior to the release,
please report them quickly with their respective mainline commit IDs.

Responses should be made by Fri Aug 26 17:04:04 CEST 2016.
Anything received after that time might be too late. If someone
wants a bit more time for a deeper review, please let me know.

The whole patch series can be found in one patch at :
https://kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.10.103-rc1.gz

The shortlog and diffstat are appended below.

Thanks,
Willy

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


Al Viro (1):
fix d_walk()/non-delayed __d_free() race

Alan Stern (2):
USB: fix invalid memory access in hub_activate()
USB: EHCI: declare hostpc register as zero-length array

Alex Deucher (3):
drm/radeon: fix asic initialization for virtualized environments
drm/radeon: add a delay after ATPX dGPU power off
drm/radeon: fix firmware info version checks

Alex Hung (1):
hp-wmi: Fix wifi cannot be hard-unblocked

Alexander Shiyan (1):
stb6100: fix buffer length check in stb6100_write_reg_range()

Alexey Brodkin (1):
arc: unwind: warn only once if DW2_UNWIND is disabled

Amadeusz Sławiński (1):
Bluetooth: Fix l2cap_sock_setsockopt() with optname BT_RCVMTU

Andi Kleen (1):
x86, asmlinkage, apm: Make APM data structure used from assembler
visible

Andrew Goodbody (2):
usb: musb: Stop bulk endpoint while queue is rotated
usb: musb: Ensure rx reinit occurs for shared_fifo endpoints

Andrey Grodzovsky (1):
xen/pciback: Fix conf_space read/write overlap check.

Andrey Ryabinin (1):
perf/x86: Fix undefined shift on 32-bit kernels

Andy Lutomirski (2):
x86/mm: Add barriers and document switch_mm()-vs-flush synchronization
x86/mm: Improve switch_mm() barrier comments

Anthony Romano (1):
tmpfs: don't undo fallocate past its last page

Antonio Alecrim Jr (2):
X.509: remove possible code fragility: enumeration values not handled
isdn: hfcpci_softirq: get func return to suppress compiler warning

Ben Hutchings (1):
module: Invalidate signatures on force-loaded modules

Bernhard Thaler (1):
Revert "netfilter: ensure number of counters is >0 in do_replace()"

Bjørn Mork (1):
cdc_ncm: do not call usbnet_link_change from cdc_ncm_bind

Bjørn Mork (1):
cdc_ncm: workaround for EM7455 "silent" data interface

Bob Copeland (1):
mac80211: mesh: flush mesh paths unconditionally

Borislav Petkov (1):
x86/amd_nb: Fix boot crash on non-AMD systems

Brian King (1):
ipr: Clear interrupt on croc/crocodile when running with LSI

Cameron Gutman (1):
Input: xpad - validate USB endpoint count during probe

Charles (Chas) Williams (1):
tcp: make challenge acks less predictable

Christoph Hellwig (1):
scsi: remove scsi_end_request

Crestez Dan Leonard (1):
iio: Fix error handling in iio_trigger_attach_poll_func

Cyril Bur (1):
powerpc/tm: Always reclaim in start_thread() for exec() class syscalls

Dan Carpenter (1):
KEYS: potential uninitialized variable

Daniele Palmas (1):
USB: serial: option: add support for Telit LE910 PID 0x1206

Dave Chinner (3):
xfs: xfs_iflush_cluster fails to abort on error
xfs: fix inode validity check in xfs_iflush_cluster
xfs: skip stale inodes in xfs_iflush_cluster

Dave Jones (1):
netfilter: ensure number of counters is >0 in do_replace()

Dave Weinstein (1):
arm: oabi compat: add missing access checks

David Howells (1):
KEYS: 64-bit MIPS needs to use compat_sys_keyctl for 32-bit userspace

Dmitri Epshtein (1):
net: mvneta: set real interrupt per packet for tx_done

Dmitry Torokhov (1):
tty/vt/keyboard: fix OOB access in do_compute_shiftstate()

Erez Shitrit (1):
IB/IPoIB: Don't update neigh validity for unresolved entries

Eric Dumazet (1):
udp: properly support MSG_PEEK with truncated buffers

Feng Tang (1):
net: alx: Work around the DMA RX overflow issue

Florian Westphal (19):
netfilter: x_tables: validate e->target_offset early
netfilter: x_tables: make sure e->next_offset covers remaining blob
size
netfilter: x_tables: fix unconditional helper
netfilter: x_tables: don't move to non-existent next rule
netfilter: x_tables: validate targets of jumps
netfilter: x_tables: add and use xt_check_entry_offsets
netfilter: x_tables: kill check_entry helper
netfilter: x_tables: assert minimum target size
netfilter: x_tables: add compat version of xt_check_entry_offsets
netfilter: x_tables: check standard target size too
netfilter: x_tables: check for bogus target offset
netfilter: x_tables: validate all offsets and sizes in a rule
netfilter: x_tables: don't reject valid target size on some
architectures
netfilter: arp_tables: simplify translate_compat_table args
netfilter: ip_tables: simplify translate_compat_table args
netfilter: ip6_tables: simplify translate_compat_table args
netfilter: x_tables: xt_compat_match_from_user doesn't need a retval
netfilter: x_tables: do compat validation via translate_table
netfilter: x_tables: introduce and use xt_copy_counters_from_user

Gavin Shan (1):
powerpc/pseries: Fix PCI config address for DDW

Greg Kroah-Hartman (1):
xfs: fix up backport error in fs/xfs/xfs_inode.c

Guilherme G. Piccoli (1):
powerpc/iommu: Remove the dependency on EEH struct in DDW mechanism

H. Peter Anvin (1):
x86, build: copy ldlinux.c32 to image.iso

Hari Bathini (1):
powerpc/book3s64: Fix branching to OOL handlers in relocatable kernel

Helge Deller (1):
parisc: Fix pagefault crash in unaligned __get_user() call

Herbert Xu (2):
crypto: gcm - Filter out async ghash if necessary
crypto: scatterwalk - Fix test in scatterwalk_done

Hugh Dickins (2):
mm: migrate dirty page without clear_page_dirty_for_io etc
tmpfs: fix regression hang in fallocate undo

Ilya Dryomov (1):
libceph: apply new_state before new_up_client on incrementals

Iosif Harutyunov (1):
ubi: Fix race condition between ubi device creation and udev

Itai Handler (1):
drm/gma500: Fix possible out of bounds read

James Bottomley (1):
scsi_lib: correctly retry failed zero length REQ_TYPE_FS commands

James C Boyd (1):
HID: hid-input: Add parentheses to quell gcc warning

James Hogan (7):
MIPS: KVM: Fix mapped fault broken commpage handling
MIPS: KVM: Add missing gfn range check
MIPS: KVM: Fix gfn range check in kseg0 tlb faults
MIPS: KVM: Propagate kseg0/mapped tlb fault errors
MIPS: Fix siginfo.h to use strict posix types
MIPS: KVM: Fix modular KVM under QEMU
metag: Fix __cmpxchg_u32 asm constraint for CMP

Jan Beulich (1):
xen/acpi: allow xen-acpi-processor driver to load on Xen 4.7

Jan Willeke (1):
s390/seccomp: fix error return for filtered system calls

Jann Horn (1):
ecryptfs: forbid opening files without mmap handler

Jason Gunthorpe (2):
IB/mlx4: Properly initialize GRH TClass and FlowLabel in AHs
IB/security: Restrict use of the write() interface

Javier Martinez Canillas (2):
s5p-mfc: Set device name for reserved memory region devs
s5p-mfc: Add release callback for memory region devs

Jeff Mahoney (2):
Revert "ecryptfs: forbid opening files without mmap handler"
ecryptfs: don't allow mmap when the lower fs doesn't support it

Jiri Slaby (1):
base: make module_create_drivers_dir race-free

Joseph Salisbury (1):
ath5k: Change led pin configuration for compaq c700 laptop

Kangjie Lu (4):
USB: usbfs: fix potential infoleak in devio
ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS
ALSA: timer: Fix leak in events via snd_timer_user_ccallback
ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt

Karl Heiss (1):
sctp: Prevent soft lockup when sctp_accept() is called during a
timeout event

Kirill A. Shutemov (1):
UBIFS: Implement ->migratepage()

Konstantin Neumoin (1):
balloon: check the number of available pages in leak balloon

Laura Abbott (1):
ftrace/recordmcount: Work around for addition of metag magic but not
relocations

Linus Walleij (2):
crypto: ux500 - memmove the right size
iio: accel: kxsd9: fix the usage of spi_w8r8()

Luis Henriques (1):
net: rfkill: Do not ignore errors from regulator_enable()

Luis de Bethencourt (1):
staging: iio: accel: fix error check

Lyude (2):
drm/fb_helper: Fix references to dev->mode_config.num_connector
drm/radeon: Poll for both connect/disconnect on analog connectors

Mark Brown (2):
iio:ad7266: Fix broken regulator error handling
iio:ad7266: Fix probe deferral for vref

Martin Willi (1):
mac80211_hwsim: Add missing check for HWSIM_ATTR_SIGNAL

Masami Hiramatsu (1):
kprobes/x86: Clear TF bit in fault on single-stepping

Matthias Schiffer (1):
MIPS: ath79: make bootconsole wait for both THRE and TEMT

Mike Snitzer (1):
dm flakey: error READ bios during the down_interval

Neil Horman (1):
PCI/ACPI: Fix _OSC ordering to allow PCIe hotplug use when available

Nicolai Stange (2):
ext4: address UBSAN warning in mb_find_order_for_block()
ext4: silence UBSAN in ext4_mb_init()

Oliver Hartkopp (1):
can: fix oops caused by wrong rtnl dellink usage

Palik, Imre (1):
perf/x86: Honor the architectural performance monitoring version

Paolo Bonzini (1):
KVM: x86: fix OOPS after invalid KVM_SET_DEBUGREGS

Paul Burton (1):
MIPS: math-emu: Fix jalr emulation when rd == $0

Paul Moore (1):
netlabel: add address family checks to netlbl_{sock,req}_delattr()

Ping Cheng (1):
Input: wacom_w8001 - w8001_MAX_LENGTH should be 13

Prarit Bhargava (1):
PCI: Disable all BAR sizing for devices with non-compliant BARs

Prasun Maiti (1):
wext: Fix 32 bit iwpriv compatibility issue with 64 bit Kernel

Raghava Aditya Renukunta (2):
aacraid: Relinquish CPU during timeout wait
aacraid: Fix for aac_command_thread hang

Ralf Baechle (1):
MIPS: Fix 64k page support for 32 bit kernels.

Richard Weinberger (2):
mm: Export migrate_page_move_mapping and migrate_page_copy
ubi: Make volume resize power cut aware

Ricky Liang (1):
Input: uinput - handle compat ioctl for UI_SET_PHYS

Russell Currey (1):
powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge

Russell King (1):
ARM: fix PTRACE_SETVFPREGS on SMP systems

Sachin Prabhu (1):
cifs: Check for existing directory when opening file with O_CREAT

Scott Bauer (1):
HID: hiddev: validate num_values for HIDIOCGUSAGES, HIDIOCSUSAGES
commands

Simon Horman (1):
sit: correct IP protocol used in ipip6_err

Soheil Hassas Yeganeh (1):
tcp: consider recv buf for the initial window scale

Steve French (1):
Fix reconnect to not defer smb3 session reconnect long after socket
reconnect

Steven Rostedt (Red Hat) (1):
tracing: Handle NULL formats in hold_module_trace_bprintk_format()

Takashi Iwai (3):
ALSA: dummy: Fix a use-after-free at closing
ALSA: au88x0: Fix calculation in vortex_wtdma_bufshift()
ALSA: ctl: Stop notification after disconnection

Taras Kondratiuk (1):
mmc: block: fix packed command header endianness

Tejun Heo (1):
printk: do cond_resched() between lines while outputting to consoles

Theodore Ts'o (1):
ext4: fix hang when processing corrupted orphaned inode list

Thomas Huth (2):
powerpc: Fix definition of SIAR and SDAR registers
powerpc: Use privileged SPR number for MMCR2

Tim Gardner (1):
be2iscsi: Fix bogus WARN_ON length check

Tom Goff (1):
ipmr/ip6mr: Initialize the last assert time of mfc entries.

Tomer Barletz (1):
ALSA: oxygen: Fix logical-not-parentheses warning

Tomáš Trnka (1):
sunrpc: fix stripping of padded MIC tokens

Torsten Hilbrich (1):
fs/nilfs2: fix potential underflow in call to crc32_le

Trond Myklebust (1):
NFS: Fix another OPEN_DOWNGRADE bug

Ursula Braun (1):
qeth: delete napi struct when removing a qeth device

Vegard Nossum (7):
ext4: verify extent header depth
ext4: check for extents that wrap around
ext4: don't call ext4_should_journal_data() on the journal inode
ext4: short-cut orphan cleanup on error
ext4: fix reference counting bug on block allocation error
block: fix use-after-free in seq file
net/irda: fix NULL pointer dereference on memory allocation failure

Vignesh R (1):
gpio: pca953x: Fix NBANK calculation for PCA9536

Ville Syrjälä (1):
dma-debug: avoid spinlock recursion when disabling dma-debug

Vineet Gupta (1):
ARC: use ASL assembler mnemonic

Vladimir Davydov (1):
signal: remove warning about using SI_TKILL in rt_[tg]sigqueueinfo

Wei Fang (2):
scsi: fix race between simultaneous decrements of ->host_failed
fuse: fix wrong assignment of ->flags in fuse_send_init()

Willy Tarreau (3):
USB: fix up faulty backports
pipe: limit the per-user amount of pages allocated in pipes
squash mm: Export migrate_page_... : also make it non-static

Wolfgang Grandegger (1):
can: at91_can: RX queue could get stuck at high bus load

Xiubo Li (1):
kvm: Fix irq route entries exceeding KVM_MAX_IRQ_ROUTES

Yishai Hadas (1):
IB/mlx4: Fix the SQ size of an RC QP

Yoshihiro Shimoda (1):
usb: renesas_usbhs: protect the CFIFOSEL setting in usbhsg_ep_enable()

Yuchung Cheng (1):
tcp: record TLP and ER timer stats in v6 stats

dan.ca...@oracle.com (1):
spi: spi-xilinx: cleanup a check in xilinx_spi_txrx_bufs()

wang yanqing (1):
rtlwifi: Fix logic error in enter/exit power-save mode

Documentation/scsi/scsi_eh.txt | 8 +-
Documentation/sysctl/fs.txt | 23 ++
arch/arc/kernel/stacktrace.c | 2 +-
arch/arc/mm/tlbex.S | 4 +-
arch/arm/kernel/ptrace.c | 2 +-
arch/arm/kernel/sys_oabi-compat.c | 8 +-
arch/metag/include/asm/cmpxchg_lnkget.h | 2 +-
arch/mips/ath79/early_printk.c | 6 +-
arch/mips/include/asm/kvm_host.h | 1 +
arch/mips/include/asm/processor.h | 2 +-
arch/mips/include/uapi/asm/siginfo.h | 18 +-
arch/mips/kernel/scall64-n32.S | 2 +-
arch/mips/kernel/scall64-o32.S | 2 +-
arch/mips/kvm/kvm_locore.S | 1 +
arch/mips/kvm/kvm_mips.c | 11 +-
arch/mips/kvm/kvm_mips_emul.c | 33 ++-
arch/mips/kvm/kvm_mips_int.h | 2 +
arch/mips/kvm/kvm_tlb.c | 61 +++--
arch/mips/math-emu/cp1emu.c | 8 +-
arch/parisc/kernel/unaligned.c | 10 +-
arch/powerpc/include/asm/reg.h | 6 +-
arch/powerpc/kernel/exceptions-64s.S | 16 +-
arch/powerpc/kernel/process.c | 10 +
arch/powerpc/platforms/pseries/eeh_pseries.c | 51 ++--
arch/powerpc/platforms/pseries/iommu.c | 24 +-
arch/s390/include/asm/syscall.h | 2 +-
arch/x86/boot/Makefile | 3 +
arch/x86/include/asm/mmu_context.h | 33 ++-
arch/x86/kernel/amd_nb.c | 4 +-
arch/x86/kernel/apm_32.c | 2 +-
arch/x86/kernel/cpu/perf_event_intel.c | 11 +-
arch/x86/kernel/kprobes/core.c | 12 +
arch/x86/kvm/x86.c | 5 +
arch/x86/mm/tlb.c | 24 +-
block/genhd.c | 1 +
crypto/gcm.c | 4 +-
crypto/scatterwalk.c | 3 +-
drivers/acpi/pci_root.c | 67 ++---
drivers/ata/libata-eh.c | 2 +-
drivers/base/module.c | 8 +-
drivers/crypto/ux500/hash/hash_core.c | 4 +-
drivers/gpio/gpio-pca953x.c | 2 +-
drivers/gpu/drm/drm_fb_helper.c | 5 +-
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c | 2 +-
drivers/gpu/drm/radeon/radeon_atombios.c | 4 +-
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 5 +
drivers/gpu/drm/radeon/radeon_connectors.c | 15 +-
drivers/gpu/drm/radeon/radeon_device.c | 21 ++
drivers/hid/hid-input.c | 2 +-
drivers/hid/usbhid/hiddev.c | 10 +-
drivers/iio/accel/kxsd9.c | 4 +-
drivers/iio/adc/ad7266.c | 6 +-
drivers/iio/industrialio-trigger.c | 23 +-
drivers/infiniband/core/ucm.c | 4 +
drivers/infiniband/core/ucma.c | 4 +
drivers/infiniband/core/uverbs_main.c | 5 +
drivers/infiniband/hw/mlx4/ah.c | 2 +-
drivers/infiniband/hw/mlx4/qp.c | 2 +-
drivers/infiniband/hw/qib/qib_file_ops.c | 5 +
drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 +-
drivers/input/joystick/xpad.c | 3 +
drivers/input/misc/uinput.c | 6 +
drivers/input/touchscreen/wacom_w8001.c | 2 +-
drivers/isdn/hardware/mISDN/hfcpci.c | 4 +-
drivers/md/dm-flakey.c | 23 +-
drivers/media/dvb-frontends/stb6100.c | 2 +-
drivers/media/platform/s5p-mfc/s5p_mfc.c | 11 +
drivers/mmc/card/block.c | 12 +-
drivers/mtd/ubi/build.c | 5 +-
drivers/mtd/ubi/vmt.c | 25 +-
drivers/net/can/at91_can.c | 5 +-
drivers/net/can/dev.c | 6 +
drivers/net/ethernet/atheros/alx/main.c | 7 +-
drivers/net/ethernet/marvell/mvneta.c | 2 +-
drivers/net/usb/cdc_ncm.c | 27 +-
drivers/net/wireless/ath/ath5k/led.c | 2 +-
drivers/net/wireless/mac80211_hwsim.c | 1 +
drivers/net/wireless/rtlwifi/base.c | 4 +-
drivers/pci/probe.c | 6 +-
drivers/platform/x86/hp-wmi.c | 5 +
drivers/s390/net/qeth_l2_main.c | 1 +
drivers/s390/net/qeth_l3_main.c | 1 +
drivers/scsi/aacraid/commsup.c | 12 +-
drivers/scsi/be2iscsi/be_main.c | 2 +-
drivers/scsi/ipr.c | 1 +
drivers/scsi/scsi_error.c | 4 +-
drivers/scsi/scsi_lib.c | 116 +++------
drivers/spi/spi-xilinx.c | 2 +-
drivers/staging/iio/accel/sca3000_core.c | 2 +-
drivers/tty/vt/keyboard.c | 30 +--
drivers/usb/core/devio.c | 9 +-
drivers/usb/core/hub.c | 23 +-
drivers/usb/core/quirks.c | 16 +-
drivers/usb/musb/musb_host.c | 21 +-
drivers/usb/renesas_usbhs/mod_gadget.c | 9 +-
drivers/usb/serial/option.c | 3 +
drivers/virtio/virtio_balloon.c | 2 +
drivers/xen/xen-acpi-processor.c | 35 +--
drivers/xen/xen-pciback/conf_space.c | 6 +-
fs/cifs/connect.c | 4 +-
fs/cifs/dir.c | 24 +-
fs/cifs/smb2pdu.c | 27 ++
fs/dcache.c | 4 +-
fs/ecryptfs/file.c | 15 +-
fs/ext4/extents.c | 12 +-
fs/ext4/ialloc.c | 10 +-
fs/ext4/inode.c | 6 +-
fs/ext4/mballoc.c | 27 +-
fs/ext4/super.c | 10 +
fs/fuse/inode.c | 2 +-
fs/nfs/nfs4proc.c | 5 +-
fs/nilfs2/the_nilfs.c | 2 +-
fs/pipe.c | 47 +++-
fs/ubifs/file.c | 24 ++
fs/xfs/xfs_inode.c | 26 +-
include/linux/console.h | 1 +
include/linux/migrate.h | 3 +
include/linux/netfilter/x_tables.h | 12 +-
include/linux/pipe_fs_i.h | 4 +
include/linux/sched.h | 1 +
include/linux/usb/ehci_def.h | 4 +-
include/rdma/ib.h | 54 ++++
kernel/module.c | 13 +-
kernel/panic.c | 3 +
kernel/printk.c | 35 ++-
kernel/signal.c | 14 +-
kernel/sysctl.c | 14 +
kernel/trace/trace_printk.c | 7 +-
lib/dma-debug.c | 2 +-
mm/migrate.c | 55 ++--
mm/shmem.c | 8 +-
net/bluetooth/l2cap_sock.c | 2 +-
net/ceph/osdmap.c | 152 +++++++----
net/ipv4/ipmr.c | 4 +-
net/ipv4/netfilter/arp_tables.c | 327 ++++++++---------------
net/ipv4/netfilter/ip_tables.c | 360 ++++++++------------------
net/ipv4/tcp_input.c | 14 +-
net/ipv4/tcp_output.c | 3 +-
net/ipv4/udp.c | 6 +-
net/ipv6/ip6mr.c | 1 +
net/ipv6/netfilter/ip6_tables.c | 354 ++++++++-----------------
net/ipv6/sit.c | 4 +-
net/ipv6/tcp_ipv6.c | 4 +-
net/ipv6/udp.c | 6 +-
net/irda/af_irda.c | 7 +-
net/mac80211/mesh.c | 4 +
net/netfilter/x_tables.c | 245 +++++++++++++++++-
net/netlabel/netlabel_kapi.c | 12 +-
net/rfkill/rfkill-regulator.c | 8 +-
net/sctp/sm_sideeffect.c | 42 +--
net/sunrpc/auth_gss/svcauth_gss.c | 4 +-
net/wireless/wext-core.c | 25 +-
scripts/asn1_compiler.c | 2 +
scripts/recordmcount.c | 9 +-
security/keys/key.c | 2 +-
sound/core/control.c | 2 +
sound/core/timer.c | 3 +
sound/drivers/dummy.c | 1 +
sound/pci/au88x0/au88x0_core.c | 5 +-
sound/pci/oxygen/oxygen_mixer.c | 2 +-
virt/kvm/kvm_main.c | 2 +-
161 files changed, 1869 insertions(+), 1294 deletions(-)
create mode 100644 include/rdma/ib.h

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:18 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 7d35812c3214afa5b37a675113555259cfd67b98 upstream.

Currently arp/ip and ip6tables each implement a short helper to check that
the target offset is large enough to hold one xt_entry_target struct and
that t->u.target_size fits within the current rule.

Unfortunately these checks are not sufficient.

To avoid adding new tests to all of ip/ip6/arptables move the current
checks into a helper, then extend this helper in followup patches.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
include/linux/netfilter/x_tables.h | 4 ++++
net/ipv4/netfilter/arp_tables.c | 11 +----------
net/ipv4/netfilter/ip_tables.c | 12 +-----------
net/ipv6/netfilter/ip6_tables.c | 12 +-----------
net/netfilter/x_tables.c | 34 ++++++++++++++++++++++++++++++++++
5 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index dd49566..6da5c82 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -239,6 +239,10 @@ extern void xt_unregister_match(struct xt_match *target);
extern int xt_register_matches(struct xt_match *match, unsigned int n);
extern void xt_unregister_matches(struct xt_match *match, unsigned int n);

+int xt_check_entry_offsets(const void *base,
+ unsigned int target_offset,
+ unsigned int next_offset);
+
extern int xt_check_match(struct xt_mtchk_param *,
unsigned int size, u_int8_t proto, bool inv_proto);
extern int xt_check_target(struct xt_tgchk_param *,
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b2adc4b..839a698 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -487,19 +487,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,

static inline int check_entry(const struct arpt_entry *e)
{
- const struct xt_entry_target *t;
-
if (!arp_checkentry(&e->arp))
return -EINVAL;

- if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
- return -EINVAL;
-
- t = arpt_get_target_c(e);
- if (e->target_offset + t->u.target_size > e->next_offset)
- return -EINVAL;
-
- return 0;
+ return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
}

static inline int check_target(struct arpt_entry *e, const char *name)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index eea26fc..ffd46717 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -581,20 +581,10 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
static int
check_entry(const struct ipt_entry *e)
{
- const struct xt_entry_target *t;
-
if (!ip_checkentry(&e->ip))
return -EINVAL;

- if (e->target_offset + sizeof(struct xt_entry_target) >
- e->next_offset)
- return -EINVAL;
-
- t = ipt_get_target_c(e);
- if (e->target_offset + t->u.target_size > e->next_offset)
- return -EINVAL;
-
- return 0;
+ return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
}

static int
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 5eeec96..5692017 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -591,20 +591,10 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
static int
check_entry(const struct ip6t_entry *e)
{
- const struct xt_entry_target *t;
-
if (!ip6_checkentry(&e->ipv6))
return -EINVAL;

- if (e->target_offset + sizeof(struct xt_entry_target) >
- e->next_offset)
- return -EINVAL;
-
- t = ip6t_get_target_c(e);
- if (e->target_offset + t->u.target_size > e->next_offset)
- return -EINVAL;
-
- return 0;
+ return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
}

static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8b03028..55b1e0c 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -560,6 +560,40 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
#endif /* CONFIG_COMPAT */

+/**
+ * xt_check_entry_offsets - validate arp/ip/ip6t_entry
+ *
+ * @base: pointer to arp/ip/ip6t_entry
+ * @target_offset: the arp/ip/ip6_t->target_offset
+ * @next_offset: the arp/ip/ip6_t->next_offset
+ *
+ * validates that target_offset and next_offset are sane.
+ *
+ * The arp/ip/ip6t_entry structure @base must have passed following tests:
+ * - it must point to a valid memory location
+ * - base to base + next_offset must be accessible, i.e. not exceed allocated
+ * length.
+ *
+ * Return: 0 on success, negative errno on failure.
+ */
+int xt_check_entry_offsets(const void *base,
+ unsigned int target_offset,
+ unsigned int next_offset)
+{
+ const struct xt_entry_target *t;
+ const char *e = base;
+
+ if (target_offset + sizeof(*t) > next_offset)
+ return -EINVAL;
+
+ t = (void *)(e + target_offset);
+ if (target_offset + t->u.target_size > next_offset)
+ return -EINVAL;
+
+ return 0;
+}
+EXPORT_SYMBOL(xt_check_entry_offsets);
+
int xt_check_target(struct xt_tgchk_param *par,
unsigned int size, u_int8_t proto, bool inv_proto)
{
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:21 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 8dddd32756f6fe8e4e82a63361119b7e2384e02f upstream.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/netfilter/arp_tables.c | 82 ++++++++++++++++++-----------------------
1 file changed, 36 insertions(+), 46 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index bb329cb..2ad0bc6 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1199,6 +1199,18 @@ static int do_add_counters(struct net *net, const void __user *user,
}

#ifdef CONFIG_COMPAT
+struct compat_arpt_replace {
+ char name[XT_TABLE_MAXNAMELEN];
+ u32 valid_hooks;
+ u32 num_entries;
+ u32 size;
+ u32 hook_entry[NF_ARP_NUMHOOKS];
+ u32 underflow[NF_ARP_NUMHOOKS];
+ u32 num_counters;
+ compat_uptr_t counters;
+ struct compat_arpt_entry entries[0];
+};
+
static inline void compat_release_entry(struct compat_arpt_entry *e)
{
struct xt_entry_target *t;
@@ -1214,8 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
const unsigned char *base,
const unsigned char *limit,
const unsigned int *hook_entries,
- const unsigned int *underflows,
- const char *name)
+ const unsigned int *underflows)
{
struct xt_entry_target *t;
struct xt_target *target;
@@ -1286,7 +1297,7 @@ out:

static int
compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
- unsigned int *size, const char *name,
+ unsigned int *size,
struct xt_table_info *newinfo, unsigned char *base)
{
struct xt_entry_target *t;
@@ -1319,14 +1330,9 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
return ret;
}

-static int translate_compat_table(const char *name,
- unsigned int valid_hooks,
- struct xt_table_info **pinfo,
+static int translate_compat_table(struct xt_table_info **pinfo,
void **pentry0,
- unsigned int total_size,
- unsigned int number,
- unsigned int *hook_entries,
- unsigned int *underflows)
+ const struct compat_arpt_replace *compatr)
{
unsigned int i, j;
struct xt_table_info *newinfo, *info;
@@ -1338,8 +1344,8 @@ static int translate_compat_table(const char *name,

info = *pinfo;
entry0 = *pentry0;
- size = total_size;
- info->number = number;
+ size = compatr->size;
+ info->number = compatr->num_entries;

/* Init all hooks to impossible value. */
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
@@ -1350,40 +1356,39 @@ static int translate_compat_table(const char *name,
duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(NFPROTO_ARP);
- xt_compat_init_offsets(NFPROTO_ARP, number);
+ xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
/* Walk through entries, checking offsets. */
- xt_entry_foreach(iter0, entry0, total_size) {
+ xt_entry_foreach(iter0, entry0, compatr->size) {
ret = check_compat_entry_size_and_hooks(iter0, info, &size,
entry0,
- entry0 + total_size,
- hook_entries,
- underflows,
- name);
+ entry0 + compatr->size,
+ compatr->hook_entry,
+ compatr->underflow);
if (ret != 0)
goto out_unlock;
++j;
}

ret = -EINVAL;
- if (j != number) {
+ if (j != compatr->num_entries) {
duprintf("translate_compat_table: %u not %u entries\n",
- j, number);
+ j, compatr->num_entries);
goto out_unlock;
}

/* Check hooks all assigned */
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
/* Only hooks which are valid */
- if (!(valid_hooks & (1 << i)))
+ if (!(compatr->valid_hooks & (1 << i)))
continue;
if (info->hook_entry[i] == 0xFFFFFFFF) {
duprintf("Invalid hook entry %u %u\n",
- i, hook_entries[i]);
+ i, info->hook_entry[i]);
goto out_unlock;
}
if (info->underflow[i] == 0xFFFFFFFF) {
duprintf("Invalid underflow %u %u\n",
- i, underflows[i]);
+ i, info->underflow[i]);
goto out_unlock;
}
}
@@ -1393,17 +1398,17 @@ static int translate_compat_table(const char *name,
if (!newinfo)
goto out_unlock;

- newinfo->number = number;
+ newinfo->number = compatr->num_entries;
for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
newinfo->hook_entry[i] = info->hook_entry[i];
newinfo->underflow[i] = info->underflow[i];
}
entry1 = newinfo->entries[raw_smp_processor_id()];
pos = entry1;
- size = total_size;
- xt_entry_foreach(iter0, entry0, total_size) {
+ size = compatr->size;
+ xt_entry_foreach(iter0, entry0, compatr->size) {
ret = compat_copy_entry_from_user(iter0, &pos, &size,
- name, newinfo, entry1);
+ newinfo, entry1);
if (ret != 0)
break;
}
@@ -1413,12 +1418,12 @@ static int translate_compat_table(const char *name,
goto free_newinfo;

ret = -ELOOP;
- if (!mark_source_chains(newinfo, valid_hooks, entry1))
+ if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
goto free_newinfo;

i = 0;
xt_entry_foreach(iter1, entry1, newinfo->size) {
- ret = check_target(iter1, name);
+ ret = check_target(iter1, compatr->name);
if (ret != 0)
break;
++i;
@@ -1463,7 +1468,7 @@ static int translate_compat_table(const char *name,
free_newinfo:
xt_free_table_info(newinfo);
out:
- xt_entry_foreach(iter0, entry0, total_size) {
+ xt_entry_foreach(iter0, entry0, compatr->size) {
if (j-- == 0)
break;
compat_release_entry(iter0);
@@ -1475,18 +1480,6 @@ out_unlock:
goto out;
}

-struct compat_arpt_replace {
- char name[XT_TABLE_MAXNAMELEN];
- u32 valid_hooks;
- u32 num_entries;
- u32 size;
- u32 hook_entry[NF_ARP_NUMHOOKS];
- u32 underflow[NF_ARP_NUMHOOKS];
- u32 num_counters;
- compat_uptr_t counters;
- struct compat_arpt_entry entries[0];
-};
-
static int compat_do_replace(struct net *net, void __user *user,
unsigned int len)
{
@@ -1517,10 +1510,7 @@ static int compat_do_replace(struct net *net, void __user *user,
goto free_newinfo;
}

- ret = translate_compat_table(tmp.name, tmp.valid_hooks,
- &newinfo, &loc_cpu_entry, tmp.size,
- tmp.num_entries, tmp.hook_entry,
- tmp.underflow);
+ ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
if (ret != 0)
goto free_newinfo;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:24 AM8/21/16
to
From: Wolfgang Grandegger <w...@grandegger.com>

commit 43200a4480cbbe660309621817f54cbb93907108 upstream.

At high bus load it could happen that "at91_poll()" enters with all RX
message boxes filled up. If then at the end the "quota" is exceeded as
well, "rx_next" will not be reset to the first RX mailbox and hence the
interrupts remain disabled.

Signed-off-by: Wolfgang Grandegger <w...@grandegger.com>
Tested-by: Amr Bekhit <amrb...@gmail.com>
Cc: <sta...@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <m...@pengutronix.de>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/net/can/at91_can.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 535d5dd..024078c 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -731,9 +731,10 @@ static int at91_poll_rx(struct net_device *dev, int quota)

/* upper group completed, look again in lower */
if (priv->rx_next > get_mb_rx_low_last(priv) &&
- quota > 0 && mb > get_mb_rx_last(priv)) {
+ mb > get_mb_rx_last(priv)) {
priv->rx_next = get_mb_rx_first(priv);
- goto again;
+ if (quota > 0)
+ goto again;
}

return received;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:40:43 AM8/21/16
to
From: Kangjie Lu <kang...@gmail.com>

commit cec8f96e49d9be372fdb0c3836dcf31ec71e457e upstream.

The stack object “tread” has a total size of 32 bytes. Its field
“event” and “val” both contain 4 bytes padding. These 8 bytes
padding bytes are sent to user without being initialized.

Signed-off-by: Kangjie Lu <kj...@gatech.edu>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
sound/core/timer.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/sound/core/timer.c b/sound/core/timer.c
index 38742e8..54ff806 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -1707,6 +1707,7 @@ static int snd_timer_user_params(struct file *file,
if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
if (tu->tread) {
struct snd_timer_tread tread;
+ memset(&tread, 0, sizeof(tread));
tread.event = SNDRV_TIMER_EVENT_EARLY;
tread.tstamp.tv_sec = 0;
tread.tstamp.tv_nsec = 0;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:41:26 AM8/21/16
to
From: Antonio Alecrim Jr <antonio...@gmail.com>

commit d6d6d1bc44362112e10a48d434e5b3c716152003 upstream.

Signed-off-by: Antonio Alecrim Jr <antonio...@gmail.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/isdn/hardware/mISDN/hfcpci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index a7e4939..eab9167 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -2295,8 +2295,8 @@ _hfcpci_softirq(struct device *dev, void *arg)
static void
hfcpci_softirq(void *arg)
{
- (void) driver_for_each_device(&hfc_driver.driver, NULL, arg,
- _hfcpci_softirq);
+ WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, arg,
+ _hfcpci_softirq) != 0);

/* if next event would be in the past ... */
if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:41:26 AM8/21/16
to
From: James Hogan <james...@imgtec.com>

commit 9b731bcfdec4c159ad2e4312e25d69221709b96a upstream.

Propagate errors from kvm_mips_handle_kseg0_tlb_fault() and
kvm_mips_handle_mapped_seg_tlb_fault(), usually triggering an internal
error since they normally indicate the guest accessed bad physical
memory or the commpage in an unexpected way.

Fixes: 858dd5d45733 ("KVM/MIPS32: MMU/TLB operations for the Guest.")
Fixes: e685c689f3a8 ("KVM/MIPS32: Privileged instruction/target branch emulation.")
Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Paolo Bonzini <pbon...@redhat.com>
Cc: "Radim Krčmář" <rkr...@redhat.com>
Cc: Ralf Baechle <ra...@linux-mips.org>
Cc: linux...@linux-mips.org
Cc: k...@vger.kernel.org
Signed-off-by: Radim Krčmář <rkr...@redhat.com>
[james...@imgtec.com: Backport to v3.10.y - v3.15.y]
Signed-off-by: James Hogan <james...@imgtec.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/kvm/kvm_mips_emul.c | 33 ++++++++++++++++++++++++---------
arch/mips/kvm/kvm_tlb.c | 14 ++++++++++----
2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c
index 3308581..9f76438 100644
--- a/arch/mips/kvm/kvm_mips_emul.c
+++ b/arch/mips/kvm/kvm_mips_emul.c
@@ -972,8 +972,13 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause,
preempt_disable();
if (KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG0) {

- if (kvm_mips_host_tlb_lookup(vcpu, va) < 0) {
- kvm_mips_handle_kseg0_tlb_fault(va, vcpu);
+ if (kvm_mips_host_tlb_lookup(vcpu, va) < 0 &&
+ kvm_mips_handle_kseg0_tlb_fault(va, vcpu)) {
+ kvm_err("%s: handling mapped kseg0 tlb fault for %lx, vcpu: %p, ASID: %#lx\n",
+ __func__, va, vcpu, read_c0_entryhi());
+ er = EMULATE_FAIL;
+ preempt_enable();
+ goto done;
}
} else if ((KVM_GUEST_KSEGX(va) < KVM_GUEST_KSEG0) ||
KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG23) {
@@ -1006,11 +1011,16 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause,
run, vcpu);
preempt_enable();
goto dont_update_pc;
- } else {
- /* We fault an entry from the guest tlb to the shadow host TLB */
- kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
- NULL,
- NULL);
+ }
+ /* We fault an entry from the guest tlb to the shadow host TLB */
+ if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
+ NULL, NULL)) {
+ kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
+ __func__, va, index, vcpu,
+ read_c0_entryhi());
+ er = EMULATE_FAIL;
+ preempt_enable();
+ goto done;
}
}
} else {
@@ -1821,8 +1831,13 @@ kvm_mips_handle_tlbmiss(unsigned long cause, uint32_t *opc,
tlb->tlb_hi, tlb->tlb_lo0, tlb->tlb_lo1);
#endif
/* OK we have a Guest TLB entry, now inject it into the shadow host TLB */
- kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb, NULL,
- NULL);
+ if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb,
+ NULL, NULL)) {
+ kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
+ __func__, va, index, vcpu,
+ read_c0_entryhi());
+ er = EMULATE_FAIL;
+ }
}
}

diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c
index 5a3c373..4bee439 100644
--- a/arch/mips/kvm/kvm_tlb.c
+++ b/arch/mips/kvm/kvm_tlb.c
@@ -926,10 +926,16 @@ uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu)
local_irq_restore(flags);
return KVM_INVALID_INST;
}
- kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
- &vcpu->arch.
- guest_tlb[index],
- NULL, NULL);
+ if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
+ &vcpu->arch.guest_tlb[index],
+ NULL, NULL)) {
+ kvm_err("%s: handling mapped seg tlb fault failed for %p, index: %u, vcpu: %p, ASID: %#lx\n",
+ __func__, opc, index, vcpu,
+ read_c0_entryhi());
+ kvm_mips_dump_guest_tlbs(vcpu);
+ local_irq_restore(flags);
+ return KVM_INVALID_INST;
+ }
inst = *(opc);
}
local_irq_restore(flags);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:41:36 AM8/21/16
to
From: Wei Fang <fang...@huawei.com>

commit 72d8c36ec364c82bf1bf0c64dfa1041cfaf139f7 upstream.

sas_ata_strategy_handler() adds the works of the ata error handler to
system_unbound_wq. This workqueue asynchronously runs work items, so the
ata error handler will be performed concurrently on different CPUs. In
this case, ->host_failed will be decreased simultaneously in
scsi_eh_finish_cmd() on different CPUs, and become abnormal.

It will lead to permanently inequality between ->host_failed and
->host_busy, and scsi error handler thread won't start running. IO
errors after that won't be handled.

Since all scmds must have been handled in the strategy handler, just
remove the decrement in scsi_eh_finish_cmd() and zero ->host_busy after
the strategy handler to fix this race.

Fixes: 50824d6c5657 ("[SCSI] libsas: async ata-eh")
Cc: sta...@vger.kernel.org
Signed-off-by: Wei Fang <fang...@huawei.com>
Reviewed-by: James Bottomley <je...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
Documentation/scsi/scsi_eh.txt | 8 ++++++--
drivers/ata/libata-eh.c | 2 +-
drivers/scsi/scsi_error.c | 4 +++-
3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
index 6ff16b6..c08b62d 100644
--- a/Documentation/scsi/scsi_eh.txt
+++ b/Documentation/scsi/scsi_eh.txt
@@ -255,19 +255,23 @@ scmd->allowed.

3. scmd recovered
ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
- - shost->host_failed--
- clear scmd->eh_eflags
- scsi_setup_cmd_retry()
- move from local eh_work_q to local eh_done_q
LOCKING: none
+ CONCURRENCY: at most one thread per separate eh_work_q to
+ keep queue manipulation lockless

4. EH completes
ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper
- layer of failure.
+ layer of failure. May be called concurrently but must have
+ a no more than one thread per separate eh_work_q to
+ manipulate the queue locklessly
- scmd is removed from eh_done_q and scmd->eh_entry is cleared
- if retry is necessary, scmd is requeued using
scsi_queue_insert()
- otherwise, scsi_finish_command() is invoked for scmd
+ - zero shost->host_failed
LOCKING: queue or finish function performs appropriate locking


diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 063036d..126eb86 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -604,7 +604,7 @@ void ata_scsi_error(struct Scsi_Host *host)
ata_scsi_port_error_handler(host, ap);

/* finish or retry handled scmd's and clean up */
- WARN_ON(host->host_failed || !list_empty(&eh_work_q));
+ WARN_ON(!list_empty(&eh_work_q));

DPRINTK("EXIT\n");
}
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 9acbc88..5ba69ea 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -898,7 +898,6 @@ static int scsi_request_sense(struct scsi_cmnd *scmd)
*/
void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
{
- scmd->device->host->host_failed--;
scmd->eh_eflags = 0;
list_move_tail(&scmd->eh_entry, done_q);
}
@@ -1892,6 +1891,9 @@ int scsi_error_handler(void *data)
else
scsi_unjam_host(shost);

+ /* All scmds have been handled */
+ shost->host_failed = 0;
+
/*
* Note - if the above fails completely, the action is to take
* individual devices offline and flush the queue of any
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:45:49 AM8/21/16
to
From: David Howells <dhow...@redhat.com>

commit 20f06ed9f61a185c6dabd662c310bed6189470df upstream.

MIPS64 needs to use compat_sys_keyctl for 32-bit userspace rather than
calling sys_keyctl. The latter will work in a lot of cases, thereby hiding
the issue.

Reported-by: Stephan Mueller <smue...@chronox.de>
Signed-off-by: David Howells <dhow...@redhat.com>
cc: sta...@vger.kernel.org
Cc: linux...@linux-mips.org
Cc: linux-...@vger.kernel.org
Cc: linux-secu...@vger.kernel.org
Cc: keyr...@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/13832/
Signed-off-by: Ralf Baechle <ra...@linux-mips.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/kernel/scall64-n32.S | 2 +-
arch/mips/kernel/scall64-o32.S | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index cab1507..b657fbe 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -349,7 +349,7 @@ EXPORT(sysn32_call_table)
PTR sys_ni_syscall /* available, was setaltroot */
PTR sys_add_key
PTR sys_request_key
- PTR sys_keyctl /* 6245 */
+ PTR compat_sys_keyctl /* 6245 */
PTR sys_set_thread_area
PTR sys_inotify_init
PTR sys_inotify_add_watch
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 37605dc..bf56d7e 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -474,7 +474,7 @@ sys_call_table:
PTR sys_ni_syscall /* available, was setaltroot */
PTR sys_add_key /* 4280 */
PTR sys_request_key
- PTR sys_keyctl
+ PTR compat_sys_keyctl
PTR sys_set_thread_area
PTR sys_inotify_init
PTR sys_inotify_add_watch /* 4285 */
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:46:19 AM8/21/16
to
From: Takashi Iwai <ti...@suse.de>

commit f388cdcdd160687c6650833f286b9c89c50960ff upstream.

snd_ctl_remove() has a notification for the removal event. It's
superfluous when done during the device got disconnected. Although
the notification itself is mostly harmless, it may potentially be
harmful, and should be suppressed. Actually some components PCM may
free ctl elements during the disconnect or free callbacks, thus it's
no theoretical issue.

This patch adds the check of card->shutdown flag for avoiding
unnecessary notifications after (or during) the disconnect.

Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
sound/core/control.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/sound/core/control.c b/sound/core/control.c
index 3fcead6..251bc57 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -150,6 +150,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,

if (snd_BUG_ON(!card || !id))
return;
+ if (card->shutdown)
+ return;
read_lock(&card->ctl_files_rwlock);
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
card->mixer_oss_change_count++;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:46:24 AM8/21/16
to
From: Theodore Ts'o <ty...@mit.edu>

commit c9eb13a9105e2e418f72e46a2b6da3f49e696902 upstream.

If the orphaned inode list contains inode #5, ext4_iget() returns a
bad inode (since the bootloader inode should never be referenced
directly). Because of the bad inode, we end up processing the inode
repeatedly and this hangs the machine.

This can be reproduced via:

mke2fs -t ext4 /tmp/foo.img 100
debugfs -w -R "ssv last_orphan 5" /tmp/foo.img
mount -o loop /tmp/foo.img /mnt

(But don't do this if you are using an unpatched kernel if you care
about the system staying functional. :-)

This bug was found by the port of American Fuzzy Lop into the kernel
to find file system problems[1]. (Since it *only* happens if inode #5
shows up on the orphan list --- 3, 7, 8, etc. won't do it, it's not
surprising that AFL needed two hours before it found it.)

[1] http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf

Cc: sta...@vger.kernel.org
Reported by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/ext4/ialloc.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 4d4718c..00cbc64 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -1027,11 +1027,13 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
goto iget_failed;

/*
- * If the orphans has i_nlinks > 0 then it should be able to be
- * truncated, otherwise it won't be removed from the orphan list
- * during processing and an infinite loop will result.
+ * If the orphans has i_nlinks > 0 then it should be able to
+ * be truncated, otherwise it won't be removed from the orphan
+ * list during processing and an infinite loop will result.
+ * Similarly, it must not be a bad inode.
*/
- if (inode->i_nlink && !ext4_can_truncate(inode))
+ if ((inode->i_nlink && !ext4_can_truncate(inode)) ||
+ is_bad_inode(inode))
goto bad_orphan;

if (NEXT_ORPHAN(inode) > max_ino)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:47:33 AM8/21/16
to
From: Vegard Nossum <vegard...@oracle.com>

commit 6a7fd522a7c94cdef0a3b08acf8e6702056e635c upstream.

If ext4_fill_super() fails early, it's possible for ext4_evict_inode()
to call ext4_should_journal_data() before superblock options and flags
are fully set up. In that case, the iput() on the journal inode can
end up causing a BUG().

Work around this problem by reordering the tests so we only call
ext4_should_journal_data() after we know it's not the journal inode.

Fixes: 2d859db3e4 ("ext4: fix data corruption in inodes with journalled data")
Fixes: 2b405bfa84 ("ext4: fix data=journal fast mount/umount hang")
Cc: Jan Kara <ja...@suse.cz>
Cc: sta...@vger.kernel.org
Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: Theodore Ts'o <ty...@mit.edu>
Reviewed-by: Jan Kara <ja...@suse.cz>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
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 fb7e576d..221b582 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -206,9 +206,9 @@ void ext4_evict_inode(struct inode *inode)
* Note that directories do not have this problem because they
* don't use page cache.
*/
- if (ext4_should_journal_data(inode) &&
- (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
- inode->i_ino != EXT4_JOURNAL_INO) {
+ if (inode->i_ino != EXT4_JOURNAL_INO &&
+ ext4_should_journal_data(inode) &&
+ (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:47:48 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 7d3f843eed29222254c9feab481f55175a1afcc9 upstream.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/netfilter/ip_tables.c | 61 +++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 36 deletions(-)

diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 29f3092..ddfc3ac 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1439,7 +1439,6 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,

static int
compat_find_calc_match(struct xt_entry_match *m,
- const char *name,
const struct ipt_ip *ip,
unsigned int hookmask,
int *size)
@@ -1477,8 +1476,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
const unsigned char *base,
const unsigned char *limit,
const unsigned int *hook_entries,
- const unsigned int *underflows,
- const char *name)
+ const unsigned int *underflows)
{
struct xt_entry_match *ematch;
struct xt_entry_target *t;
@@ -1514,8 +1512,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
entry_offset = (void *)e - (void *)base;
j = 0;
xt_ematch_foreach(ematch, e) {
- ret = compat_find_calc_match(ematch, name,
- &e->ip, e->comefrom, &off);
+ ret = compat_find_calc_match(ematch, &e->ip, e->comefrom,
+ &off);
if (ret != 0)
goto release_matches;
++j;
@@ -1564,7 +1562,7 @@ release_matches:

static int
compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
- unsigned int *size, const char *name,
+ unsigned int *size,
struct xt_table_info *newinfo, unsigned char *base)
{
struct xt_entry_target *t;
@@ -1640,14 +1638,9 @@ compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)

static int
translate_compat_table(struct net *net,
- const char *name,
- unsigned int valid_hooks,
struct xt_table_info **pinfo,
void **pentry0,
- unsigned int total_size,
- unsigned int number,
- unsigned int *hook_entries,
- unsigned int *underflows)
+ const struct compat_ipt_replace *compatr)
{
unsigned int i, j;
struct xt_table_info *newinfo, *info;
@@ -1659,8 +1652,8 @@ translate_compat_table(struct net *net,

info = *pinfo;
entry0 = *pentry0;
- size = total_size;
- info->number = number;
+ size = compatr->size;
+ info->number = compatr->num_entries;

/* Init all hooks to impossible value. */
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
@@ -1671,40 +1664,39 @@ translate_compat_table(struct net *net,
duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(AF_INET);
- xt_compat_init_offsets(AF_INET, number);
+ xt_compat_init_offsets(AF_INET, compatr->num_entries);
/* Walk through entries, checking offsets. */
- xt_entry_foreach(iter0, entry0, total_size) {
+ xt_entry_foreach(iter0, entry0, compatr->size) {
ret = check_compat_entry_size_and_hooks(iter0, info, &size,
entry0,
- entry0 + total_size,
- hook_entries,
- underflows,
- name);
+ entry0 + compatr->size,
+ compatr->hook_entry,
+ compatr->underflow);
if (ret != 0)
goto out_unlock;
++j;
}

ret = -EINVAL;
- if (j != number) {
+ if (j != compatr->num_entries) {
duprintf("translate_compat_table: %u not %u entries\n",
- j, number);
+ j, compatr->num_entries);
goto out_unlock;
}

/* Check hooks all assigned */
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
/* Only hooks which are valid */
- if (!(valid_hooks & (1 << i)))
+ if (!(compatr->valid_hooks & (1 << i)))
continue;
if (info->hook_entry[i] == 0xFFFFFFFF) {
duprintf("Invalid hook entry %u %u\n",
- i, hook_entries[i]);
+ i, info->hook_entry[i]);
goto out_unlock;
}
if (info->underflow[i] == 0xFFFFFFFF) {
duprintf("Invalid underflow %u %u\n",
- i, underflows[i]);
+ i, info->underflow[i]);
goto out_unlock;
}
}
@@ -1714,17 +1706,17 @@ translate_compat_table(struct net *net,
if (!newinfo)
goto out_unlock;

- newinfo->number = number;
+ newinfo->number = compatr->num_entries;
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
newinfo->hook_entry[i] = info->hook_entry[i];
newinfo->underflow[i] = info->underflow[i];
}
entry1 = newinfo->entries[raw_smp_processor_id()];
pos = entry1;
- size = total_size;
- xt_entry_foreach(iter0, entry0, total_size) {
+ size = compatr->size;
+ xt_entry_foreach(iter0, entry0, compatr->size) {
ret = compat_copy_entry_from_user(iter0, &pos, &size,
- name, newinfo, entry1);
+ newinfo, entry1);
if (ret != 0)
break;
}
@@ -1734,12 +1726,12 @@ translate_compat_table(struct net *net,
goto free_newinfo;

ret = -ELOOP;
- if (!mark_source_chains(newinfo, valid_hooks, entry1))
+ if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
goto free_newinfo;

i = 0;
xt_entry_foreach(iter1, entry1, newinfo->size) {
- ret = compat_check_entry(iter1, net, name);
+ ret = compat_check_entry(iter1, net, compatr->name);
if (ret != 0)
break;
++i;
@@ -1784,7 +1776,7 @@ translate_compat_table(struct net *net,
free_newinfo:
xt_free_table_info(newinfo);
out:
- xt_entry_foreach(iter0, entry0, total_size) {
+ xt_entry_foreach(iter0, entry0, compatr->size) {
if (j-- == 0)
break;
compat_release_entry(iter0);
@@ -1827,10 +1819,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
goto free_newinfo;
}

- ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
- &newinfo, &loc_cpu_entry, tmp.size,
- tmp.num_entries, tmp.hook_entry,
- tmp.underflow);
+ ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);

Willy Tarreau

unread,
Aug 21, 2016, 11:48:23 AM8/21/16
to
From: James Bottomley <James.B...@HansenPartnership.com>

commit a621bac3044ed6f7ec5fa0326491b2d4838bfa93 upstream.

When SCSI was written, all commands coming from the filesystem
(REQ_TYPE_FS commands) had data. This meant that our signal for needing
to complete the command was the number of bytes completed being equal to
the number of bytes in the request. Unfortunately, with the advent of
flush barriers, we can now get zero length REQ_TYPE_FS commands, which
confuse this logic because they satisfy the condition every time. This
means they never get retried even for retryable conditions, like UNIT
ATTENTION because we complete them early assuming they're done. Fix
this by special casing the early completion condition to recognise zero
length commands with errors and let them drop through to the retry code.

Reported-by: Sebastian Parschauer <s.pars...@gmx.de>
Signed-off-by: James E.J. Bottomley <je...@linux.vnet.ibm.com>
Tested-by: Jack Wang <jinpu...@profitbricks.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
[ jwang: backport from upstream 4.7 to fix scsi resize issue ]
Signed-off-by: Jack Wang <jinpu...@profitbricks.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/scsi/scsi_lib.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index dc96905..60031e1 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -790,9 +790,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
}

/*
- * If we finished all bytes in the request we are done now.
+ * special case: failed zero length commands always need to
+ * drop down into the retry code. Otherwise, if we finished
+ * all bytes in the request we are done now.
*/
- if (!blk_end_request(req, error, good_bytes))
+ if (!(blk_rq_bytes(req) == 0 && error) &&
+ !blk_end_request(req, error, good_bytes))
goto next_command;

/*
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:05 AM8/21/16
to
From: Mark Brown <bro...@kernel.org>

commit 6b7f4e25f3309f106a5c7ff42c8231494cf285d3 upstream.

All regulator_get() variants return either a pointer to a regulator or an
ERR_PTR() so testing for NULL makes no sense and may lead to bugs if we
use NULL as a valid regulator. Fix this by using IS_ERR() as expected.

Signed-off-by: Mark Brown <bro...@kernel.org>
Cc: <Sta...@vger.kernel.org>
Signed-off-by: Jonathan Cameron <ji...@kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/iio/adc/ad7266.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index c2744a7..d08f417 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -406,7 +406,7 @@ static int ad7266_probe(struct spi_device *spi)
st = iio_priv(indio_dev);

st->reg = regulator_get(&spi->dev, "vref");
- if (!IS_ERR_OR_NULL(st->reg)) {
+ if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:05 AM8/21/16
to
From: Paolo Bonzini <pbon...@redhat.com>

commit d14bdb553f9196169f003058ae1cdabe514470e6 upstream.

MOV to DR6 or DR7 causes a #GP if an attempt is made to write a 1 to
any of bits 63:32. However, this is not detected at KVM_SET_DEBUGREGS
time, and the next KVM_RUN oopses:

general protection fault: 0000 [#1] SMP
CPU: 2 PID: 14987 Comm: a.out Not tainted 4.4.9-300.fc23.x86_64 #1
Hardware name: LENOVO 2325F51/2325F51, BIOS G2ET32WW (1.12 ) 05/30/2012
[...]
Call Trace:
[<ffffffffa072c93d>] kvm_arch_vcpu_ioctl_run+0x141d/0x14e0 [kvm]
[<ffffffffa071405d>] kvm_vcpu_ioctl+0x33d/0x620 [kvm]
[<ffffffff81241648>] do_vfs_ioctl+0x298/0x480
[<ffffffff812418a9>] SyS_ioctl+0x79/0x90
[<ffffffff817a0f2e>] entry_SYSCALL_64_fastpath+0x12/0x71
Code: 55 83 ff 07 48 89 e5 77 27 89 ff ff 24 fd 90 87 80 81 0f 23 fe 5d c3 0f 23 c6 5d c3 0f 23 ce 5d c3 0f 23 d6 5d c3 0f 23 de 5d c3 <0f> 23 f6 5d c3 0f 0b 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00
RIP [<ffffffff810639eb>] native_set_debugreg+0x2b/0x40
RSP <ffff88005836bd50>

Testcase (beautified/reduced from syzkaller output):

#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdint.h>
#include <linux/kvm.h>
#include <fcntl.h>
#include <sys/ioctl.h>

long r[8];

int main()
{
struct kvm_debugregs dr = { 0 };

r[2] = open("/dev/kvm", O_RDONLY);
r[3] = ioctl(r[2], KVM_CREATE_VM, 0);
r[4] = ioctl(r[3], KVM_CREATE_VCPU, 7);

memcpy(&dr,
"\x5d\x6a\x6b\xe8\x57\x3b\x4b\x7e\xcf\x0d\xa1\x72"
"\xa3\x4a\x29\x0c\xfc\x6d\x44\x00\xa7\x52\xc7\xd8"
"\x00\xdb\x89\x9d\x78\xb5\x54\x6b\x6b\x13\x1c\xe9"
"\x5e\xd3\x0e\x40\x6f\xb4\x66\xf7\x5b\xe3\x36\xcb",
48);
r[7] = ioctl(r[4], KVM_SET_DEBUGREGS, &dr);
r[6] = ioctl(r[4], KVM_RUN, 0);
}

Reported-by: Dmitry Vyukov <dvy...@google.com>
Signed-off-by: Paolo Bonzini <pbon...@redhat.com>
Signed-off-by: Radim Krčmář <rkr...@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/kvm/x86.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3c0b085..8e57771 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2966,6 +2966,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
if (dbgregs->flags)
return -EINVAL;

+ if (dbgregs->dr6 & ~0xffffffffull)
+ return -EINVAL;
+ if (dbgregs->dr7 & ~0xffffffffull)
+ return -EINVAL;
+
memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
vcpu->arch.dr6 = dbgregs->dr6;
vcpu->arch.dr7 = dbgregs->dr7;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:05 AM8/21/16
to
From: Javier Martinez Canillas <jav...@osg.samsung.com>

commit 6311f1261f59ce5e51fbe5cc3b5e7737197316ac upstream.

When s5p_mfc_remove() calls put_device() for the reserved memory region
devs, the driver core warns that the dev doesn't have a release callback:

WARNING: CPU: 0 PID: 591 at drivers/base/core.c:251 device_release+0x8c/0x90
Device 's5p-mfc-l' does not have a release() function, it is broken and must be fixed.

Also, the declared DMA memory using dma_declare_coherent_memory() isn't
relased so add a dev .release that calls dma_release_declared_memory().

Cc: <sta...@vger.kernel.org>
Fixes: 6e83e6e25eb4 ("[media] s5p-mfc: Fix kernel warning on memory init")
Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com>
Tested-by: Marek Szyprowski <m.szyp...@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.naw...@samsung.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/media/platform/s5p-mfc/s5p_mfc.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index fe91623..eb92027 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1000,6 +1000,11 @@ static int match_child(struct device *dev, void *data)
return !strcmp(dev_name(dev), (char *)data);
}

+static void s5p_mfc_memdev_release(struct device *dev)
+{
+ dma_release_declared_memory(dev);
+}
+
static void *mfc_get_drv_data(struct platform_device *pdev);

static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
@@ -1014,6 +1019,7 @@ static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
}

dev_set_name(dev->mem_dev_l, "%s", "s5p-mfc-l");
+ dev->mem_dev_l->release = s5p_mfc_memdev_release;
device_initialize(dev->mem_dev_l);
of_property_read_u32_array(dev->plat_dev->dev.of_node,
"samsung,mfc-l", mem_info, 2);
@@ -1033,6 +1039,7 @@ static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
}

dev_set_name(dev->mem_dev_r, "%s", "s5p-mfc-r");
+ dev->mem_dev_r->release = s5p_mfc_memdev_release;
device_initialize(dev->mem_dev_r);
of_property_read_u32_array(dev->plat_dev->dev.of_node,
"samsung,mfc-r", mem_info, 2);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:05 AM8/21/16
to
From: Simon Horman <simon....@netronome.com>

commit d5d8760b78d0cfafe292f965f599988138b06a70 upstream.

Since 32b8a8e59c9c ("sit: add IPv4 over IPv4 support")
ipip6_err() may be called for packets whose IP protocol is
IPPROTO_IPIP as well as those whose IP protocol is IPPROTO_IPV6.

In the case of IPPROTO_IPIP packets the correct protocol value is not
passed to ipv4_update_pmtu() or ipv4_redirect().

This patch resolves this problem by using the IP protocol of the packet
rather than a hard-coded value. This appears to be consistent
with the usage of the protocol of a packet by icmp_socket_deliver()
the caller of ipip6_err().

I was able to exercise the redirect case by using a setup where an ICMP
redirect was received for the destination of the encapsulated packet.
However, it appears that although incorrect the protocol field is not used
in this case and thus no problem manifests. On inspection it does not
appear that a problem will manifest in the fragmentation needed/update pmtu
case either.

In short I believe this is a cosmetic fix. None the less, the use of
IPPROTO_IPV6 seems wrong and confusing.

Reviewed-by: Dinan Gunawardena <dinan.gu...@netronome.com>
Signed-off-by: Simon Horman <simon....@netronome.com>
Acked-by: YOSHIFUJI Hideaki <yosh...@linux-ipv6.org>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv6/sit.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 4ddf67c..d9535bb 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -530,13 +530,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info)

if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
ipv4_update_pmtu(skb, dev_net(skb->dev), info,
- t->parms.link, 0, IPPROTO_IPV6, 0);
+ t->parms.link, 0, iph->protocol, 0);
err = 0;
goto out;
}
if (type == ICMP_REDIRECT) {
ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
- IPPROTO_IPV6, 0);
+ iph->protocol, 0);
err = 0;
goto out;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:05 AM8/21/16
to
From: Vineet Gupta <vgu...@synopsys.com>

commit a6416f57ce57fb390b6ee30b12c01c29032a26af upstream.

ARCompact and ARCv2 only have ASL, while binutils used to support LSL as
a alias mnemonic.

Newer binutils (upstream) don't want to do that so replace it.

Signed-off-by: Vineet Gupta <vgu...@synopsys.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/arc/mm/tlbex.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arc/mm/tlbex.S b/arch/arc/mm/tlbex.S
index 3357d26..74691e6 100644
--- a/arch/arc/mm/tlbex.S
+++ b/arch/arc/mm/tlbex.S
@@ -219,7 +219,7 @@ ex_saved_reg1:
#ifdef CONFIG_SMP
sr r0, [ARC_REG_SCRATCH_DATA0] ; freeup r0 to code with
GET_CPU_ID r0 ; get to per cpu scratch mem,
- lsl r0, r0, L1_CACHE_SHIFT ; cache line wide per cpu
+ asl r0, r0, L1_CACHE_SHIFT ; cache line wide per cpu
add r0, @ex_saved_reg1, r0
#else
st r0, [@ex_saved_reg1]
@@ -239,7 +239,7 @@ ex_saved_reg1:
.macro TLBMISS_RESTORE_REGS
#ifdef CONFIG_SMP
GET_CPU_ID r0 ; get to per cpu scratch mem
- lsl r0, r0, L1_CACHE_SHIFT ; each is cache line wide
+ asl r0, r0, L1_CACHE_SHIFT ; each is cache line wide
add r0, @ex_saved_reg1, r0
ld_s r3, [r0,12]
ld_s r2, [r0, 8]
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:05 AM8/21/16
to
From: Luis Henriques <luis.he...@canonical.com>

commit dee08ab83d0378d922b67e7cf10bbec3e4ea343b upstream.

Function regulator_enable() may return an error that has to be checked.
This patch changes function rfkill_regulator_set_block() so that it checks
for the return code. Also, rfkill_data->reg_enabled is set to 'true' only
if there is no error.

This fixes the following compilation warning:

net/rfkill/rfkill-regulator.c:43:20: warning: ignoring return value of 'regulator_enable', declared with attribute warn_unused_result [-Wunused-result]

Signed-off-by: Luis Henriques <luis.he...@canonical.com>
Signed-off-by: Johannes Berg <johann...@intel.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/rfkill/rfkill-regulator.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c
index d11ac79..cf5b145 100644
--- a/net/rfkill/rfkill-regulator.c
+++ b/net/rfkill/rfkill-regulator.c
@@ -30,6 +30,7 @@ struct rfkill_regulator_data {
static int rfkill_regulator_set_block(void *data, bool blocked)
{
struct rfkill_regulator_data *rfkill_data = data;
+ int ret = 0;

pr_debug("%s: blocked: %d\n", __func__, blocked);

@@ -40,15 +41,16 @@ static int rfkill_regulator_set_block(void *data, bool blocked)
}
} else {
if (!rfkill_data->reg_enabled) {
- regulator_enable(rfkill_data->vcc);
- rfkill_data->reg_enabled = true;
+ ret = regulator_enable(rfkill_data->vcc);
+ if (!ret)
+ rfkill_data->reg_enabled = true;
}
}

pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__,
regulator_is_enabled(rfkill_data->vcc));

- return 0;
+ return ret;
}

static struct rfkill_ops rfkill_regulator_ops = {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Cameron Gutman <aicom...@gmail.com>

commit caca925fca4fb30c67be88cacbe908eec6721e43 upstream.

This prevents a malicious USB device from causing an oops.

Signed-off-by: Cameron Gutman <aicom...@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry....@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/input/joystick/xpad.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 856c1b0..685e125 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -843,6 +843,9 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_endpoint_descriptor *ep_irq_in;
int i, error;

+ if (intf->cur_altsetting->desc.bNumEndpoints != 2)
+ return -ENODEV;
+
for (i = 0; xpad_device[i].idVendor; i++) {
if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
(le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Bjørn Mork <bj...@mork.no>

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.

CVE-2016-3951

Fixes: 8a34b0ae8778 ("usbnet: cdc_ncm: apply usbnet_link_change")
Reported-by: Andrey Konovalov <andre...@gmail.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Signed-off-by: Bjørn Mork <bj...@mork.no>
Signed-off-by: David S. Miller <da...@davemloft.net>
[ciwi...@brocade.com: backported to 3.10: adjusted context]
Signed-off-by: Charles (Chas) Williams <ciwi...@brocade.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
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 74581cb..6ee9665 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.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Paul Burton <paul....@imgtec.com>

commit ab4a92e66741b35ca12f8497896bafbe579c28a1 upstream.

When emulating a jalr instruction with rd == $0, the code in
isBranchInstr was incorrectly writing to GPR $0 which should actually
always remain zeroed. This would lead to any further instructions
emulated which use $0 operating on a bogus value until the task is next
context switched, at which point the value of $0 in the task context
would be restored to the correct zero by a store in SAVE_SOME. Fix this
by not writing to rd if it is $0.

Fixes: 102cedc32a6e ("MIPS: microMIPS: Floating point support.")
Signed-off-by: Paul Burton <paul....@imgtec.com>
Cc: Maciej W. Rozycki <ma...@imgtec.com>
Cc: James Hogan <james...@imgtec.com>
Cc: linux...@linux-mips.org
Cc: linux-...@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/13160/
Signed-off-by: Ralf Baechle <ra...@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/math-emu/cp1emu.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index f03771900..3d492a8 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -684,9 +684,11 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case spec_op:
switch (insn.r_format.func) {
case jalr_op:
- regs->regs[insn.r_format.rd] =
- regs->cp0_epc + dec_insn.pc_inc +
- dec_insn.next_pc_inc;
+ if (insn.r_format.rd != 0) {
+ regs->regs[insn.r_format.rd] =
+ regs->cp0_epc + dec_insn.pc_inc +
+ dec_insn.next_pc_inc;
+ }
/* Fall through */
case jr_op:
*contpc = regs->regs[insn.r_format.rs];
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Soheil Hassas Yeganeh <soh...@google.com>

commit f626300a3e776ccc9671b0dd94698fb3aa315966 upstream.

tcp_select_initial_window() intends to advertise a window
scaling for the maximum possible window size. To do so,
it considers the maximum of net.ipv4.tcp_rmem[2] and
net.core.rmem_max as the only possible upper-bounds.
However, users with CAP_NET_ADMIN can use SO_RCVBUFFORCE
to set the socket's receive buffer size to values
larger than net.ipv4.tcp_rmem[2] and net.core.rmem_max.
Thus, SO_RCVBUFFORCE is effectively ignored by
tcp_select_initial_window().

To fix this, consider the maximum of net.ipv4.tcp_rmem[2],
net.core.rmem_max and socket's initial buffer space.

Fixes: b0573dea1fb3 ("[NET]: Introduce SO_{SND,RCV}BUFFORCE socket options")
Signed-off-by: Soheil Hassas Yeganeh <soh...@google.com>
Suggested-by: Neal Cardwell <ncar...@google.com>
Acked-by: Neal Cardwell <ncar...@google.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/tcp_output.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 76c80b59..276b283 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -222,7 +222,8 @@ void tcp_select_initial_window(int __space, __u32 mss,
/* Set window scaling on max possible window
* See RFC1323 for an explanation of the limit to 14
*/
- space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
+ space = max_t(u32, space, sysctl_tcp_rmem[2]);
+ space = max_t(u32, space, sysctl_rmem_max);
space = min_t(u32, space, *window_clamp);
while (space > 65535 && (*rcv_wscale) < 14) {
space >>= 1;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Andy Lutomirski <lu...@kernel.org>

commit 4eaffdd5a5fe6ff9f95e1ab4de1ac904d5e0fa8b upstream.

My previous comments were still a bit confusing and there was a
typo. Fix it up.

Reported-by: Peter Zijlstra <pet...@infradead.org>
Signed-off-by: Andy Lutomirski <lu...@kernel.org>
Cc: Andy Lutomirski <lu...@amacapital.net>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brg...@gmail.com>
Cc: Dave Hansen <dave....@linux.intel.com>
Cc: Denys Vlasenko <dvla...@redhat.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Rik van Riel <ri...@redhat.com>
Cc: Thomas Gleixner <tg...@linutronix.de>
Cc: sta...@vger.kernel.org
Fixes: 71b3c126e611 ("x86/mm: Add barriers and document switch_mm()-vs-flush synchronization")
Link: http://lkml.kernel.org/r/0a0b43cdcdd241c5faaaecfbcc91a1...@kernel.org
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/include/asm/mmu_context.h | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
index c0d2f6b..29a3d1b 100644
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
@@ -58,14 +58,16 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* be sent, and CPU 0's TLB will contain a stale entry.)
*
* The bad outcome can occur if either CPU's load is
- * reordered before that CPU's store, so both CPUs much
+ * reordered before that CPU's store, so both CPUs must
* execute full barriers to prevent this from happening.
*
* Thus, switch_mm needs a full barrier between the
* store to mm_cpumask and any operation that could load
- * from next->pgd. This barrier synchronizes with
- * remote TLB flushers. Fortunately, load_cr3 is
- * serializing and thus acts as a full barrier.
+ * from next->pgd. TLB fills are special and can happen
+ * due to instruction fetches or for no reason at all,
+ * and neither LOCK nor MFENCE orders them.
+ * Fortunately, load_cr3() is serializing and gives the
+ * ordering guarantee we need.
*
*/
load_cr3(next->pgd);
@@ -96,9 +98,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
* tlb flush IPI delivery. We must reload CR3
* to make sure to use no freed page tables.
*
- * As above, this is a barrier that forces
- * TLB repopulation to be ordered after the
- * store to mm_cpumask.
+ * As above, load_cr3() is serializing and orders TLB
+ * fills with respect to the mm_cpumask write.
*/
load_cr3(next->pgd);
load_LDT_nolock(&next->context);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Raghava Aditya Renukunta <RaghavaAdit...@microsemi.com>

commit fc4bf75ea300a5e62a2419f89dd0e22189dd7ab7 upstream.

Typically under error conditions, it is possible for aac_command_thread()
to miss the wakeup from kthread_stop() and go back to sleep, causing it
to hang aac_shutdown.

In the observed scenario, the adapter is not functioning correctly and so
aac_fib_send() never completes (or time-outs depending on how it was
called). Shortly after aac_command_thread() starts it performs
aac_fib_send(SendHostTime) which hangs. When aac_probe_one
/aac_get_adapter_info send time outs, kthread_stop is called which breaks
the command thread out of it's hang.

The code will still go back to sleep in schedule_timeout() without
checking kthread_should_stop() so it causes aac_probe_one to hang until
the schedule_timeout() which is 30 minutes.

Fixed by: Adding another kthread_should_stop() before schedule_timeout()
Cc: sta...@vger.kernel.org
Signed-off-by: Raghava Aditya Renukunta <RaghavaAdit...@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthum...@suse.de>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/scsi/aacraid/commsup.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index addcd58..284efac 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1920,6 +1920,10 @@ int aac_command_thread(void *data)
if (difference <= 0)
difference = 1;
set_current_state(TASK_INTERRUPTIBLE);
+
+ if (kthread_should_stop())
+ break;
+
schedule_timeout(difference);

if (kthread_should_stop())
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: "Guilherme G. Piccoli" <gpic...@linux.vnet.ibm.com>

commit 8445a87f7092bc8336ea1305be9306f26b846d93 upstream.

Commit 39baadbf36ce ("powerpc/eeh: Remove eeh information from pci_dn")
changed the pci_dn struct by removing its EEH-related members.
As part of this clean-up, DDW mechanism was modified to read the device
configuration address from eeh_dev struct.

As a consequence, now if we disable EEH mechanism on kernel command-line
for example, the DDW mechanism will fail, generating a kernel oops by
dereferencing a NULL pointer (which turns to be the eeh_dev pointer).

This patch just changes the configuration address calculation on DDW
functions to a manual calculation based on pci_dn members instead of
using eeh_dev-based address.

No functional changes were made. This was tested on pSeries, both
in PHyp and qemu guest.

Fixes: 39baadbf36ce ("powerpc/eeh: Remove eeh information from pci_dn")
Cc: sta...@vger.kernel.org # v3.4+
Reviewed-by: Gavin Shan <gws...@linux.vnet.ibm.com>
Signed-off-by: Guilherme G. Piccoli <gpic...@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/powerpc/platforms/pseries/iommu.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 86ae364..1d2fc2f 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -858,7 +858,8 @@ machine_arch_initcall(pseries, find_existing_ddw_windows);
static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
struct ddw_query_response *query)
{
- struct eeh_dev *edev;
+ struct device_node *dn;
+ struct pci_dn *pdn;
u32 cfg_addr;
u64 buid;
int ret;
@@ -869,11 +870,10 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
* Retrieve them from the pci device, not the node with the
* dma-window property
*/
- edev = pci_dev_to_eeh_dev(dev);
- cfg_addr = edev->config_addr;
- if (edev->pe_config_addr)
- cfg_addr = edev->pe_config_addr;
- buid = edev->phb->buid;
+ dn = pci_device_to_OF_node(dev);
+ pdn = PCI_DN(dn);
+ buid = pdn->phb->buid;
+ cfg_addr = (pdn->busno << 8) | pdn->devfn;

ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
cfg_addr, BUID_HI(buid), BUID_LO(buid));
@@ -887,7 +887,8 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
struct ddw_create_response *create, int page_shift,
int window_shift)
{
- struct eeh_dev *edev;
+ struct device_node *dn;
+ struct pci_dn *pdn;
u32 cfg_addr;
u64 buid;
int ret;
@@ -898,11 +899,10 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
* Retrieve them from the pci device, not the node with the
* dma-window property
*/
- edev = pci_dev_to_eeh_dev(dev);
- cfg_addr = edev->config_addr;
- if (edev->pe_config_addr)
- cfg_addr = edev->pe_config_addr;
- buid = edev->phb->buid;
+ dn = pci_device_to_OF_node(dev);
+ pdn = PCI_DN(dn);
+ buid = pdn->phb->buid;
+ cfg_addr = (pdn->busno << 8) | pdn->devfn;

do {
/* extra outputs are LIOBN and dma-addr (hi, lo) */
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 0188346f21e6546498c2a0f84888797ad4063fc5 upstream.

Always returned 0.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
include/linux/netfilter/x_tables.h | 2 +-
net/ipv4/netfilter/arp_tables.c | 17 +++++------------
net/ipv4/netfilter/ip_tables.c | 26 +++++++++-----------------
net/ipv6/netfilter/ip6_tables.c | 27 +++++++++------------------
net/netfilter/x_tables.c | 5 ++---
5 files changed, 26 insertions(+), 51 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 8bb7706..9f0d2b5 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -427,7 +427,7 @@ extern void xt_compat_init_offsets(u_int8_t af, unsigned int number);
extern int xt_compat_calc_jump(u_int8_t af, unsigned int offset);

extern int xt_compat_match_offset(const struct xt_match *match);
-extern int xt_compat_match_from_user(struct xt_entry_match *m,
+extern void xt_compat_match_from_user(struct xt_entry_match *m,
void **dstptr, unsigned int *size);
extern int xt_compat_match_to_user(const struct xt_entry_match *m,
void __user **dstptr, unsigned int *size);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 2ad0bc6..b6fa4cc 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1295,7 +1295,7 @@ out:
return ret;
}

-static int
+static void
compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
unsigned int *size,
struct xt_table_info *newinfo, unsigned char *base)
@@ -1304,9 +1304,8 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
struct xt_target *target;
struct arpt_entry *de;
unsigned int origsize;
- int ret, h;
+ int h;

- ret = 0;
origsize = *size;
de = (struct arpt_entry *)*dstptr;
memcpy(de, e, sizeof(struct arpt_entry));
@@ -1327,7 +1326,6 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
if ((unsigned char *)de - base < newinfo->underflow[h])
newinfo->underflow[h] -= origsize - *size;
}
- return ret;
}

static int translate_compat_table(struct xt_table_info **pinfo,
@@ -1406,16 +1404,11 @@ static int translate_compat_table(struct xt_table_info **pinfo,
entry1 = newinfo->entries[raw_smp_processor_id()];
pos = entry1;
size = compatr->size;
- xt_entry_foreach(iter0, entry0, compatr->size) {
- ret = compat_copy_entry_from_user(iter0, &pos, &size,
- newinfo, entry1);
- if (ret != 0)
- break;
- }
+ xt_entry_foreach(iter0, entry0, compatr->size)
+ compat_copy_entry_from_user(iter0, &pos, &size,
+ newinfo, entry1);
xt_compat_flush_offsets(NFPROTO_ARP);
xt_compat_unlock(NFPROTO_ARP);
- if (ret)
- goto free_newinfo;

ret = -ELOOP;
if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index ddfc3ac..d68137b 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1560,7 +1560,7 @@ release_matches:
return ret;
}

-static int
+static void
compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
unsigned int *size,
struct xt_table_info *newinfo, unsigned char *base)
@@ -1569,10 +1569,9 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
struct xt_target *target;
struct ipt_entry *de;
unsigned int origsize;
- int ret, h;
+ int h;
struct xt_entry_match *ematch;

- ret = 0;
origsize = *size;
de = (struct ipt_entry *)*dstptr;
memcpy(de, e, sizeof(struct ipt_entry));
@@ -1581,11 +1580,9 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
*dstptr += sizeof(struct ipt_entry);
*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);

- xt_ematch_foreach(ematch, e) {
- ret = xt_compat_match_from_user(ematch, dstptr, size);
- if (ret != 0)
- return ret;
- }
+ xt_ematch_foreach(ematch, e)
+ xt_compat_match_from_user(ematch, dstptr, size);
+
de->target_offset = e->target_offset - (origsize - *size);
t = compat_ipt_get_target(e);
target = t->u.kernel.target;
@@ -1598,7 +1595,6 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
if ((unsigned char *)de - base < newinfo->underflow[h])
newinfo->underflow[h] -= origsize - *size;
}
- return ret;
}

static int
@@ -1714,16 +1710,12 @@ translate_compat_table(struct net *net,
entry1 = newinfo->entries[raw_smp_processor_id()];
pos = entry1;
size = compatr->size;
- xt_entry_foreach(iter0, entry0, compatr->size) {
- ret = compat_copy_entry_from_user(iter0, &pos, &size,
- newinfo, entry1);
- if (ret != 0)
- break;
- }
+ xt_entry_foreach(iter0, entry0, compatr->size)
+ compat_copy_entry_from_user(iter0, &pos, &size,
+ newinfo, entry1);
+
xt_compat_flush_offsets(AF_INET);
xt_compat_unlock(AF_INET);
- if (ret)
- goto free_newinfo;

ret = -ELOOP;
if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index a4565fe..49ec278 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1572,7 +1572,7 @@ release_matches:
return ret;
}

-static int
+static void
compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
unsigned int *size,
struct xt_table_info *newinfo, unsigned char *base)
@@ -1580,10 +1580,9 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
struct xt_entry_target *t;
struct ip6t_entry *de;
unsigned int origsize;
- int ret, h;
+ int h;
struct xt_entry_match *ematch;

- ret = 0;
origsize = *size;
de = (struct ip6t_entry *)*dstptr;
memcpy(de, e, sizeof(struct ip6t_entry));
@@ -1592,11 +1591,9 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
*dstptr += sizeof(struct ip6t_entry);
*size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);

- xt_ematch_foreach(ematch, e) {
- ret = xt_compat_match_from_user(ematch, dstptr, size);
- if (ret != 0)
- return ret;
- }
+ xt_ematch_foreach(ematch, e)
+ xt_compat_match_from_user(ematch, dstptr, size);
+
de->target_offset = e->target_offset - (origsize - *size);
t = compat_ip6t_get_target(e);
xt_compat_target_from_user(t, dstptr, size);
@@ -1608,7 +1605,6 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
if ((unsigned char *)de - base < newinfo->underflow[h])
newinfo->underflow[h] -= origsize - *size;
}
- return ret;
}

static int compat_check_entry(struct ip6t_entry *e, struct net *net,
@@ -1723,17 +1719,12 @@ translate_compat_table(struct net *net,
}
entry1 = newinfo->entries[raw_smp_processor_id()];
pos = entry1;
- size = compatr->size;
- xt_entry_foreach(iter0, entry0, compatr->size) {
- ret = compat_copy_entry_from_user(iter0, &pos, &size,
- newinfo, entry1);
- if (ret != 0)
- break;
- }
+ xt_entry_foreach(iter0, entry0, compatr->size)
+ compat_copy_entry_from_user(iter0, &pos, &size,
+ newinfo, entry1);
+
xt_compat_flush_offsets(AF_INET6);
xt_compat_unlock(AF_INET6);
- if (ret)
- goto free_newinfo;

ret = -ELOOP;
if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 6ac9fb4..9cf3039 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -545,8 +545,8 @@ int xt_compat_match_offset(const struct xt_match *match)
}
EXPORT_SYMBOL_GPL(xt_compat_match_offset);

-int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
- unsigned int *size)
+void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+ unsigned int *size)
{
const struct xt_match *match = m->u.kernel.match;
struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
@@ -568,7 +568,6 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,

*size += off;
*dstptr += msize;
- return 0;
}
EXPORT_SYMBOL_GPL(xt_compat_match_from_user);

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:06 AM8/21/16
to
From: Tim Gardner <tim.g...@canonical.com>

commit dd29dae00d39186890a5eaa2fe4ad8768bfd41a9 upstream.

drivers/scsi/be2iscsi/be_main.c: In function 'be_sgl_create_contiguous':
drivers/scsi/be2iscsi/be_main.c:3187:18: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses]
WARN_ON(!length > 0);

gcc version 5.2.1

Signed-off-by: Tim Gardner <tim.g...@canonical.com>
Cc: Jayamohan Kallickal <jayamohan...@avagotech.com>
Cc: Minh Tran <minh...@avagotech.com>
Cc: John Soni Jose <sony....@avagotech.com>
Cc: "James E.J. Bottomley" <JBott...@odin.com>
Reported-by: Joel Stanley <jo...@jms.id.au>
Reviewed-by: Manoj Kumar <ma...@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin....@oracle.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/scsi/be2iscsi/be_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index a683a83..0227813 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -2978,7 +2978,7 @@ be_sgl_create_contiguous(void *virtual_address,
{
WARN_ON(!virtual_address);
WARN_ON(!physical_address);
- WARN_ON(!length > 0);
+ WARN_ON(!length);
WARN_ON(!sgl);

sgl->va = virtual_address;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:07 AM8/21/16
to
From: Yishai Hadas <yis...@mellanox.com>

commit f2940e2c76bb554a7fbdd28ca5b90904117a9e96 upstream.

When calculating the required size of an RC QP send queue, leave
enough space for masked atomic operations, which require more space than
"regular" atomic operation.

Fixes: 6fa8f719844b ("IB/mlx4: Add support for masked atomic operations")
Signed-off-by: Yishai Hadas <yis...@mellanox.com>
Reviewed-by: Jack Morgenstein <ja...@mellanox.co.il>
Reviewed-by: Eran Ben Elisha <era...@mellanox.com>
Signed-off-by: Leon Romanovsky <le...@kernel.org>
Signed-off-by: Doug Ledford <dled...@redhat.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/infiniband/hw/mlx4/qp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 262a184..1fe3bdb 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -346,7 +346,7 @@ static int send_wqe_overhead(enum mlx4_ib_qp_type type, u32 flags)
sizeof (struct mlx4_wqe_raddr_seg);
case MLX4_IB_QPT_RC:
return sizeof (struct mlx4_wqe_ctrl_seg) +
- sizeof (struct mlx4_wqe_atomic_seg) +
+ sizeof (struct mlx4_wqe_masked_atomic_seg) +
sizeof (struct mlx4_wqe_raddr_seg);
case MLX4_IB_QPT_SMI:
case MLX4_IB_QPT_GSI:
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:07 AM8/21/16
to
From: James Hogan <james...@imgtec.com>

commit 5daebc477da4dfeb31ae193d83084def58fd2697 upstream.

Commit 85efde6f4e0d ("make exported headers use strict posix types")
changed the asm-generic siginfo.h to use the __kernel_* types, and
commit 3a471cbc081b ("remove __KERNEL_STRICT_NAMES") make the internal
types accessible only to the kernel, but the MIPS implementation hasn't
been updated to match.

Switch to proper types now so that the exported asm/siginfo.h won't
produce quite so many compiler errors when included alone by a user
program.

Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Christopher Ferris <cfe...@google.com>
Cc: linux...@linux-mips.org
Cc: <sta...@vger.kernel.org> # 2.6.30-
Cc: linux-...@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/12477/
Signed-off-by: Ralf Baechle <ra...@linux-mips.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/include/uapi/asm/siginfo.h | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h
index 6a87141..b5f77f7 100644
--- a/arch/mips/include/uapi/asm/siginfo.h
+++ b/arch/mips/include/uapi/asm/siginfo.h
@@ -45,13 +45,13 @@ typedef struct siginfo {

/* kill() */
struct {
- pid_t _pid; /* sender's pid */
+ __kernel_pid_t _pid; /* sender's pid */
__ARCH_SI_UID_T _uid; /* sender's uid */
} _kill;

/* POSIX.1b timers */
struct {
- timer_t _tid; /* timer id */
+ __kernel_timer_t _tid; /* timer id */
int _overrun; /* overrun count */
char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
sigval_t _sigval; /* same as below */
@@ -60,26 +60,26 @@ typedef struct siginfo {

/* POSIX.1b signals */
struct {
- pid_t _pid; /* sender's pid */
+ __kernel_pid_t _pid; /* sender's pid */
__ARCH_SI_UID_T _uid; /* sender's uid */
sigval_t _sigval;
} _rt;

/* SIGCHLD */
struct {
- pid_t _pid; /* which child */
+ __kernel_pid_t _pid; /* which child */
__ARCH_SI_UID_T _uid; /* sender's uid */
int _status; /* exit code */
- clock_t _utime;
- clock_t _stime;
+ __kernel_clock_t _utime;
+ __kernel_clock_t _stime;
} _sigchld;

/* IRIX SIGCHLD */
struct {
- pid_t _pid; /* which child */
- clock_t _utime;
+ __kernel_pid_t _pid; /* which child */
+ __kernel_clock_t _utime;
int _status; /* exit code */
- clock_t _stime;
+ __kernel_clock_t _stime;
} _irix_sigchld;

/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:07 AM8/21/16
to
commit ce16887b69e94a8c0305e88c918989f8bc1bd6b7 upstream.

Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
mm/migrate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index 2ee28c2..808f8ab 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -308,7 +308,7 @@ static inline bool buffer_migrate_lock_buffers(struct buffer_head *head,
* 2 for pages with a mapping
* 3 for pages with a mapping and PagePrivate/PagePrivate2 set.
*/
-static int migrate_page_move_mapping(struct address_space *mapping,
+int migrate_page_move_mapping(struct address_space *mapping,
struct page *newpage, struct page *page,
struct buffer_head *head, enum migrate_mode mode)
{
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:07 AM8/21/16
to
From: Luis de Bethencourt <lui...@osg.samsung.com>

commit ef3149eb3ddb7f9125e11c90f8330e371b55cffd upstream.

sca3000_read_ctrl_reg() returns a negative number on failure, check for
this instead of zero.

Signed-off-by: Luis de Bethencourt <lui...@osg.samsung.com>
Cc: <Sta...@vger.kernel.org>
Signed-off-by: Jonathan Cameron <ji...@kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/staging/iio/accel/sca3000_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index 32950ad..b30c41b 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -588,7 +588,7 @@ static ssize_t sca3000_read_frequency(struct device *dev,
goto error_ret_mut;
ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
mutex_unlock(&st->lock);
- if (ret)
+ if (ret < 0)
goto error_ret;
val = ret;
if (base_freq > 0)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:07 AM8/21/16
to
From: Helge Deller <del...@gmx.de>

commit 8b78f260887df532da529f225c49195d18fef36b upstream.

One of the debian buildd servers had this crash in the syslog without
any other information:

Unaligned handler failed, ret = -2
clock_adjtime (pid 22578): Unaligned data reference (code 28)
CPU: 1 PID: 22578 Comm: clock_adjtime Tainted: G E 4.5.0-2-parisc64-smp #1 Debian 4.5.4-1
task: 000000007d9960f8 ti: 00000001bde7c000 task.ti: 00000001bde7c000

YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
PSW: 00001000000001001111100000001111 Tainted: G E
r00-03 000000ff0804f80f 00000001bde7c2b0 00000000402d2be8 00000001bde7c2b0
r04-07 00000000409e1fd0 00000000fa6f7fff 00000001bde7c148 00000000fa6f7fff
r08-11 0000000000000000 00000000ffffffff 00000000fac9bb7b 000000000002b4d4
r12-15 000000000015241c 000000000015242c 000000000000002d 00000000fac9bb7b
r16-19 0000000000028800 0000000000000001 0000000000000070 00000001bde7c218
r20-23 0000000000000000 00000001bde7c210 0000000000000002 0000000000000000
r24-27 0000000000000000 0000000000000000 00000001bde7c148 00000000409e1fd0
r28-31 0000000000000001 00000001bde7c320 00000001bde7c350 00000001bde7c218
sr00-03 0000000001200000 0000000001200000 0000000000000000 0000000001200000
sr04-07 0000000000000000 0000000000000000 0000000000000000 0000000000000000

IASQ: 0000000000000000 0000000000000000 IAOQ: 00000000402d2e84 00000000402d2e88
IIR: 0ca0d089 ISR: 0000000001200000 IOR: 00000000fa6f7fff
CPU: 1 CR30: 00000001bde7c000 CR31: ffffffffffffffff
ORIG_R28: 00000002369fe628
IAOQ[0]: compat_get_timex+0x2dc/0x3c0
IAOQ[1]: compat_get_timex+0x2e0/0x3c0
RP(r2): compat_get_timex+0x40/0x3c0
Backtrace:
[<00000000402d4608>] compat_SyS_clock_adjtime+0x40/0xc0
[<0000000040205024>] syscall_exit+0x0/0x14

This means the userspace program clock_adjtime called the clock_adjtime()
syscall and then crashed inside the compat_get_timex() function.
Syscalls should never crash programs, but instead return EFAULT.

The IIR register contains the executed instruction, which disassebles
into "ldw 0(sr3,r5),r9".
This load-word instruction is part of __get_user() which tried to read the word
at %r5/IOR (0xfa6f7fff). This means the unaligned handler jumped in. The
unaligned handler is able to emulate all ldw instructions, but it fails if it
fails to read the source e.g. because of page fault.

The following program reproduces the problem:

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/mman.h>

int main(void) {
/* allocate 8k */
char *ptr = mmap(NULL, 2*4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
/* free second half (upper 4k) and make it invalid. */
munmap(ptr+4096, 4096);
/* syscall where first int is unaligned and clobbers into invalid memory region */
/* syscall should return EFAULT */
return syscall(__NR_clock_adjtime, 0, ptr+4095);
}

To fix this issue we simply need to check if the faulting instruction address
is in the exception fixup table when the unaligned handler failed. If it
is, call the fixup routine instead of crashing.

While looking at the unaligned handler I found another issue as well: The
target register should not be modified if the handler was unsuccessful.

Signed-off-by: Helge Deller <del...@gmx.de>
Cc: sta...@vger.kernel.org
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/parisc/kernel/unaligned.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index d7c0acb..8d49614 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs)
break;
}

- if (modify && R1(regs->iir))
+ if (ret == 0 && modify && R1(regs->iir))
regs->gr[R1(regs->iir)] = newbase;


@@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs)

if (ret)
{
+ /*
+ * The unaligned handler failed.
+ * If we were called by __get_user() or __put_user() jump
+ * to it's exception fixup handler instead of crashing.
+ */
+ if (!user_mode(regs) && fixup_exception(regs))
+ return;
+
printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
die_if_kernel("Unaligned data reference", regs, 28);

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:08 AM8/21/16
to
From: Vladimir Davydov <vdav...@parallels.com>

commit 69828dce7af2cb6d08ef5a03de687d422fb7ec1f upstream.

Sending SI_TKILL from rt_[tg]sigqueueinfo was deprecated, so now we issue
a warning on the first attempt of doing it. We use WARN_ON_ONCE, which is
not informative and, what is worse, taints the kernel, making the trinity
syscall fuzzer complain false-positively from time to time.

It does not look like we need this warning at all, because the behaviour
changed quite a long time ago (2.6.39), and if an application relies on
the old API, it gets EPERM anyway and can issue a warning by itself.

So let us zap the warning in kernel.

Signed-off-by: Vladimir Davydov <vdav...@parallels.com>
Acked-by: Oleg Nesterov <ol...@redhat.com>
Cc: Richard Weinberger <ric...@nod.at>
Cc: "Paul E. McKenney" <pau...@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <ak...@linux-foundation.org>
Signed-off-by: Linus Torvalds <torv...@linux-foundation.org>
Cc: Vinson Lee <vl...@freedesktop.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
kernel/signal.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index 4d1f7fa..7b81c53 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3004,11 +3004,9 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
- (task_pid_vnr(current) != pid)) {
- /* We used to allow any < 0 si_code */
- WARN_ON_ONCE(info->si_code < 0);
+ (task_pid_vnr(current) != pid))
return -EPERM;
- }
+
info->si_signo = sig;

/* POSIX.1b doesn't mention process groups. */
@@ -3053,12 +3051,10 @@ static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (((info->si_code >= 0 || info->si_code == SI_TKILL)) &&
- (task_pid_vnr(current) != pid)) {
- /* We used to allow any < 0 si_code */
- WARN_ON_ONCE(info->si_code < 0);
+ if ((info->si_code >= 0 || info->si_code == SI_TKILL) &&
+ (task_pid_vnr(current) != pid))
return -EPERM;
- }
+
info->si_signo = sig;

return do_send_specific(tgid, pid, sig, info);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:08 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 7b7eba0f3515fca3296b8881d583f7c1042f5226 upstream.

Quoting John Stultz:
In updating a 32bit arm device from 4.6 to Linus' current HEAD, I
noticed I was having some trouble with networking, and realized that
/proc/net/ip_tables_names was suddenly empty.
Digging through the registration process, it seems we're catching on the:

if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
target_offset + sizeof(struct xt_standard_target) != next_offset)
return -EINVAL;

Where next_offset seems to be 4 bytes larger then the
offset + standard_target struct size.

next_offset needs to be aligned via XT_ALIGN (so we can access all members
of ip(6)t_entry struct).

This problem didn't show up on i686 as it only needs 4-byte alignment for
u64, but iptables userspace on other 32bit arches does insert extra padding.

Reported-by: John Stultz <john....@linaro.org>
Tested-by: John Stultz <john....@linaro.org>
Fixes: 7ed2abddd20cf ("netfilter: x_tables: check standard target size too")
Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/netfilter/x_tables.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index c482633..6ac9fb4 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -628,7 +628,7 @@ int xt_compat_check_entry_offsets(const void *base, const char *elems,
return -EINVAL;

if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
- target_offset + sizeof(struct compat_xt_standard_target) != next_offset)
+ COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset)
return -EINVAL;

/* compat_xt_entry match has less strict aligment requirements,
@@ -710,7 +710,7 @@ int xt_check_entry_offsets(const void *base,
return -EINVAL;

if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
- target_offset + sizeof(struct xt_standard_target) != next_offset)
+ XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset)
return -EINVAL;

return xt_check_entry_match(elems, base + target_offset,
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:08 AM8/21/16
to
From: Vegard Nossum <vegard...@oracle.com>

commit d3e6952cfb7ba5f4bfa29d4803ba91f96ce1204d upstream.

I ran into this:

kasan: CONFIG_KASAN_INLINE enabled
kasan: GPF could be caused by NULL-ptr deref or user memory access
general protection fault: 0000 [#1] PREEMPT SMP KASAN
CPU: 2 PID: 2012 Comm: trinity-c3 Not tainted 4.7.0-rc7+ #19
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
task: ffff8800b745f2c0 ti: ffff880111740000 task.ti: ffff880111740000
RIP: 0010:[<ffffffff82bbf066>] [<ffffffff82bbf066>] irttp_connect_request+0x36/0x710
RSP: 0018:ffff880111747bb8 EFLAGS: 00010286
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000069dd8358
RDX: 0000000000000009 RSI: 0000000000000027 RDI: 0000000000000048
RBP: ffff880111747c00 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000069dd8358 R11: 1ffffffff0759723 R12: 0000000000000000
R13: ffff88011a7e4780 R14: 0000000000000027 R15: 0000000000000000
FS: 00007fc738404700(0000) GS:ffff88011af00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fc737fdfb10 CR3: 0000000118087000 CR4: 00000000000006e0
Stack:
0000000000000200 ffff880111747bd8 ffffffff810ee611 ffff880119f1f220
ffff880119f1f4f8 ffff880119f1f4f0 ffff88011a7e4780 ffff880119f1f232
ffff880119f1f220 ffff880111747d58 ffffffff82bca542 0000000000000000
Call Trace:
[<ffffffff82bca542>] irda_connect+0x562/0x1190
[<ffffffff825ae582>] SYSC_connect+0x202/0x2a0
[<ffffffff825b4489>] SyS_connect+0x9/0x10
[<ffffffff8100334c>] do_syscall_64+0x19c/0x410
[<ffffffff83295ca5>] entry_SYSCALL64_slow_path+0x25/0x25
Code: 41 89 ca 48 89 e5 41 57 41 56 41 55 41 54 41 89 d7 53 48 89 fb 48 83 c7 48 48 89 fa 41 89 f6 48 c1 ea 03 48 83 ec 20 4c 8b 65 10 <0f> b6 04 02 84 c0 74 08 84 c0 0f 8e 4c 04 00 00 80 7b 48 00 74
RIP [<ffffffff82bbf066>] irttp_connect_request+0x36/0x710
RSP <ffff880111747bb8>
---[ end trace 4cda2588bc055b30 ]---

The problem is that irda_open_tsap() can fail and leave self->tsap = NULL,
and then irttp_connect_request() almost immediately dereferences it.

Cc: sta...@vger.kernel.org
Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/irda/af_irda.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index f8133ff..c95bafa 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1039,8 +1039,11 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
}

/* Check if we have opened a local TSAP */
- if (!self->tsap)
- irda_open_tsap(self, LSAP_ANY, addr->sir_name);
+ if (!self->tsap) {
+ err = irda_open_tsap(self, LSAP_ANY, addr->sir_name);
+ if (err)
+ goto out;
+ }

/* Move to connecting socket, start sending Connect Requests */
sock->state = SS_CONNECTING;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:09 AM8/21/16
to
From: Ricky Liang <jcl...@chromium.org>

commit affa80bd97f7ca282d1faa91667b3ee9e4c590e6 upstream.

When running a 32-bit userspace on a 64-bit kernel, the UI_SET_PHYS
ioctl needs to be treated with special care, as it has the pointer
size encoded in the command.

Signed-off-by: Ricky Liang <jcl...@chromium.org>
Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry....@gmail.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/input/misc/uinput.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index a0a4bba..3f2f3ac 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -835,9 +835,15 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}

#ifdef CONFIG_COMPAT
+
+#define UI_SET_PHYS_COMPAT _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
+
static long uinput_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
+ if (cmd == UI_SET_PHYS_COMPAT)
+ cmd = UI_SET_PHYS;
+
return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
}
#endif
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:09 AM8/21/16
to
From: Takashi Iwai <ti...@suse.de>

commit d5dbbe6569481bf12dcbe3e12cff72c5f78d272c upstream.

syzkaller fuzzer spotted a potential use-after-free case in snd-dummy
driver when hrtimer is used as backend:
> ==================================================================
> BUG: KASAN: use-after-free in rb_erase+0x1b17/0x2010 at addr ffff88005e5b6f68
> Read of size 8 by task syz-executor/8984
> =============================================================================
> BUG kmalloc-192 (Not tainted): kasan: bad access detected
> -----------------------------------------------------------------------------
>
> Disabling lock debugging due to kernel taint
> INFO: Allocated in 0xbbbbbbbbbbbbbbbb age=18446705582212484632
> ....
> [< none >] dummy_hrtimer_create+0x49/0x1a0 sound/drivers/dummy.c:464
> ....
> INFO: Freed in 0xfffd8e09 age=18446705496313138713 cpu=2164287125 pid=-1
> [< none >] dummy_hrtimer_free+0x68/0x80 sound/drivers/dummy.c:481
> ....
> Call Trace:
> [<ffffffff8179e59e>] __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:333
> [< inline >] rb_set_parent include/linux/rbtree_augmented.h:111
> [< inline >] __rb_erase_augmented include/linux/rbtree_augmented.h:218
> [<ffffffff82ca5787>] rb_erase+0x1b17/0x2010 lib/rbtree.c:427
> [<ffffffff82cb02e8>] timerqueue_del+0x78/0x170 lib/timerqueue.c:86
> [<ffffffff814d0c80>] __remove_hrtimer+0x90/0x220 kernel/time/hrtimer.c:903
> [< inline >] remove_hrtimer kernel/time/hrtimer.c:945
> [<ffffffff814d23da>] hrtimer_try_to_cancel+0x22a/0x570 kernel/time/hrtimer.c:1046
> [<ffffffff814d2742>] hrtimer_cancel+0x22/0x40 kernel/time/hrtimer.c:1066
> [<ffffffff85420531>] dummy_hrtimer_stop+0x91/0xb0 sound/drivers/dummy.c:417
> [<ffffffff854228bf>] dummy_pcm_trigger+0x17f/0x1e0 sound/drivers/dummy.c:507
> [<ffffffff85392170>] snd_pcm_do_stop+0x160/0x1b0 sound/core/pcm_native.c:1106
> [<ffffffff85391b26>] snd_pcm_action_single+0x76/0x120 sound/core/pcm_native.c:956
> [<ffffffff85391e01>] snd_pcm_action+0x231/0x290 sound/core/pcm_native.c:974
> [< inline >] snd_pcm_stop sound/core/pcm_native.c:1139
> [<ffffffff8539754d>] snd_pcm_drop+0x12d/0x1d0 sound/core/pcm_native.c:1784
> [<ffffffff8539d3be>] snd_pcm_common_ioctl1+0xfae/0x2150 sound/core/pcm_native.c:2805
> [<ffffffff8539ee91>] snd_pcm_capture_ioctl1+0x2a1/0x5e0 sound/core/pcm_native.c:2976
> [<ffffffff8539f2ec>] snd_pcm_kernel_ioctl+0x11c/0x160 sound/core/pcm_native.c:3020
> [<ffffffff853d9a44>] snd_pcm_oss_sync+0x3a4/0xa30 sound/core/oss/pcm_oss.c:1693
> [<ffffffff853da27d>] snd_pcm_oss_release+0x1ad/0x280 sound/core/oss/pcm_oss.c:2483
> .....

A workaround is to call hrtimer_cancel() in dummy_hrtimer_sync() which
is called certainly before other blocking ops.

Reported-by: Dmitry Vyukov <dvy...@google.com>
Tested-by: Dmitry Vyukov <dvy...@google.com>
Cc: <sta...@vger.kernel.org>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
sound/drivers/dummy.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 982a2c2..7f400a1 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -422,6 +422,7 @@ static int dummy_hrtimer_stop(struct snd_pcm_substream *substream)

static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
{
+ hrtimer_cancel(&dpcm->timer);
tasklet_kill(&dpcm->tasklet);
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:09 AM8/21/16
to
From: Dave Jones <da...@codemonkey.org.uk>

commit 1086bbe97a074844188c6c988fa0b1a98c3ccbb9 upstream.

After improving setsockopt() coverage in trinity, I started triggering
vmalloc failures pretty reliably from this code path:

warn_alloc_failed+0xe9/0x140
__vmalloc_node_range+0x1be/0x270
vzalloc+0x4b/0x50
__do_replace+0x52/0x260 [ip_tables]
do_ipt_set_ctl+0x15d/0x1d0 [ip_tables]
nf_setsockopt+0x65/0x90
ip_setsockopt+0x61/0xa0
raw_setsockopt+0x16/0x60
sock_common_setsockopt+0x14/0x20
SyS_setsockopt+0x71/0xd0

It turns out we don't validate that the num_counters field in the
struct we pass in from userspace is initialized.

The same problem also exists in ebtables, arptables, ipv6, and the
compat variants.

Signed-off-by: Dave Jones <da...@codemonkey.org.uk>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/bridge/netfilter/ebtables.c | 4 ++++
net/ipv4/netfilter/arp_tables.c | 6 ++++++
net/ipv4/netfilter/ip_tables.c | 6 ++++++
net/ipv6/netfilter/ip6_tables.c | 6 ++++++
4 files changed, 22 insertions(+)

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 6651a77..8d60948 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1105,6 +1105,8 @@ static int do_replace(struct net *net, const void __user *user,
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;

tmp.name[sizeof(tmp.name) - 1] = 0;

@@ -2150,6 +2152,8 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;

memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index b6fa4cc..b65b562 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1076,6 +1076,9 @@ static int do_replace(struct net *net, const void __user *user,
/* overflow check */
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;
+
tmp.name[sizeof(tmp.name)-1] = 0;

newinfo = xt_alloc_table_info(tmp.size);
@@ -1490,6 +1493,9 @@ static int compat_do_replace(struct net *net, void __user *user,
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;
+
tmp.name[sizeof(tmp.name)-1] = 0;

newinfo = xt_alloc_table_info(tmp.size);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index d68137b..b9dd1fd 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1262,6 +1262,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
/* overflow check */
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;
+
tmp.name[sizeof(tmp.name)-1] = 0;

newinfo = xt_alloc_table_info(tmp.size);
@@ -1797,6 +1800,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;
+
tmp.name[sizeof(tmp.name)-1] = 0;

newinfo = xt_alloc_table_info(tmp.size);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 49ec278..6e7f5ac 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1272,6 +1272,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
/* overflow check */
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;
+
tmp.name[sizeof(tmp.name)-1] = 0;

newinfo = xt_alloc_table_info(tmp.size);
@@ -1806,6 +1809,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
return -ENOMEM;
if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
return -ENOMEM;
+ if (tmp.num_counters == 0)
+ return -EINVAL;
+
tmp.name[sizeof(tmp.name)-1] = 0;

newinfo = xt_alloc_table_info(tmp.size);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:09 AM8/21/16
to
From: Jason Gunthorpe <jgunt...@obsidianresearch.com>

commit 8c5122e45a10a9262f872b53f151a592e870f905 upstream.

When this code was reworked for IBoE support the order of assignments
for the sl_tclass_flowlabel got flipped around resulting in
TClass & FlowLabel being permanently set to 0 in the packet headers.

This breaks IB routers that rely on these headers, but only affects
kernel users - libmlx4 does this properly for user space.

Cc: sta...@vger.kernel.org
Fixes: fa417f7b520e ("IB/mlx4: Add support for IBoE")
Signed-off-by: Jason Gunthorpe <jgunt...@obsidianresearch.com>
Signed-off-by: Doug Ledford <dled...@redhat.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/infiniband/hw/mlx4/ah.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index 890c23b..f55d695 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -65,6 +65,7 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,

ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
ah->av.ib.g_slid = ah_attr->src_path_bits;
+ ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
if (ah_attr->ah_flags & IB_AH_GRH) {
ah->av.ib.g_slid |= 0x80;
ah->av.ib.gid_index = ah_attr->grh.sgid_index;
@@ -82,7 +83,6 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
!(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support))
--ah->av.ib.stat_rate;
}
- ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);

return &ah->ibah;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:10 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit aa412ba225dd3bc36d404c28cdc3d674850d80d0 upstream.

Once we add more sanity testing to xt_check_entry_offsets it
becomes relvant if we're expecting a 32bit 'config_compat' blob
or a normal one.

Since we already have a lot of similar-named functions (check_entry,
compat_check_entry, find_and_check_entry, etc.) and the current
incarnation is short just fold its contents into the callers.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/netfilter/arp_tables.c | 19 ++++++++-----------
net/ipv4/netfilter/ip_tables.c | 20 ++++++++------------
net/ipv6/netfilter/ip6_tables.c | 20 ++++++++------------
3 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 839a698..e931372 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -485,14 +485,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
return 1;
}

-static inline int check_entry(const struct arpt_entry *e)
-{
- if (!arp_checkentry(&e->arp))
- return -EINVAL;
-
- return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
-}
-
static inline int check_target(struct arpt_entry *e, const char *name)
{
struct xt_entry_target *t = arpt_get_target(e);
@@ -582,7 +574,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
return -EINVAL;
}

- err = check_entry(e);
+ if (!arp_checkentry(&e->arp))
+ return -EINVAL;
+
+ err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
if (err)
return err;

@@ -1241,8 +1236,10 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
return -EINVAL;
}

- /* For purposes of check_entry casting the compat entry is fine */
- ret = check_entry((struct arpt_entry *)e);
+ if (!arp_checkentry(&e->arp))
+ return -EINVAL;
+
+ ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
if (ret)
return ret;

diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index ffd46717..f1e083a 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -579,15 +579,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
}

static int
-check_entry(const struct ipt_entry *e)
-{
- if (!ip_checkentry(&e->ip))
- return -EINVAL;
-
- return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
-}
-
-static int
check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ipt_ip *ip = par->entryinfo;
@@ -743,7 +734,10 @@ check_entry_size_and_hooks(struct ipt_entry *e,
return -EINVAL;
}

- err = check_entry(e);
+ if (!ip_checkentry(&e->ip))
+ return -EINVAL;
+
+ err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
if (err)
return err;

@@ -1507,8 +1501,10 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
return -EINVAL;
}

- /* For purposes of check_entry casting the compat entry is fine */
- ret = check_entry((struct ipt_entry *)e);
+ if (!ip_checkentry(&e->ip))
+ return -EINVAL;
+
+ ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
if (ret)
return ret;

diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 5692017..23401a7 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -588,15 +588,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
module_put(par.match->me);
}

-static int
-check_entry(const struct ip6t_entry *e)
-{
- if (!ip6_checkentry(&e->ipv6))
- return -EINVAL;
-
- return xt_check_entry_offsets(e, e->target_offset, e->next_offset);
-}
-
static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
{
const struct ip6t_ip6 *ipv6 = par->entryinfo;
@@ -754,7 +745,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
return -EINVAL;
}

- err = check_entry(e);
+ if (!ip6_checkentry(&e->ipv6))
+ return -EINVAL;
+
+ err = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
if (err)
return err;

@@ -1519,8 +1513,10 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
return -EINVAL;
}

- /* For purposes of check_entry casting the compat entry is fine */
- ret = check_entry((struct ip6t_entry *)e);
+ if (!ip6_checkentry(&e->ipv6))
+ return -EINVAL;
+
+ ret = xt_check_entry_offsets(e, e->target_offset, e->next_offset);
if (ret)
return ret;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:10 AM8/21/16
to
From: Dave Weinstein <olo...@google.com>

commit 7de249964f5578e67b99699c5f0b405738d820a2 upstream.

Add access checks to sys_oabi_epoll_wait() and sys_oabi_semtimedop().
This fixes CVE-2016-3857, a local privilege escalation under
CONFIG_OABI_COMPAT.

Cc: sta...@vger.kernel.org
Reported-by: Chiachih Wu <wuchi...@gmail.com>
Reviewed-by: Kees Cook <kees...@chromium.org>
Reviewed-by: Nicolas Pitre <ni...@linaro.org>
Signed-off-by: Dave Weinstein <olo...@google.com>
Signed-off-by: Linus Torvalds <torv...@linux-foundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/arm/kernel/sys_oabi-compat.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index 3e94811..a0aee80 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -275,8 +275,12 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
mm_segment_t fs;
long ret, err, i;

- if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
+ if (maxevents <= 0 ||
+ maxevents > (INT_MAX/sizeof(*kbuf)) ||
+ maxevents > (INT_MAX/sizeof(*events)))
return -EINVAL;
+ if (!access_ok(VERIFY_WRITE, events, sizeof(*events) * maxevents))
+ return -EFAULT;
kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
@@ -313,6 +317,8 @@ asmlinkage long sys_oabi_semtimedop(int semid,

if (nsops < 1 || nsops > SEMOPM)
return -EINVAL;
+ if (!access_ok(VERIFY_READ, tsops, sizeof(*tsops) * nsops))
+ return -EFAULT;
sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
if (!sops)
return -ENOMEM;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:10 AM8/21/16
to
From: "H. Peter Anvin" <h...@zytor.com>

commit 9c77679cadb118c0aa99e6f88533d91765a131ba upstream.

For newer versions of Syslinux, we need ldlinux.c32 in addition to
isolinux.bin to reside on the boot disk, so if the latter is found,
copy it, too, to the isoimage tree.

Signed-off-by: H. Peter Anvin <h...@zytor.com>
Cc: Linux Stable Tree <sta...@vger.kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/boot/Makefile | 3 +++
1 file changed, 3 insertions(+)

diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index 6cf0111..368f358 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -168,6 +168,9 @@ isoimage: $(obj)/bzImage
for i in lib lib64 share end ; do \
if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
+ if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \
+ cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \
+ fi ; \
break ; \
fi ; \
if [ $$i = end ] ; then exit 1 ; fi ; \
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:11 AM8/21/16
to
From: James Hogan <james...@imgtec.com>

commit 797179bc4fe06c89e47a9f36f886f68640b423f8 upstream.

Copy __kvm_mips_vcpu_run() into unmapped memory, so that we can never
get a TLB refill exception in it when KVM is built as a module.

This was observed to happen with the host MIPS kernel running under
QEMU, due to a not entirely transparent optimisation in the QEMU TLB
handling where TLB entries replaced with TLBWR are copied to a separate
part of the TLB array. Code in those pages continue to be executable,
but those mappings persist only until the next ASID switch, even if they
are marked global.

An ASID switch happens in __kvm_mips_vcpu_run() at exception level after
switching to the guest exception base. Subsequent TLB mapped kernel
instructions just prior to switching to the guest trigger a TLB refill
exception, which enters the guest exception handlers without updating
EPC. This appears as a guest triggered TLB refill on a host kernel
mapped (host KSeg2) address, which is not handled correctly as user
(guest) mode accesses to kernel (host) segments always generate address
error exceptions.

Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Paolo Bonzini <pbon...@redhat.com>
Cc: Radim Krčmář <rkr...@redhat.com>
Cc: Ralf Baechle <ra...@linux-mips.org>
Cc: k...@vger.kernel.org
Cc: linux...@linux-mips.org
Cc: <sta...@vger.kernel.org> # 3.10.x-
Signed-off-by: Paolo Bonzini <pbon...@redhat.com>
[james...@imgtec.com: backported for stable 3.14]
Signed-off-by: James Hogan <james...@imgtec.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/include/asm/kvm_host.h | 1 +
arch/mips/kvm/kvm_locore.S | 1 +
arch/mips/kvm/kvm_mips.c | 11 ++++++++++-
arch/mips/kvm/kvm_mips_int.h | 2 ++
4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 4d6fa0b..883a162 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -349,6 +349,7 @@ struct kvm_mips_tlb {
#define KVM_MIPS_GUEST_TLB_SIZE 64
struct kvm_vcpu_arch {
void *host_ebase, *guest_ebase;
+ int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
unsigned long host_stack;
unsigned long host_gp;

diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S
index 34c35f0..73553cd 100644
--- a/arch/mips/kvm/kvm_locore.S
+++ b/arch/mips/kvm/kvm_locore.S
@@ -227,6 +227,7 @@ FEXPORT(__kvm_mips_load_k0k1)
/* Jump to guest */
eret
.set pop
+EXPORT(__kvm_mips_vcpu_run_end)

VECTOR(MIPSX(exception), unknown)
/*
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
index 8aa5f30..97a181a 100644
--- a/arch/mips/kvm/kvm_mips.c
+++ b/arch/mips/kvm/kvm_mips.c
@@ -343,6 +343,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
memcpy(gebase + offset, mips32_GuestException,
mips32_GuestExceptionEnd - mips32_GuestException);

+#ifdef MODULE
+ offset += mips32_GuestExceptionEnd - mips32_GuestException;
+ memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
+ __kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
+ vcpu->arch.vcpu_run = gebase + offset;
+#else
+ vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
+#endif
+
/* Invalidate the icache for these ranges */
mips32_SyncICache((unsigned long) gebase, ALIGN(size, PAGE_SIZE));

@@ -426,7 +435,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)

kvm_guest_enter();

- r = __kvm_mips_vcpu_run(run, vcpu);
+ r = vcpu->arch.vcpu_run(run, vcpu);

kvm_guest_exit();
local_irq_enable();
diff --git a/arch/mips/kvm/kvm_mips_int.h b/arch/mips/kvm/kvm_mips_int.h
index 20da7d2..bf41ea3 100644
--- a/arch/mips/kvm/kvm_mips_int.h
+++ b/arch/mips/kvm/kvm_mips_int.h
@@ -27,6 +27,8 @@
#define MIPS_EXC_MAX 12
/* XXXSL More to follow */

+extern char __kvm_mips_vcpu_run_end[];
+
#define C_TI (_ULCAST_(1) << 30)

#define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (0)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:11 AM8/21/16
to
From: James Hogan <james...@imgtec.com>

commit 0741f52d1b980dbeb290afe67d88fc2928edd8ab upstream.

Two consecutive gfns are loaded into host TLB, so ensure the range check
isn't off by one if guest_pmap_npages is odd.

Fixes: 858dd5d45733 ("KVM/MIPS32: MMU/TLB operations for the Guest.")
Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Paolo Bonzini <pbon...@redhat.com>
Cc: "Radim Krčmář" <rkr...@redhat.com>
Cc: Ralf Baechle <ra...@linux-mips.org>
Cc: linux...@linux-mips.org
Cc: k...@vger.kernel.org
Signed-off-by: Radim Krčmář <rkr...@redhat.com>
[james...@imgtec.com: Backport to v3.10.y - v3.15.y]
Signed-off-by: James Hogan <james...@imgtec.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/kvm/kvm_tlb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c
index 8aba2e5..5a3c373 100644
--- a/arch/mips/kvm/kvm_tlb.c
+++ b/arch/mips/kvm/kvm_tlb.c
@@ -312,7 +312,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
}

gfn = (KVM_GUEST_CPHYSADDR(badvaddr) >> PAGE_SHIFT);
- if (gfn >= kvm->arch.guest_pmap_npages) {
+ if ((gfn | 1) >= kvm->arch.guest_pmap_npages) {
kvm_err("%s: Invalid gfn: %#llx, BadVaddr: %#lx\n", __func__,
gfn, badvaddr);
kvm_mips_dump_host_tlbs();
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:11 AM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 7ed2abddd20cf8f6bd27f65bd218f26fa5bf7f44 upstream.

We have targets and standard targets -- the latter carries a verdict.

The ip/ip6tables validation functions will access t->verdict for the
standard targets to fetch the jump offset or verdict for chainloop
detection, but this happens before the targets get checked/validated.

Thus we also need to check for verdict presence here, else t->verdict
can point right after a blob.

Spotted with UBSAN while testing malformed blobs.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/netfilter/x_tables.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index eeb4edc..37f7eda 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -559,6 +559,13 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
}
EXPORT_SYMBOL_GPL(xt_compat_match_to_user);

+/* non-compat version may have padding after verdict */
+struct compat_xt_standard_target {
+ struct compat_xt_entry_target t;
+ compat_uint_t verdict;
+};
+
+/* see xt_check_entry_offsets */
int xt_compat_check_entry_offsets(const void *base,
unsigned int target_offset,
unsigned int next_offset)
@@ -576,6 +583,10 @@ int xt_compat_check_entry_offsets(const void *base,
if (target_offset + t->u.target_size > next_offset)
return -EINVAL;

+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
+ target_offset + sizeof(struct compat_xt_standard_target) != next_offset)
+ return -EINVAL;
+
return 0;
}
EXPORT_SYMBOL(xt_compat_check_entry_offsets);
@@ -615,6 +626,10 @@ int xt_check_entry_offsets(const void *base,
if (target_offset + t->u.target_size > next_offset)
return -EINVAL;

+ if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
+ target_offset + sizeof(struct xt_standard_target) != next_offset)
+ return -EINVAL;
+
return 0;
}
EXPORT_SYMBOL(xt_check_entry_offsets);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:22 AM8/21/16
to
From: Paul Moore <pa...@paul-moore.com>

commit 0e0e36774081534783aa8eeb9f6fbddf98d3c061 upstream.

It seems risky to always rely on the caller to ensure the socket's
address family is correct before passing it to the NetLabel kAPI,
especially since we see at least one LSM which didn't. Add address
family checks to the *_delattr() functions to help prevent future
problems.

Cc: <sta...@vger.kernel.org>
Reported-by: Maninder Singh <manin...@samsung.com>
Signed-off-by: Paul Moore <pa...@paul-moore.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/netlabel/netlabel_kapi.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 7c94aed..5b1fbe4 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -700,7 +700,11 @@ socket_setattr_return:
*/
void netlbl_sock_delattr(struct sock *sk)
{
- cipso_v4_sock_delattr(sk);
+ switch (sk->sk_family) {
+ case AF_INET:
+ cipso_v4_sock_delattr(sk);
+ break;
+ }
}

/**
@@ -879,7 +883,11 @@ req_setattr_return:
*/
void netlbl_req_delattr(struct request_sock *req)
{
- cipso_v4_req_delattr(req);
+ switch (req->rsk_ops->family) {
+ case AF_INET:
+ cipso_v4_req_delattr(req);
+ break;
+ }
}

/**
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:22 AM8/21/16
to
From: Mark Brown <bro...@kernel.org>

commit 68b356eb3d9f5e38910fb62e22a78e2a18d544ae upstream.

Currently the ad7266 driver treats any failure to get vref as though the
regulator were not present but this means that if probe deferral is
triggered the driver will act as though the regulator were not present.
Instead only use the internal reference if we explicitly got -ENODEV which
is what is returned for absent regulators.

Signed-off-by: Mark Brown <bro...@kernel.org>
Cc: <Sta...@vger.kernel.org>
Signed-off-by: Jonathan Cameron <ji...@kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/iio/adc/ad7266.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
index d08f417..6569a4e 100644
--- a/drivers/iio/adc/ad7266.c
+++ b/drivers/iio/adc/ad7266.c
@@ -417,6 +417,10 @@ static int ad7266_probe(struct spi_device *spi)

st->vref_uv = ret;
} else {
+ /* Any other error indicates that the regulator does exist */
+ if (PTR_ERR(st->reg) != -ENODEV)
+ return PTR_ERR(st->reg);
+
/* Use internal reference */
st->vref_uv = 2500000;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:05 PM8/21/16
to
From: Amadeusz Sławiński <amadeusz....@tieto.com>

commit 23bc6ab0a0912146fd674a0becc758c3162baabc upstream.

When we retrieve imtu value from userspace we should use 16 bit pointer
cast instead of 32 as it's defined that way in headers. Fixes setsockopt
calls on big-endian platforms.

Signed-off-by: Amadeusz Sławiński <amadeusz....@tieto.com>
Signed-off-by: Marcel Holtmann <mar...@holtmann.org>
Cc: sta...@vger.kernel.org
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/bluetooth/l2cap_sock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 5f36f70..4b966c6 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -725,7 +725,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
break;
}

- if (get_user(opt, (u32 __user *) optval)) {
+ if (get_user(opt, (u16 __user *) optval)) {
err = -EFAULT;
break;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: Dave Chinner <dchi...@redhat.com>

commit 7d3aa7fe970791f1a674b14572a411accf2f4d4e upstream.

We don't write back stale inodes so we should skip them in
xfs_iflush_cluster, too.

cc: <sta...@vger.kernel.org> # 3.10.x-
Signed-off-by: Dave Chinner <dchi...@redhat.com>
Reviewed-by: Brian Foster <bfo...@redhat.com>
Reviewed-by: Christoph Hellwig <h...@lst.de>
Signed-off-by: Dave Chinner <da...@fromorbit.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/xfs/xfs_inode.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 52faf49..130881e 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2606,6 +2606,7 @@ xfs_iflush_cluster(
*/
spin_lock(&iq->i_flags_lock);
if (!iq->i_ino ||
+ __xfs_iflags_test(iq, XFS_ISTALE) ||
(XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
spin_unlock(&iq->i_flags_lock);
continue;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: Alexey Brodkin <Alexey....@synopsys.com>

commit 9bd54517ee86cb164c734f72ea95aeba4804f10b upstream.

If CONFIG_ARC_DW2_UNWIND is disabled every time arc_unwind_core()
gets called following message gets printed in debug console:
----------------->8---------------
CONFIG_ARC_DW2_UNWIND needs to be enabled
----------------->8---------------

That message makes sense if user indeed wants to see a backtrace or
get nice function call-graphs in perf but what if user disabled
unwinder for the purpose? Why pollute his debug console?

So instead we'll warn user about possibly missing feature once and
let him decide if that was what he or she really wanted.

Signed-off-by: Alexey Brodkin <abro...@synopsys.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Vineet Gupta <vgu...@synopsys.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/arc/kernel/stacktrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
index ca0207b..06997ad 100644
--- a/arch/arc/kernel/stacktrace.c
+++ b/arch/arc/kernel/stacktrace.c
@@ -131,7 +131,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
* prelogue is setup (callee regs saved and then fp set and not other
* way around
*/
- pr_warn("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
+ pr_warn_once("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
return 0;

#endif
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: Tomer Barletz <bar...@gmail.com>

commit 8ec7cfce3762299ae289c384e281b2f4010ae231 upstream.

This fixes the following warning, that is seen with gcc 5.1:
warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses].

Signed-off-by: Tomer Barletz <bar...@gmail.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
sound/pci/oxygen/oxygen_mixer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index c0dbb52..1e4bcb9 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -88,7 +88,7 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
int changed;

mutex_lock(&chip->mutex);
- changed = !value->value.integer.value[0] != chip->dac_mute;
+ changed = (!value->value.integer.value[0]) != chip->dac_mute;
if (changed) {
chip->dac_mute = !value->value.integer.value[0];
chip->model.update_dac_mute(chip);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: Florian Westphal <f...@strlen.de>

commit 329a0807124f12fe1c8032f95d8a8eb47047fb0e upstream.

Signed-off-by: Florian Westphal <f...@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv6/netfilter/ip6_tables.c | 61 +++++++++++++++++------------------------
1 file changed, 25 insertions(+), 36 deletions(-)

diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index df9947d..a4565fe 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1451,7 +1451,6 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,

static int
compat_find_calc_match(struct xt_entry_match *m,
- const char *name,
const struct ip6t_ip6 *ipv6,
unsigned int hookmask,
int *size)
@@ -1489,8 +1488,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
const unsigned char *base,
const unsigned char *limit,
const unsigned int *hook_entries,
- const unsigned int *underflows,
- const char *name)
+ const unsigned int *underflows)
{
struct xt_entry_match *ematch;
struct xt_entry_target *t;
@@ -1526,8 +1524,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
entry_offset = (void *)e - (void *)base;
j = 0;
xt_ematch_foreach(ematch, e) {
- ret = compat_find_calc_match(ematch, name,
- &e->ipv6, e->comefrom, &off);
+ ret = compat_find_calc_match(ematch, &e->ipv6, e->comefrom,
+ &off);
if (ret != 0)
goto release_matches;
++j;
@@ -1576,7 +1574,7 @@ release_matches:

static int
compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
- unsigned int *size, const char *name,
+ unsigned int *size,
struct xt_table_info *newinfo, unsigned char *base)
{
struct xt_entry_target *t;
@@ -1650,14 +1648,9 @@ static int compat_check_entry(struct ip6t_entry *e, struct net *net,

static int
translate_compat_table(struct net *net,
- const char *name,
- unsigned int valid_hooks,
struct xt_table_info **pinfo,
void **pentry0,
- unsigned int total_size,
- unsigned int number,
- unsigned int *hook_entries,
- unsigned int *underflows)
+ const struct compat_ip6t_replace *compatr)
{
unsigned int i, j;
struct xt_table_info *newinfo, *info;
@@ -1669,8 +1662,8 @@ translate_compat_table(struct net *net,

info = *pinfo;
entry0 = *pentry0;
- size = total_size;
- info->number = number;
+ size = compatr->size;
+ info->number = compatr->num_entries;

/* Init all hooks to impossible value. */
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
@@ -1681,40 +1674,39 @@ translate_compat_table(struct net *net,
duprintf("translate_compat_table: size %u\n", info->size);
j = 0;
xt_compat_lock(AF_INET6);
- xt_compat_init_offsets(AF_INET6, number);
+ xt_compat_init_offsets(AF_INET6, compatr->num_entries);
/* Walk through entries, checking offsets. */
- xt_entry_foreach(iter0, entry0, total_size) {
+ xt_entry_foreach(iter0, entry0, compatr->size) {
ret = check_compat_entry_size_and_hooks(iter0, info, &size,
entry0,
- entry0 + total_size,
- hook_entries,
- underflows,
- name);
+ entry0 + compatr->size,
+ compatr->hook_entry,
+ compatr->underflow);
if (ret != 0)
goto out_unlock;
++j;
}

ret = -EINVAL;
- if (j != number) {
+ if (j != compatr->num_entries) {
duprintf("translate_compat_table: %u not %u entries\n",
- j, number);
+ j, compatr->num_entries);
goto out_unlock;
}

/* Check hooks all assigned */
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
/* Only hooks which are valid */
- if (!(valid_hooks & (1 << i)))
+ if (!(compatr->valid_hooks & (1 << i)))
continue;
if (info->hook_entry[i] == 0xFFFFFFFF) {
duprintf("Invalid hook entry %u %u\n",
- i, hook_entries[i]);
+ i, info->hook_entry[i]);
goto out_unlock;
}
if (info->underflow[i] == 0xFFFFFFFF) {
duprintf("Invalid underflow %u %u\n",
- i, underflows[i]);
+ i, info->underflow[i]);
goto out_unlock;
}
}
@@ -1724,17 +1716,17 @@ translate_compat_table(struct net *net,
if (!newinfo)
goto out_unlock;

- newinfo->number = number;
+ newinfo->number = compatr->num_entries;
for (i = 0; i < NF_INET_NUMHOOKS; i++) {
newinfo->hook_entry[i] = info->hook_entry[i];
newinfo->underflow[i] = info->underflow[i];
}
entry1 = newinfo->entries[raw_smp_processor_id()];
pos = entry1;
- size = total_size;
- xt_entry_foreach(iter0, entry0, total_size) {
+ size = compatr->size;
+ xt_entry_foreach(iter0, entry0, compatr->size) {
ret = compat_copy_entry_from_user(iter0, &pos, &size,
- name, newinfo, entry1);
+ newinfo, entry1);
if (ret != 0)
break;
}
@@ -1744,12 +1736,12 @@ translate_compat_table(struct net *net,
goto free_newinfo;

ret = -ELOOP;
- if (!mark_source_chains(newinfo, valid_hooks, entry1))
+ if (!mark_source_chains(newinfo, compatr->valid_hooks, entry1))
goto free_newinfo;

i = 0;
xt_entry_foreach(iter1, entry1, newinfo->size) {
- ret = compat_check_entry(iter1, net, name);
+ ret = compat_check_entry(iter1, net, compatr->name);
if (ret != 0)
break;
++i;
@@ -1794,7 +1786,7 @@ translate_compat_table(struct net *net,
free_newinfo:
xt_free_table_info(newinfo);
out:
- xt_entry_foreach(iter0, entry0, total_size) {
+ xt_entry_foreach(iter0, entry0, compatr->size) {
if (j-- == 0)
break;
compat_release_entry(iter0);
@@ -1837,10 +1829,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
goto free_newinfo;
}

- ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
- &newinfo, &loc_cpu_entry, tmp.size,
- tmp.num_entries, tmp.hook_entry,
- tmp.underflow);
+ ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
if (ret != 0)
goto free_newinfo;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: "Palik, Imre" <im...@amazon.de>

commit 2c33645d366d13b969d936b68b9f4875b1fdddea upstream.

Architectural performance monitoring, version 1, doesn't support fixed counters.

Currently, even if a hypervisor advertises support for architectural
performance monitoring version 1, perf may still try to use the fixed
counters, as the constraints are set up based on the CPU model.

This patch ensures that perf honors the architectural performance monitoring
version returned by CPUID, and it only uses the fixed counters for version 2
and above.

(Some of the ideas in this patch came from Peter Zijlstra.)

Signed-off-by: Imre Palik <im...@amazon.de>
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Cc: Andrew Morton <ak...@linux-foundation.org>
Cc: Andy Lutomirski <lu...@amacapital.net>
Cc: Anthony Liguori <alig...@amazon.com>
Cc: Arnaldo Carvalho de Melo <ac...@kernel.org>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brg...@gmail.com>
Cc: Denys Vlasenko <dvla...@redhat.com>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Oleg Nesterov <ol...@redhat.com>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <tg...@linutronix.de>
Link: http://lkml.kernel.org/r/1433767609-1039-1-git...@gmail.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
[wt: FIXED_EVENT_FLAGS was X86_RAW_EVENT_MASK in 3.10]
Cc: Kevin Christopher <kev...@vmware.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/kernel/cpu/perf_event_intel.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index ac05758..bfc6bb5 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2241,13 +2241,16 @@ __init int intel_pmu_init(void)
* counter, so do not extend mask to generic counters
*/
for_each_event_constraint(c, x86_pmu.event_constraints) {
- if (c->cmask != X86_RAW_EVENT_MASK
- || c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) {
+ if (c->cmask == X86_RAW_EVENT_MASK
+ && c->idxmsk64 == INTEL_PMC_MSK_FIXED_REF_CYCLES) {
+ c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
continue;
}

- c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
- c->weight += x86_pmu.num_counters;
+ c->idxmsk64 &=
+ ~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
+ c->weight = hweight64(c->idxmsk64);
+
}
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: Erez Shitrit <ere...@mellanox.com>

commit 61c78eea9516a921799c17b4c20558e2aa780fd3 upstream.

ipoib_neigh_get unconditionally updates the "alive" variable member on
any packet send. This prevents the neighbor garbage collection from
cleaning out a dead neighbor entry if we are still queueing packets
for it. If the queue for this neighbor is full, then don't update the
alive timestamp. That way the neighbor can time out even if packets
are still being queued as long as none of them are being sent.

Fixes: b63b70d87741 ("IPoIB: Use a private hash table for path lookup in xmit path")
Signed-off-by: Erez Shitrit <ere...@mellanox.com>
Signed-off-by: Leon Romanovsky <le...@kernel.org>
Signed-off-by: Doug Ledford <dled...@redhat.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index b6e049a..a481094 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -887,7 +887,9 @@ struct ipoib_neigh *ipoib_neigh_get(struct net_device *dev, u8 *daddr)
neigh = NULL;
goto out_unlock;
}
- neigh->alive = jiffies;
+
+ if (likely(skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE))
+ neigh->alive = jiffies;
goto out_unlock;
}
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:06 PM8/21/16
to
From: Takashi Iwai <ti...@suse.de>

commit 62db7152c924e4c060e42b34a69cd39658e8a0dc upstream.

vortex_wtdma_bufshift() function does calculate the page index
wrongly, first masking then shift, which always results in zero.
The proper computation is to first shift, then mask.

Reported-by: Dan Carpenter <dan.ca...@oracle.com>
Cc: <sta...@vger.kernel.org>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
sound/pci/au88x0/au88x0_core.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index ae59dba..42d4b13 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -1442,9 +1442,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
int page, p, pp, delta, i;

page =
- (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
- WT_SUBBUF_MASK)
- >> WT_SUBBUF_SHIFT;
+ (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2))
+ >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
if (dma->nr_periods >= 4)
delta = (page - dma->period_real) & 3;
else {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:07 PM8/21/16
to
From: Christoph Hellwig <h...@lst.de>

commit bc85dc500f9df9b2eec15077e5046672c46adeaa upstream.

By folding scsi_end_request into its only caller we can significantly clean
up the completion logic. We can use simple goto labels now to only have
a single place to finish or requeue command there instead of the previous
convoluted logic.

Signed-off-by: Christoph Hellwig <h...@lst.de>
Reviewed-by: Nicholas Bellinger <n...@linux-iscsi.org>
Reviewed-by: Mike Christie <mich...@cs.wisc.edu>
Reviewed-by: Hannes Reinecke <ha...@suse.de>
[jwang: backport to 3.12]
Signed-off-by: Jack Wang <jinpu...@profitbricks.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/scsi/scsi_lib.c | 113 +++++++++++++-----------------------------------
1 file changed, 31 insertions(+), 82 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9f3168e..dc96905 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -546,66 +546,6 @@ void scsi_run_host_queues(struct Scsi_Host *shost)

static void __scsi_release_buffers(struct scsi_cmnd *, int);

-/*
- * Function: scsi_end_request()
- *
- * Purpose: Post-processing of completed commands (usually invoked at end
- * of upper level post-processing and scsi_io_completion).
- *
- * Arguments: cmd - command that is complete.
- * error - 0 if I/O indicates success, < 0 for I/O error.
- * bytes - number of bytes of completed I/O
- * requeue - indicates whether we should requeue leftovers.
- *
- * Lock status: Assumed that lock is not held upon entry.
- *
- * Returns: cmd if requeue required, NULL otherwise.
- *
- * Notes: This is called for block device requests in order to
- * mark some number of sectors as complete.
- *
- * We are guaranteeing that the request queue will be goosed
- * at some point during this call.
- * Notes: If cmd was requeued, upon return it will be a stale pointer.
- */
-static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
- int bytes, int requeue)
-{
- struct request_queue *q = cmd->device->request_queue;
- struct request *req = cmd->request;
-
- /*
- * If there are blocks left over at the end, set up the command
- * to queue the remainder of them.
- */
- if (blk_end_request(req, error, bytes)) {
- /* kill remainder if no retrys */
- if (error && scsi_noretry_cmd(cmd))
- blk_end_request_all(req, error);
- else {
- if (requeue) {
- /*
- * Bleah. Leftovers again. Stick the
- * leftovers in the front of the
- * queue, and goose the queue again.
- */
- scsi_release_buffers(cmd);
- scsi_requeue_command(q, cmd);
- cmd = NULL;
- }
- return cmd;
- }
- }
-
- /*
- * This will goose the queue request function at the end, so we don't
- * need to worry about launching another command.
- */
- __scsi_release_buffers(cmd, 0);
- scsi_next_command(cmd);
- return NULL;
-}
-
static inline unsigned int scsi_sgtable_index(unsigned short nents)
{
unsigned int index;
@@ -735,16 +675,9 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
*
* Returns: Nothing
*
- * Notes: This function is matched in terms of capabilities to
- * the function that created the scatter-gather list.
- * In other words, if there are no bounce buffers
- * (the normal case for most drivers), we don't need
- * the logic to deal with cleaning up afterwards.
- *
- * We must call scsi_end_request(). This will finish off
- * the specified number of sectors. If we are done, the
- * command block will be released and the queue function
- * will be goosed. If we are not done then we have to
+ * Notes: We will finish off the specified number of sectors. If we
+ * are done, the command block will be released and the queue
+ * function will be goosed. If we are not done then we have to
* figure out what to do next:
*
* a) We can call scsi_requeue_command(). The request
@@ -753,7 +686,7 @@ static int __scsi_error_from_host_byte(struct scsi_cmnd *cmd, int result)
* be used if we made forward progress, or if we want
* to switch from READ(10) to READ(6) for example.
*
- * b) We can call scsi_queue_insert(). The request will
+ * b) We can call __scsi_queue_insert(). The request will
* be put back on the queue and retried using the same
* command as before, possibly after a delay.
*
@@ -857,12 +790,25 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
}

/*
- * A number of bytes were successfully read. If there
- * are leftovers and there is some kind of error
- * (result != 0), retry the rest.
+ * If we finished all bytes in the request we are done now.
*/
- if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
- return;
+ if (!blk_end_request(req, error, good_bytes))
+ goto next_command;
+
+ /*
+ * Kill remainder if no retrys.
+ */
+ if (error && scsi_noretry_cmd(cmd)) {
+ blk_end_request_all(req, error);
+ goto next_command;
+ }
+
+ /*
+ * If there had been no error, but we have leftover bytes in the
+ * requeues just queue the command up again.
+ */
+ if (result == 0)
+ goto requeue;

error = __scsi_error_from_host_byte(cmd, result);

@@ -984,7 +930,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
switch (action) {
case ACTION_FAIL:
/* Give up and fail the remainder of the request */
- scsi_release_buffers(cmd);
if (!(req->cmd_flags & REQ_QUIET)) {
if (description)
scmd_printk(KERN_INFO, cmd, "%s\n",
@@ -994,12 +939,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
scsi_print_sense("", cmd);
scsi_print_command(cmd);
}
- if (blk_end_request_err(req, error))
- scsi_requeue_command(q, cmd);
- else
- scsi_next_command(cmd);
- break;
+ if (!blk_end_request_err(req, error))
+ goto next_command;
+ /*FALLTHRU*/
case ACTION_REPREP:
+ requeue:
/* Unprep the request and put it back at the head of the queue.
* A new command will be prepared and issued.
*/
@@ -1015,6 +959,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
__scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
break;
}
+ return;
+
+next_command:
+ __scsi_release_buffers(cmd, 0);
+ scsi_next_command(cmd);
}

static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:07 PM8/21/16
to
From: Thomas Huth <th...@redhat.com>

commit d23fac2b27d94aeb7b65536a50d32bfdc21fe01e upstream.

The SIAR and SDAR registers are available twice, one time as SPRs
780 / 781 (unprivileged, but read-only), and one time as the SPRs
796 / 797 (privileged, but read and write). The Linux kernel code
currently uses the unprivileged SPRs - while this is OK for reading,
writing to that register of course does not work.
Since the KVM code tries to write to this register, too (see the mtspr
in book3s_hv_rmhandlers.S), the contents of this register sometimes get
lost for the guests, e.g. during migration of a VM.
To fix this issue, simply switch to the privileged SPR numbers instead.

Signed-off-by: Thomas Huth <th...@redhat.com>
Acked-by: Paul Mackerras <pau...@ozlabs.org>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/powerpc/include/asm/reg.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 60c3169..d2a6651 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -677,13 +677,13 @@
#define SPRN_PMC6 792
#define SPRN_PMC7 793
#define SPRN_PMC8 794
-#define SPRN_SIAR 780
-#define SPRN_SDAR 781
#define SPRN_SIER 784
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
+#define SPRN_SIAR 796
+#define SPRN_SDAR 797

#define SPRN_PA6T_MMCR0 795
#define PA6T_MMCR0_EN0 0x0000000000000001UL
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:07 PM8/21/16
to
From: Dmitry Torokhov <dmitry....@gmail.com>

commit 510cccb5b0c8868a2b302a0ab524da7912da648b upstream.

The size of individual keymap in drivers/tty/vt/keyboard.c is NR_KEYS,
which is currently 256, whereas number of keys/buttons in input device (and
therefor in key_down) is much larger - KEY_CNT - 768, and that can cause
out-of-bound access when we do

sym = U(key_maps[0][k]);

with large 'k'.

To fix it we should not attempt iterating beyond smaller of NR_KEYS and
KEY_CNT.

Also while at it let's switch to for_each_set_bit() instead of open-coding
it.

Reported-by: Sasha Levin <sasha...@oracle.com>
Reviewed-by: Guenter Roeck <li...@roeck-us.net>
Cc: sta...@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry....@gmail.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/tty/vt/keyboard.c | 30 +++++++++---------------------
1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index a9af1b9a..1f6e096 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -371,34 +371,22 @@ static void to_utf8(struct vc_data *vc, uint c)

static void do_compute_shiftstate(void)
{
- unsigned int i, j, k, sym, val;
+ unsigned int k, sym, val;

shift_state = 0;
memset(shift_down, 0, sizeof(shift_down));

- for (i = 0; i < ARRAY_SIZE(key_down); i++) {
-
- if (!key_down[i])
+ for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
+ sym = U(key_maps[0][k]);
+ if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
continue;

- k = i * BITS_PER_LONG;
-
- for (j = 0; j < BITS_PER_LONG; j++, k++) {
-
- if (!test_bit(k, key_down))
- continue;
+ val = KVAL(sym);
+ if (val == KVAL(K_CAPSSHIFT))
+ val = KVAL(K_SHIFT);

- sym = U(key_maps[0][k]);
- if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
- continue;
-
- val = KVAL(sym);
- if (val == KVAL(K_CAPSSHIFT))
- val = KVAL(K_SHIFT);
-
- shift_down[val]++;
- shift_state |= (1 << val);
- }
+ shift_down[val]++;
+ shift_state |= BIT(val);
}
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:07 PM8/21/16
to
From: Lyude <cp...@redhat.com>

commit 255f0e7c418ad95a4baeda017ae6182ba9b3c423 upstream.

During boot, MST hotplugs are generally expected (even if no physical
hotplugging occurs) and result in DRM's connector topology changing.
This means that using num_connector from the current mode configuration
can lead to the number of connectors changing under us. This can lead to
some nasty scenarios in fbcon:

- We allocate an array to the size of dev->mode_config.num_connectors.
- MST hotplug occurs, dev->mode_config.num_connectors gets incremented.
- We try to loop through each element in the array using the new value
of dev->mode_config.num_connectors, and end up going out of bounds
since dev->mode_config.num_connectors is now larger then the array we
allocated.

fb_helper->connector_count however, will always remain consistent while
we do a modeset in fb_helper.

Note: This is just polish for 4.7, Dave Airlie's drm_connector
refcounting fixed these bugs for real. But it's good enough duct-tape
for stable kernel backporting, since backporting the refcounting
changes is way too invasive.

Signed-off-by: Lyude <cp...@redhat.com>
[danvet: Clarify why we need this. Also remove the now unused "dev"
local variable to appease gcc.]
Signed-off-by: Daniel Vetter <daniel...@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1463065021-18280-3-...@redhat.com
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/gpu/drm/drm_fb_helper.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index b78cbe7..93b7410 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1313,7 +1313,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
int n, int width, int height)
{
int c, o;
- struct drm_device *dev = fb_helper->dev;
struct drm_connector *connector;
struct drm_connector_helper_funcs *connector_funcs;
struct drm_encoder *encoder;
@@ -1334,7 +1333,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
if (modes[n] == NULL)
return best_score;

- crtcs = kzalloc(dev->mode_config.num_connector *
+ crtcs = kzalloc(fb_helper->connector_count *
sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
if (!crtcs)
return best_score;
@@ -1381,7 +1380,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
best_crtc = crtc;
best_score = score;
memcpy(best_crtcs, crtcs,
- dev->mode_config.num_connector *
+ fb_helper->connector_count *
sizeof(struct drm_fb_helper_crtc *));
}
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:08 PM8/21/16
to
From: Russell King <rmk+k...@armlinux.org.uk>

commit e2dfb4b880146bfd4b6aa8e138c0205407cebbaf upstream.

PTRACE_SETVFPREGS fails to properly mark the VFP register set to be
reloaded, because it undoes one of the effects of vfp_flush_hwstate().

Specifically vfp_flush_hwstate() sets thread->vfpstate.hard.cpu to
an invalid CPU number, but vfp_set() overwrites this with the original
CPU number, thereby rendering the hardware state as apparently "valid",
even though the software state is more recent.

Fix this by reverting the previous change.

Cc: <sta...@vger.kernel.org>
Fixes: 8130b9d7b9d8 ("ARM: 7308/1: vfp: flush thread hwstate before copying ptrace registers")
Acked-by: Will Deacon <will....@arm.com>
Tested-by: Simon Marchi <simon....@ericsson.com>
Signed-off-by: Russell King <rmk+k...@armlinux.org.uk>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/arm/kernel/ptrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 03deeff..4e2110d 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
if (ret)
return ret;

- vfp_flush_hwstate(thread);
thread->vfpstate.hard = new_vfp;
+ vfp_flush_hwstate(thread);

return 0;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:08 PM8/21/16
to
From: Laura Abbott <lab...@redhat.com>

commit b2e1c26f0b62531636509fbcb6dab65617ed8331 upstream.

glibc recently did a sync up (94e73c95d9b5 "elf.h: Sync with the gabi
webpage") that added a #define for EM_METAG but did not add relocations

This triggers build errors:

scripts/recordmcount.c: In function 'do_file':
scripts/recordmcount.c:466:28: error: 'R_METAG_ADDR32' undeclared (first use in this function)
case EM_METAG: reltype = R_METAG_ADDR32;
^~~~~~~~~~~~~~
scripts/recordmcount.c:466:28: note: each undeclared identifier is reported only once for each function it appears in
scripts/recordmcount.c:468:20: error: 'R_METAG_NONE' undeclared (first use in this function)
rel_type_nop = R_METAG_NONE;
^~~~~~~~~~~~

Work around this change with some more #ifdefery for the relocations.

Fedora Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1354034

Link: http://lkml.kernel.org/r/1468005530-14757-1-g...@redhat.com

Cc: sta...@vger.kernel.org # v3.9+
Cc: James Hogan <james...@imgtec.com>
Fixes: 00512bdd4573 ("metag: ftrace support")
Reported-by: Ross Burton <ross....@intel.com>
Signed-off-by: Laura Abbott <lab...@redhat.com>
Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
scripts/recordmcount.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index ee625e3..4f7d13d 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -33,10 +33,17 @@
#include <string.h>
#include <unistd.h>

+/*
+ * glibc synced up and added the metag number but didn't add the relocations.
+ * Work around this in a crude manner for now.
+ */
#ifndef EM_METAG
-/* Remove this when these make it to the standard system elf.h. */
#define EM_METAG 174
+#endif
+#ifndef R_METAG_ADDR32
#define R_METAG_ADDR32 2
+#endif
+#ifndef R_METAG_NONE
#define R_METAG_NONE 3
#endif

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:08 PM8/21/16
to
From: Hugh Dickins <hu...@google.com>

commit 7f556567036cb7f89aabe2f0954b08566b4efb53 upstream.

The well-spotted fallocate undo fix is good in most cases, but not when
fallocate failed on the very first page. index 0 then passes lend -1
to shmem_undo_range(), and that has two bad effects: (a) that it will
undo every fallocation throughout the file, unrestricted by the current
range; but more importantly (b) it can cause the undo to hang, because
lend -1 is treated as truncation, which makes it keep on retrying until
every page has gone, but those already fully instantiated will never go
away. Big thank you to xfstests generic/269 which demonstrates this.

Fixes: b9b4bb26af01 ("tmpfs: don't undo fallocate past its last page")
Signed-off-by: Hugh Dickins <hu...@google.com>
Signed-off-by: Linus Torvalds <torv...@linux-foundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
mm/shmem.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/mm/shmem.c b/mm/shmem.c
index e163e40..cc02b6c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1948,9 +1948,11 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
NULL);
if (error) {
/* Remove the !PageUptodate pages we added */
- shmem_undo_range(inode,
- (loff_t)start << PAGE_CACHE_SHIFT,
- ((loff_t)index << PAGE_CACHE_SHIFT) - 1, true);
+ if (index > start) {
+ shmem_undo_range(inode,
+ (loff_t)start << PAGE_CACHE_SHIFT,
+ ((loff_t)index << PAGE_CACHE_SHIFT) - 1, true);
+ }
goto undone;
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:08 PM8/21/16
to
From: Karl Heiss <khe...@gmail.com>

commit 635682a14427d241bab7bbdeebb48a7d7b91638e upstream.

A case can occur when sctp_accept() is called by the user during
a heartbeat timeout event after the 4-way handshake. Since
sctp_assoc_migrate() changes both assoc->base.sk and assoc->ep, the
bh_sock_lock in sctp_generate_heartbeat_event() will be taken with
the listening socket but released with the new association socket.
The result is a deadlock on any future attempts to take the listening
socket lock.

Note that this race can occur with other SCTP timeouts that take
the bh_lock_sock() in the event sctp_accept() is called.

BUG: soft lockup - CPU#9 stuck for 67s! [swapper:0]
...
RIP: 0010:[<ffffffff8152d48e>] [<ffffffff8152d48e>] _spin_lock+0x1e/0x30
RSP: 0018:ffff880028323b20 EFLAGS: 00000206
RAX: 0000000000000002 RBX: ffff880028323b20 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff880028323be0 RDI: ffff8804632c4b48
RBP: ffffffff8100bb93 R08: 0000000000000000 R09: 0000000000000000
R10: ffff880610662280 R11: 0000000000000100 R12: ffff880028323aa0
R13: ffff8804383c3880 R14: ffff880028323a90 R15: ffffffff81534225
FS: 0000000000000000(0000) GS:ffff880028320000(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00000000006df528 CR3: 0000000001a85000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 0, threadinfo ffff880616b70000, task ffff880616b6cab0)
Stack:
ffff880028323c40 ffffffffa01c2582 ffff880614cfb020 0000000000000000
<d> 0100000000000000 00000014383a6c44 ffff8804383c3880 ffff880614e93c00
<d> ffff880614e93c00 0000000000000000 ffff8804632c4b00 ffff8804383c38b8
Call Trace:
<IRQ>
[<ffffffffa01c2582>] ? sctp_rcv+0x492/0xa10 [sctp]
[<ffffffff8148c559>] ? nf_iterate+0x69/0xb0
[<ffffffff814974a0>] ? ip_local_deliver_finish+0x0/0x2d0
[<ffffffff8148c716>] ? nf_hook_slow+0x76/0x120
[<ffffffff814974a0>] ? ip_local_deliver_finish+0x0/0x2d0
[<ffffffff8149757d>] ? ip_local_deliver_finish+0xdd/0x2d0
[<ffffffff81497808>] ? ip_local_deliver+0x98/0xa0
[<ffffffff81496ccd>] ? ip_rcv_finish+0x12d/0x440
[<ffffffff81497255>] ? ip_rcv+0x275/0x350
[<ffffffff8145cfeb>] ? __netif_receive_skb+0x4ab/0x750
...

With lockdep debugging:

=====================================
[ BUG: bad unlock balance detected! ]
-------------------------------------
CslRx/12087 is trying to release lock (slock-AF_INET) at:
[<ffffffffa01bcae0>] sctp_generate_timeout_event+0x40/0xe0 [sctp]
but there are no more locks to release!

other info that might help us debug this:
2 locks held by CslRx/12087:
#0: (&asoc->timers[i]){+.-...}, at: [<ffffffff8108ce1f>] run_timer_softirq+0x16f/0x3e0
#1: (slock-AF_INET){+.-...}, at: [<ffffffffa01bcac3>] sctp_generate_timeout_event+0x23/0xe0 [sctp]

Ensure the socket taken is also the same one that is released by
saving a copy of the socket before entering the timeout event
critical section.

Signed-off-by: Karl Heiss <khe...@gmail.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
[wt: adjusted, 3.10 uses sctp_bh_unlock_sock() instead of bh_lock_sock()]

Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/sctp/sm_sideeffect.c | 42 +++++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8aab894..730914c 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -251,12 +251,13 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
int error;
struct sctp_transport *transport = (struct sctp_transport *) peer;
struct sctp_association *asoc = transport->asoc;
- struct net *net = sock_net(asoc->base.sk);
+ struct sock *sk = asoc->base.sk;
+ struct net *net = sock_net(sk);

/* Check whether a task is in the sock. */

- sctp_bh_lock_sock(asoc->base.sk);
- if (sock_owned_by_user(asoc->base.sk)) {
+ sctp_bh_lock_sock(sk);
+ if (sock_owned_by_user(sk)) {
SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);

/* Try again later. */
@@ -279,10 +280,10 @@ void sctp_generate_t3_rtx_event(unsigned long peer)
transport, GFP_ATOMIC);

if (error)
- asoc->base.sk->sk_err = -error;
+ sk->sk_err = -error;

out_unlock:
- sctp_bh_unlock_sock(asoc->base.sk);
+ sctp_bh_unlock_sock(sk);
sctp_transport_put(transport);
}

@@ -292,11 +293,12 @@ out_unlock:
static void sctp_generate_timeout_event(struct sctp_association *asoc,
sctp_event_timeout_t timeout_type)
{
- struct net *net = sock_net(asoc->base.sk);
+ struct sock *sk = asoc->base.sk;
+ struct net *net = sock_net(sk);
int error = 0;

- sctp_bh_lock_sock(asoc->base.sk);
- if (sock_owned_by_user(asoc->base.sk)) {
+ sctp_bh_lock_sock(sk);
+ if (sock_owned_by_user(sk)) {
SCTP_DEBUG_PRINTK("%s:Sock is busy: timer %d\n",
__func__,
timeout_type);
@@ -320,10 +322,10 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
(void *)timeout_type, GFP_ATOMIC);

if (error)
- asoc->base.sk->sk_err = -error;
+ sk->sk_err = -error;

out_unlock:
- sctp_bh_unlock_sock(asoc->base.sk);
+ sctp_bh_unlock_sock(sk);
sctp_association_put(asoc);
}

@@ -373,10 +375,11 @@ void sctp_generate_heartbeat_event(unsigned long data)
int error = 0;
struct sctp_transport *transport = (struct sctp_transport *) data;
struct sctp_association *asoc = transport->asoc;
- struct net *net = sock_net(asoc->base.sk);
+ struct sock *sk = asoc->base.sk;
+ struct net *net = sock_net(sk);

- sctp_bh_lock_sock(asoc->base.sk);
- if (sock_owned_by_user(asoc->base.sk)) {
+ sctp_bh_lock_sock(sk);
+ if (sock_owned_by_user(sk)) {
SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);

/* Try again later. */
@@ -397,10 +400,10 @@ void sctp_generate_heartbeat_event(unsigned long data)
transport, GFP_ATOMIC);

if (error)
- asoc->base.sk->sk_err = -error;
+ sk->sk_err = -error;

out_unlock:
- sctp_bh_unlock_sock(asoc->base.sk);
+ sctp_bh_unlock_sock(sk);
sctp_transport_put(transport);
}

@@ -411,10 +414,11 @@ void sctp_generate_proto_unreach_event(unsigned long data)
{
struct sctp_transport *transport = (struct sctp_transport *) data;
struct sctp_association *asoc = transport->asoc;
- struct net *net = sock_net(asoc->base.sk);
+ struct sock *sk = asoc->base.sk;
+ struct net *net = sock_net(sk);

- sctp_bh_lock_sock(asoc->base.sk);
- if (sock_owned_by_user(asoc->base.sk)) {
+ sctp_bh_lock_sock(sk);
+ if (sock_owned_by_user(sk)) {
SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__);

/* Try again later. */
@@ -435,7 +439,7 @@ void sctp_generate_proto_unreach_event(unsigned long data)
asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC);

out_unlock:
- sctp_bh_unlock_sock(asoc->base.sk);
+ sctp_bh_unlock_sock(sk);
sctp_association_put(asoc);
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:08 PM8/21/16
to
From: Javier Martinez Canillas <jav...@osg.samsung.com>

commit 29debab0a94035a390801d1f177d171d014b7765 upstream.

The devices don't have a name set, so makes dev_name() returns NULL which
makes harder to identify the devices that are causing issues, for example:

WARNING: CPU: 2 PID: 616 at drivers/base/core.c:251 device_release+0x8c/0x90
Device '(null)' does not have a release() function, it is broken and must be fixed.

And after setting the device name:

WARNING: CPU: 0 PID: 591 at drivers/base/core.c:251 device_release+0x8c/0x90
Device 's5p-mfc-l' does not have a release() function, it is broken and must be fixed.

Cc: <sta...@vger.kernel.org>
Fixes: 6e83e6e25eb4 ("[media] s5p-mfc: Fix kernel warning on memory init")
Signed-off-by: Javier Martinez Canillas <jav...@osg.samsung.com>
Tested-by: Marek Szyprowski <m.szyp...@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.naw...@samsung.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/media/platform/s5p-mfc/s5p_mfc.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 961d7ff..fe91623 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1012,6 +1012,8 @@ static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
mfc_err("Not enough memory\n");
return -ENOMEM;
}
+
+ dev_set_name(dev->mem_dev_l, "%s", "s5p-mfc-l");
device_initialize(dev->mem_dev_l);
of_property_read_u32_array(dev->plat_dev->dev.of_node,
"samsung,mfc-l", mem_info, 2);
@@ -1029,6 +1031,8 @@ static int s5p_mfc_alloc_memdevs(struct s5p_mfc_dev *dev)
mfc_err("Not enough memory\n");
return -ENOMEM;
}
+
+ dev_set_name(dev->mem_dev_r, "%s", "s5p-mfc-r");
device_initialize(dev->mem_dev_r);
of_property_read_u32_array(dev->plat_dev->dev.of_node,
"samsung,mfc-r", mem_info, 2);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:09 PM8/21/16
to
From: Joseph Salisbury <joseph.s...@canonical.com>

commit 7b9bc799a445aea95f64f15e0083cb19b5789abe upstream.

BugLink: http://bugs.launchpad.net/bugs/972604

Commit 09c9bae26b0d3c9472cb6ae45010460a2cee8b8d ("ath5k: add led pin
configuration for compaq c700 laptop") added a pin configuration for the Compaq
c700 laptop. However, the polarity of the led pin is reversed. It should be
red for wifi off and blue for wifi on, but it is the opposite. This bug was
reported in the following bug report:
http://pad.lv/972604

Fixes: 09c9bae26b0d3c9472cb6ae45010460a2cee8b8d ("ath5k: add led pin configuration for compaq c700 laptop")
Signed-off-by: Joseph Salisbury <joseph.s...@canonical.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Kalle Valo <kv...@qca.qualcomm.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/net/wireless/ath/ath5k/led.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index f77ef36..61879b1 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -77,7 +77,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath5k_led_devices) = {
/* HP Compaq CQ60-206US (ddre...@jumptv.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
/* HP Compaq C700 (nitro...@gmail.com) */
- { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
+ { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 0) },
/* LiteOn AR5BXB63 (mag...@salug.it) */
{ ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
/* IBM-specific AR5212 (all others) */
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:09 PM8/21/16
to
From: James Hogan <james...@imgtec.com>

commit c604cffa93478f8888bec62b23d6073dad03d43a upstream.

kvm_mips_handle_mapped_seg_tlb_fault() appears to map the guest page at
virtual address 0 to PFN 0 if the guest has created its own mapping
there. The intention is unclear, but it may have been an attempt to
protect the zero page from being mapped to anything but the comm page in
code paths you wouldn't expect from genuine commpage accesses (guest
kernel mode cache instructions on that address, hitting trapping
instructions when executing from that address with a coincidental TLB
eviction during the KVM handling, and guest user mode accesses to that
address).

Fix this to check for mappings exactly at KVM_GUEST_COMMPAGE_ADDR (it
may not be at address 0 since commit 42aa12e74e91 ("MIPS: KVM: Move
commpage so 0x0 is unmapped")), and set the corresponding EntryLo to be
interpreted as 0 (invalid).

Fixes: 858dd5d45733 ("KVM/MIPS32: MMU/TLB operations for the Guest.")
Signed-off-by: James Hogan <james...@imgtec.com>
Cc: Paolo Bonzini <pbon...@redhat.com>
Cc: "Radim Krčmář" <rkr...@redhat.com>
Cc: Ralf Baechle <ra...@linux-mips.org>
Cc: linux...@linux-mips.org
Cc: k...@vger.kernel.org
Signed-off-by: Radim Krčmář <rkr...@redhat.com>
[james...@imgtec.com: Backport to v3.10.y - v3.15.y]
Signed-off-by: James Hogan <james...@imgtec.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/mips/kvm/kvm_tlb.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c
index c777dd3..1e6b1f1 100644
--- a/arch/mips/kvm/kvm_tlb.c
+++ b/arch/mips/kvm/kvm_tlb.c
@@ -397,21 +397,27 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
struct kvm *kvm = vcpu->kvm;
pfn_t pfn0, pfn1;
+ long tlb_lo[2];

+ tlb_lo[0] = tlb->tlb_lo0;
+ tlb_lo[1] = tlb->tlb_lo1;

- if ((tlb->tlb_hi & VPN2_MASK) == 0) {
- pfn0 = 0;
- pfn1 = 0;
- } else {
- if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT) < 0)
- return -1;
+ /*
+ * The commpage address must not be mapped to anything else if the guest
+ * TLB contains entries nearby, or commpage accesses will break.
+ */
+ if (!((tlb->tlb_hi ^ KVM_GUEST_COMMPAGE_ADDR) &
+ VPN2_MASK & (PAGE_MASK << 1)))
+ tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >> PAGE_SHIFT) & 1] = 0;

- if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT) < 0)
- return -1;
+ if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT) < 0)
+ return -1;

- pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT];
- pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT];
- }
+ if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT) < 0)
+ return -1;
+
+ pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT];
+ pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT];

if (hpa0)
*hpa0 = pfn0 << PAGE_SHIFT;
@@ -423,9 +429,9 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
entryhi = (tlb->tlb_hi & VPN2_MASK) | (KVM_GUEST_KERNEL_MODE(vcpu) ?
kvm_mips_get_kernel_asid(vcpu) : kvm_mips_get_user_asid(vcpu));
entrylo0 = mips3_paddr_to_tlbpfn(pfn0 << PAGE_SHIFT) | (0x3 << 3) |
- (tlb->tlb_lo0 & MIPS3_PG_D) | (tlb->tlb_lo0 & MIPS3_PG_V);
+ (tlb_lo[0] & MIPS3_PG_D) | (tlb_lo[0] & MIPS3_PG_V);
entrylo1 = mips3_paddr_to_tlbpfn(pfn1 << PAGE_SHIFT) | (0x3 << 3) |
- (tlb->tlb_lo1 & MIPS3_PG_D) | (tlb->tlb_lo1 & MIPS3_PG_V);
+ (tlb_lo[1] & MIPS3_PG_D) | (tlb_lo[1] & MIPS3_PG_V);

#ifdef DEBUG
kvm_debug("@ %#lx tlb_lo0: 0x%08lx tlb_lo1: 0x%08lx\n", vcpu->arch.pc,
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:09 PM8/21/16
to
From: Richard Weinberger <ric...@nod.at>

commit 4946784bd3924b1374f05eebff2fd68660bae866 upstream.

When the volume resize operation shrinks a volume,
LEBs will be unmapped. Since unmapping will not erase these
LEBs immediately we have to wait for that operation to finish.
Otherwise in case of a power cut right after writing the new
volume table the UBI attach process can find more LEBs than the
volume table knows. This will render the UBI image unattachable.

Fix this issue by waiting for erase to complete and write the new
volume table afterward.

Cc: <sta...@vger.kernel.org>
Reported-by: Boris Brezillon <boris.b...@free-electrons.com>
Reviewed-by: Boris Brezillon <boris.b...@free-electrons.com>
Signed-off-by: Richard Weinberger <ric...@nod.at>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/mtd/ubi/vmt.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c
index 8330703..96131eb 100644
--- a/drivers/mtd/ubi/vmt.c
+++ b/drivers/mtd/ubi/vmt.c
@@ -534,13 +534,6 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
spin_unlock(&ubi->volumes_lock);
}

- /* Change volume table record */
- vtbl_rec = ubi->vtbl[vol_id];
- vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
- err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
- if (err)
- goto out_acc;
-
if (pebs < 0) {
for (i = 0; i < -pebs; i++) {
err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i);
@@ -558,6 +551,24 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
spin_unlock(&ubi->volumes_lock);
}

+ /*
+ * When we shrink a volume we have to flush all pending (erase) work.
+ * Otherwise it can happen that upon next attach UBI finds a LEB with
+ * lnum > highest_lnum and refuses to attach.
+ */
+ if (pebs < 0) {
+ err = ubi_wl_flush(ubi, vol_id, UBI_ALL);
+ if (err)
+ goto out_acc;
+ }
+
+ /* Change volume table record */
+ vtbl_rec = ubi->vtbl[vol_id];
+ vtbl_rec.reserved_pebs = cpu_to_be32(reserved_pebs);
+ err = ubi_change_vtbl_record(ubi, vol_id, &vtbl_rec);
+ if (err)
+ goto out_acc;
+
vol->reserved_pebs = reserved_pebs;
if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
vol->used_ebs = reserved_pebs;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 12:00:10 PM8/21/16
to
From: "Steven Rostedt (Red Hat)" <ros...@goodmis.org>

commit 70c8217acd4383e069fe1898bbad36ea4fcdbdcc upstream.

If a task uses a non constant string for the format parameter in
trace_printk(), then the trace_printk_fmt variable is set to NULL. This
variable is then saved in the __trace_printk_fmt section.

The function hold_module_trace_bprintk_format() checks to see if duplicate
formats are used by modules, and reuses them if so (saves them to the list
if it is new). But this function calls lookup_format() that does a strcmp()
to the value (which is now NULL) and can cause a kernel oops.

This wasn't an issue till 3debb0a9ddb ("tracing: Fix trace_printk() to print
when not using bprintk()") which added "__used" to the trace_printk_fmt
variable, and before that, the kernel simply optimized it out (no NULL value
was saved).

The fix is simply to handle the NULL pointer in lookup_format() and have the
caller ignore the value if it was NULL.

Link: http://lkml.kernel.org/r/1464769870-18344-1-git-...@intel.com

Reported-by: xingzhen <zhengj...@intel.com>
Acked-by: Namhyung Kim <namh...@kernel.org>
Fixes: 3debb0a9ddb ("tracing: Fix trace_printk() to print when not using bprintk()")
Cc: sta...@vger.kernel.org # v3.5+
Signed-off-by: Steven Rostedt <ros...@goodmis.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
kernel/trace/trace_printk.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index fdb23e8..7be4d67 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -38,6 +38,10 @@ struct trace_bprintk_fmt {
static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
{
struct trace_bprintk_fmt *pos;
+
+ if (!fmt)
+ return ERR_PTR(-EINVAL);
+
list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
if (!strcmp(pos->fmt, fmt))
return pos;
@@ -59,7 +63,8 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)
for (iter = start; iter < end; iter++) {
struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
if (tb_fmt) {
- *iter = tb_fmt->fmt;
+ if (!IS_ERR(tb_fmt))
+ *iter = tb_fmt->fmt;
continue;
}

--
2.8.0.rc2.1.gbe9624a
It is loading more messages.
0 new messages