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

[PATCH 3.10 000/180] 3.10.103-stable review

113 views
Skip to first unread message

Willy Tarreau

unread,
Aug 21, 2016, 11:32:16 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Willy Tarreau
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:32:21 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:32:31 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:32:36 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:32:36 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
From: Florian Westphal <f...@strlen.de>

commit a08e4e190b866579896c09af59b3bdca821da2cd upstream.

The target size includes the size of the xt_entry_target struct.

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 | 3 +++
1 file changed, 3 insertions(+)

diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 55b1e0c..cc34bb3 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -587,6 +587,9 @@ int xt_check_entry_offsets(const void *base,
return -EINVAL;

t = (void *)(e + target_offset);
+ if (t->u.target_size < sizeof(*t))
+ return -EINVAL;
+
if (target_offset + t->u.target_size > next_offset)
return -EINVAL;

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:32:50 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Raghava Aditya Renukunta, Martin K . Petersen, Willy Tarreau
From: Raghava Aditya Renukunta <RaghavaAdit...@microsemi.com>

commit 07beca2be24cc710461c0b131832524c9ee08910 upstream.

aac_fib_send has a special function case for initial commands during
driver initialization using wait < 0(pseudo sync mode). In this case,
the command does not sleep but rather spins checking for timeout.This
loop is calls cpu_relax() in an attempt to allow other processes/threads
to use the CPU, but this function does not relinquish the CPU and so the
command will hog the processor. This was observed in a KDUMP
"crashkernel" and that prevented the "command thread" (which is
responsible for completing the command from being timed out) from
starting because it could not get the CPU.

Fixed by replacing "cpu_relax()" call with "schedule()"
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 | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 6a0d362..addcd58 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -590,10 +590,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
return -EFAULT;
}
- /* We used to udelay() here but that absorbed
- * a CPU when a timeout occured. Not very
- * useful. */
- cpu_relax();
+ /*
+ * Allow other processes / CPUS to use core
+ */
+ schedule();
}
} else if (down_interruptible(&fibptr->event_wait)) {
/* Do nothing ... satisfy
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:32:52 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Andi Kleen, H . Peter Anvin, Willy Tarreau
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:33:03 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:33:12 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Linus Walleij, Joakim Bech, Herbert Xu, Willy Tarreau
From: Linus Walleij <linus....@linaro.org>

commit 19ced623db2fe91604d69f7d86b03144c5107739 upstream.

The hash buffer is really HASH_BLOCK_SIZE bytes, someone
must have thought that memmove takes n*u32 words by mistake.
Tests work as good/bad as before after this patch.

Cc: Joakim Bech <joaki...@linaro.org>
Cc: sta...@vger.kernel.org
Reported-by: David Binderman <linuxdev...@gmail.com>
Signed-off-by: Linus Walleij <linus....@linaro.org>
Signed-off-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/crypto/ux500/hash/hash_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
index 6789c16..cde4a6e 100644
--- a/drivers/crypto/ux500/hash/hash_core.c
+++ b/drivers/crypto/ux500/hash/hash_core.c
@@ -806,7 +806,7 @@ int hash_process_data(
&device_data->state);
memmove(req_ctx->state.buffer,
device_data->state.buffer,
- HASH_BLOCK_SIZE / sizeof(u32));
+ HASH_BLOCK_SIZE);
if (ret) {
dev_err(device_data->dev, "[%s] "
"hash_resume_state()"
@@ -858,7 +858,7 @@ int hash_process_data(

memmove(device_data->state.buffer,
req_ctx->state.buffer,
- HASH_BLOCK_SIZE / sizeof(u32));
+ HASH_BLOCK_SIZE);
if (ret) {
dev_err(device_data->dev, "[%s] "
"hash_save_state()"
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:33:16 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Mike Snitzer, Willy Tarreau
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:33:23 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Neil Horman, Bjorn Helgaas, stable@vger.kernel.org#v3.10+, Len Brown, Rafael J. Wysocki, Charles Williams, Willy Tarreau
From: Neil Horman <nho...@tuxdriver.com>

commit 3dc48af310709b85d07c8b0d3aa8f1ead02829d3 upstream.

This fixes the problem of acpiphp claiming slots that should be managed
by pciehp, which may keep ExpressCard slots from working.

The acpiphp driver claims PCIe slots unless the BIOS has granted us
control of PCIe native hotplug via _OSC. Prior to v3.10, the acpiphp
add method (add_bridge()) was always called *after* we had requested
native hotplug control with _OSC.

But after 3b63aaa70e ("PCI: acpiphp: Do not use ACPI PCI subdriver
mechanism"), which appeared in v3.10, acpiphp initialization is done
during the bus scan via the pcibios_add_bus() hook, and this happens
*before* we request native hotplug control.

Therefore, acpiphp doesn't know yet whether the BIOS will grant control,
and it claims slots that we should be handling with native hotplug.

This patch requests native hotplug control earlier, so we know whether
the BIOS granted it to us before we initialize acpiphp.

To avoid reintroducing the ASPM issue fixed by b8178f130e ('Revert
"PCI/ACPI: Request _OSC control before scanning PCI root bus"'), we run
_OSC earlier but defer the actual ASPM calls until after the bus scan is
complete.

Tested successfully by myself.

[bhelgaas: changelog, mark for stable]
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=60736
Signed-off-by: Neil Horman <nho...@tuxdriver.com>
Signed-off-by: Bjorn Helgaas <bhel...@google.com>
Acked-by: Yinghai Lu <yin...@kernel.org>
CC: sta...@vger.kernel.org # v3.10+
CC: Len Brown <le...@kernel.org>
CC: "Rafael J. Wysocki" <r...@sisk.pl>
[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/acpi/pci_root.c | 67 ++++++++++++++++++++++++++++---------------------
1 file changed, 38 insertions(+), 29 deletions(-)

diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index a02a91c..c5e3dd9 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -385,6 +385,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
int result;
struct acpi_pci_root *root;
u32 flags, base_flags;
+ bool no_aspm = false, clear_aspm = false;

root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
if (!root)
@@ -445,31 +446,10 @@ static int acpi_pci_root_add(struct acpi_device *device,
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
acpi_pci_osc_support(root, flags);

- /*
- * TBD: Need PCI interface for enumeration/configuration of roots.
- */
-
mutex_lock(&acpi_pci_root_lock);
list_add_tail(&root->node, &acpi_pci_roots);
mutex_unlock(&acpi_pci_root_lock);

- /*
- * Scan the Root Bridge
- * --------------------
- * Must do this prior to any attempt to bind the root device, as the
- * PCI namespace does not get created until this call is made (and
- * thus the root bridge's pci_dev does not exist).
- */
- root->bus = pci_acpi_scan_root(root);
- if (!root->bus) {
- printk(KERN_ERR PREFIX
- "Bus %04x:%02x not present in PCI namespace\n",
- root->segment, (unsigned int)root->secondary.start);
- result = -ENODEV;
- goto out_del_root;
- }
-
- /* Indicate support for various _OSC capabilities. */
if (pci_ext_cfg_avail())
flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
if (pcie_aspm_support_enabled()) {
@@ -483,7 +463,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (ACPI_FAILURE(status)) {
dev_info(&device->dev, "ACPI _OSC support "
"notification failed, disabling PCIe ASPM\n");
- pcie_no_aspm();
+ no_aspm = true;
flags = base_flags;
}
}
@@ -515,7 +495,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
* We have ASPM control, but the FADT indicates
* that it's unsupported. Clear it.
*/
- pcie_clear_aspm(root->bus);
+ clear_aspm = true;
}
} else {
dev_info(&device->dev,
@@ -524,7 +504,14 @@ static int acpi_pci_root_add(struct acpi_device *device,
acpi_format_exception(status), flags);
pr_info("ACPI _OSC control for PCIe not granted, "
"disabling ASPM\n");
- pcie_no_aspm();
+ /*
+ * We want to disable ASPM here, but aspm_disabled
+ * needs to remain in its state from boot so that we
+ * properly handle PCIe 1.1 devices. So we set this
+ * flag here, to defer the action until after the ACPI
+ * root scan.
+ */
+ no_aspm = true;
}
} else {
dev_info(&device->dev,
@@ -532,6 +519,33 @@ static int acpi_pci_root_add(struct acpi_device *device,
"(_OSC support mask: 0x%02x)\n", flags);
}

+ /*
+ * TBD: Need PCI interface for enumeration/configuration of roots.
+ */
+
+ /*
+ * Scan the Root Bridge
+ * --------------------
+ * Must do this prior to any attempt to bind the root device, as the
+ * PCI namespace does not get created until this call is made (and
+ * thus the root bridge's pci_dev does not exist).
+ */
+ root->bus = pci_acpi_scan_root(root);
+ if (!root->bus) {
+ dev_err(&device->dev,
+ "Bus %04x:%02x not present in PCI namespace\n",
+ root->segment, (unsigned int)root->secondary.start);
+ result = -ENODEV;
+ goto end;
+ }
+
+ if (clear_aspm) {
+ dev_info(&device->dev, "Disabling ASPM (FADT indicates it is unsupported)\n");
+ pcie_clear_aspm(root->bus);
+ }
+ if (no_aspm)
+ pcie_no_aspm();
+
pci_acpi_add_bus_pm_notifier(device, root->bus);
if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true);
@@ -548,11 +562,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
pci_bus_add_devices(root->bus);
return 1;

-out_del_root:
- mutex_lock(&acpi_pci_root_lock);
- list_del(&root->node);
- mutex_unlock(&acpi_pci_root_lock);
-
end:
kfree(root);
return result;
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:33:25 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, James Hogan, Paolo Bonzini, Radim Krčmář, Ralf Baechle, linux...@linux-mips.org, k...@vger.kernel.org, Willy Tarreau
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:33:35 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Ursula Braun, stable@vger.kernel.org#v2.6.37+, David S . Miller, Willy Tarreau
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:33:38 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Richard Weinberger, Greg Kroah-Hartman, Willy Tarreau
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:33:39 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Wei Fang, Martin K . Petersen, Willy Tarreau
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:33:43 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Lyude, Alex Deucher, Willy Tarreau
From: Lyude <cp...@redhat.com>

commit 14ff8d48f2235295dfb3117693008e367b49cdb5 upstream.

DRM_CONNECTOR_POLL_CONNECT only enables polling for connections, not
disconnections. Because of this, we end up losing hotplug polling for
analog connectors once they get connected.

Easy way to reproduce:
- Grab a machine with a radeon GPU and a VGA port
- Plug a monitor into the VGA port, wait for it to update the connector
from disconnected to connected
- Disconnect the monitor on VGA, a hotplug event is never sent for the
removal of the connector.

Originally, only using DRM_CONNECTOR_POLL_CONNECT might have been a good
idea since doing VGA polling can sometimes result in having to mess with
the DAC voltages to figure out whether or not there's actually something
there since VGA doesn't have HPD. Doing this would have the potential of
showing visible artifacts on the screen every time we ran a poll while a
VGA display was connected. Luckily, radeon_vga_detect() only resorts to
this sort of polling if the poll is forced, and DRM's polling helper
doesn't force it's polls.

Additionally, this removes some assignments to connector->polled that
weren't actually doing anything.

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

diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 1fbd38b..ea62810 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1691,7 +1691,6 @@ radeon_add_atom_connector(struct drm_device *dev,
1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -1889,8 +1888,10 @@ radeon_add_atom_connector(struct drm_device *dev,
}

if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
- if (i2c_bus->valid)
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ if (i2c_bus->valid) {
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
+ }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;

@@ -1962,7 +1963,6 @@ radeon_add_legacy_connector(struct drm_device *dev,
1);
/* no HPD on analog connectors */
radeon_connector->hpd.hpd = RADEON_HPD_NONE;
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
connector->interlace_allowed = true;
connector->doublescan_allowed = true;
break;
@@ -2047,10 +2047,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
}

if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
- if (i2c_bus->valid)
- connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+ if (i2c_bus->valid) {
+ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT;
+ }
} else
connector->polled = DRM_CONNECTOR_POLL_HPD;
+
connector->display_info.subpixel_order = subpixel_order;
drm_sysfs_connector_add(connector);
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:33:53 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Jeff Mahoney, Tyler Hicks, Greg Kroah-Hartman, Willy Tarreau
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:33:56 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Konstantin Neumoin, Denis V . Lunev, Michael S . Tsirkin, Willy Tarreau
From: Konstantin Neumoin <kneu...@virtuozzo.com>

commit 37cf99e08c6fb4dcea0f9ad2b13b6daa8c76a711 upstream.

The balloon has a special mechanism that is subscribed to the oom
notification which leads to deflation for a fixed number of pages.
The number is always fixed even when the balloon is fully deflated.
But leak_balloon did not expect that the pages to deflate will be more
than taken, and raise a "BUG" in balloon_page_dequeue when page list
will be empty.

So, the simplest solution would be to check that the number of releases
pages is less or equal to the number taken pages.

Cc: sta...@vger.kernel.org
Signed-off-by: Konstantin Neumoin <kneu...@virtuozzo.com>
Signed-off-by: Denis V. Lunev <d...@openvz.org>
CC: Michael S. Tsirkin <m...@redhat.com>
Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/virtio/virtio_balloon.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 7d7add5..148e8ea 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -177,6 +177,8 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num)
num = min(num, ARRAY_SIZE(vb->pfns));

mutex_lock(&vb->balloon_lock);
+ /* We can't release more pages than taken */
+ num = min(num, (size_t)vb->num_pages);
for (vb->num_pfns = 0; vb->num_pfns < num;
vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) {
page = balloon_page_dequeue(vb_dev_info);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:33:59 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Takashi Iwai, Greg Kroah-Hartman, Willy Tarreau
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:34:08 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Andrew Goodbody, Bin Liu, Greg Kroah-Hartman, Willy Tarreau
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:34:12 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Matthias Schiffer, Greg Kroah-Hartman, Willy Tarreau
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:34:25 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Theodore Ts'o, Willy Tarreau
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:34:32 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Cyril Bur, stable@vger.kernel.org#v3.9+, Michael Ellerman, Willy Tarreau
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:34:37 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Steve French, Steve French, Greg Kroah-Hartman, Willy Tarreau
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:34:39 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Charles (Chas) Williams, Eric Dumazet, Yuchung Cheng, Neal Cardwell, David S . Miller, Willy Tarreau
From: "Charles (Chas) Williams" <ciwi...@brocade.com>

commit 75ff39ccc1bd5d3c455b6822ab09e533c551f758 upstream.

From: Eric Dumazet <edum...@google.com>

Yue Cao claims that current host rate limiting of challenge ACKS
(RFC 5961) could leak enough information to allow a patient attacker
to hijack TCP sessions. He will soon provide details in an academic
paper.

This patch increases the default limit from 100 to 1000, and adds
some randomization so that the attacker can no longer hijack
sessions without spending a considerable amount of probes.

Based on initial analysis and patch from Linus.

Note that we also have per socket rate limiting, so it is tempting
to remove the host limit in the future.

v2: randomize the count of challenge acks per second, not the period.

Fixes: 282f23c6ee34 ("tcp: implement RFC 5961 3.2")
Reported-by: Yue Cao <yca...@ucr.edu>
Signed-off-by: Eric Dumazet <edum...@google.com>
Suggested-by: Linus Torvalds <torv...@linux-foundation.org>
Cc: Yuchung Cheng <ych...@google.com>
Cc: Neal Cardwell <ncar...@google.com>
Acked-by: Neal Cardwell <ncar...@google.com>
Acked-by: Yuchung Cheng <ych...@google.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
[ ciwillia: backport to 3.10-stable ]
Signed-off-by: Chas Williams <ciwi...@brocade.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/tcp_input.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f89087c..f3b15bb 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -68,6 +68,7 @@
#include <linux/module.h>
#include <linux/sysctl.h>
#include <linux/kernel.h>
+#include <linux/reciprocal_div.h>
#include <net/dst.h>
#include <net/tcp.h>
#include <net/inet_common.h>
@@ -87,7 +88,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 1;
EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);

/* rfc5961 challenge ack rate limiting */
-int sysctl_tcp_challenge_ack_limit = 100;
+int sysctl_tcp_challenge_ack_limit = 1000;

int sysctl_tcp_stdurg __read_mostly;
int sysctl_tcp_rfc1337 __read_mostly;
@@ -3288,12 +3289,19 @@ static void tcp_send_challenge_ack(struct sock *sk)
static u32 challenge_timestamp;
static unsigned int challenge_count;
u32 now = jiffies / HZ;
+ u32 count;

if (now != challenge_timestamp) {
+ u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1;
+
challenge_timestamp = now;
- challenge_count = 0;
+ ACCESS_ONCE(challenge_count) = half +
+ reciprocal_divide(prandom_u32(),
+ sysctl_tcp_challenge_ack_limit);
}
- if (++challenge_count <= sysctl_tcp_challenge_ack_limit) {
+ count = ACCESS_ONCE(challenge_count);
+ if (count > 0) {
+ ACCESS_ONCE(challenge_count) = count - 1;
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK);
tcp_send_ack(sk);
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:34:43 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, James Bottomley, James E . J . Bottomley, Martin K . Petersen, Jack Wang, Greg Kroah-Hartman, Willy Tarreau
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:34:56 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Ralf Baechle, James Hogan, Greg Kroah-Hartman, Willy Tarreau
From: Ralf Baechle <ra...@linux-mips.org>

commit d7de413475f443957a0c1d256e405d19b3a2cb22 upstream.

TASK_SIZE was defined as 0x7fff8000UL which for 64k pages is not a
multiple of the page size. Somewhere further down the math fails
such that executing an ELF binary fails.

Signed-off-by: Ralf Baechle <ra...@linux-mips.org>
Tested-by: Joshua Henderson <joshua.h...@microchip.com>
Cc: 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/processor.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 1470b7b..a7e7174 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -51,7 +51,7 @@ extern unsigned int vced_count, vcei_count;
* User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing.
*/
-#define TASK_SIZE 0x7fff8000UL
+#define TASK_SIZE 0x80000000UL
#endif

#ifdef __KERNEL__
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:35:00 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vegard Nossum, Theodore Ts'o, Aneesh Kumar K . V, Willy Tarreau
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:35:08 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Borislav Petkov, Linus Torvalds, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, Willy Tarreau
From: Borislav Petkov <b...@suse.de>

commit 1ead852dd88779eda12cb09cc894a03d9abfe1ec upstream.

Fix boot crash that triggers if this driver is built into a kernel and
run on non-AMD systems.

AMD northbridges users call amd_cache_northbridges() and it returns
a negative value to signal that we weren't able to cache/detect any
northbridges on the system.

At least, it should do so as all its callers expect it to do so. But it
does return a negative value only when kmalloc() fails.

Fix it to return -ENODEV if there are no NBs cached as otherwise, amd_nb
users like amd64_edac, for example, which relies on it to know whether
it should load or not, gets loaded on systems like Intel Xeons where it
shouldn't.

Reported-and-tested-by: Tony Battersby <to...@cybernetics.com>
Signed-off-by: Borislav Petkov <b...@suse.de>
Cc: <sta...@vger.kernel.org>
Cc: Linus Torvalds <torv...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <tg...@linutronix.de>
Link: http://lkml.kernel.org/r/1466097230-5333-2...@alien8.de
Link: https://lkml.kernel.org/r/5761BEB0...@cybernetics.com
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
arch/x86/kernel/amd_nb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 59554dc..e6a3b1e 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -67,8 +67,8 @@ int amd_cache_northbridges(void)
while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
i++;

- if (i == 0)
- return 0;
+ if (!i)
+ return -ENODEV;

nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL);
if (!nb)
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:35:19 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Iosif Harutyunov, Richard Weinberger, Willy Tarreau
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:35:37 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, David Howells, linux...@linux-mips.org, linux-secu...@vger.kernel.org, keyr...@vger.kernel.org, Ralf Baechle, Willy Tarreau
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:35:47 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Eric Dumazet, David S . Miller, Luis Henriques, Charles Williams, Willy Tarreau
From: Eric Dumazet <edum...@google.com>

commit 197c949e7798fbf28cfadc69d9ca0c2abbf93191 upstream.

Backport of this upstream commit into stable kernels :
89c22d8c3b27 ("net: Fix skb csum races when peeking")
exposed a bug in udp stack vs MSG_PEEK support, when user provides
a buffer smaller than skb payload.

In this case,
skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov);
returns -EFAULT.

This bug does not happen in upstream kernels since Al Viro did a great
job to replace this into :
skb_copy_and_csum_datagram_msg(skb, sizeof(struct udphdr), msg);
This variant is safe vs short buffers.

For the time being, instead reverting Herbert Xu patch and add back
skb->ip_summed invalid changes, simply store the result of
udp_lib_checksum_complete() so that we avoid computing the checksum a
second time, and avoid the problematic
skb_copy_and_csum_datagram_iovec() call.

This patch can be applied on recent kernels as it avoids a double
checksumming, then backported to stable kernels as a bug fix.

Signed-off-by: Eric Dumazet <edum...@google.com>
Acked-by: Herbert Xu <her...@gondor.apana.org.au>
Signed-off-by: David S. Miller <da...@davemloft.net>
[ luis: backported to 3.16: adjusted context ]
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>
---
net/ipv4/udp.c | 6 ++++--
net/ipv6/udp.c | 6 ++++--
2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 63b536b..68174e4 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1208,6 +1208,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
bool slow;

if (flags & MSG_ERRQUEUE)
@@ -1233,11 +1234,12 @@ try_again:
*/

if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}

- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
else {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 3046d02..d234e6f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -370,6 +370,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
int is_udp4;
bool slow;

@@ -401,11 +402,12 @@ try_again:
*/

if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}

- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
else {
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:35:50 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Daniele Palmas, Johan Hovold, Willy Tarreau
From: Daniele Palmas <dnl...@gmail.com>

commit 3c0415fa08548e3bc63ef741762664497ab187ed upstream.

This patch adds support for 0x1206 PID of Telit LE910.

Since the interfaces positions are the same than the ones for
0x1043 PID of Telit LE922, telit_le922_blacklist_usbcfg3 is used.

Signed-off-by: Daniele Palmas <dnl...@gmail.com>
Cc: stable <sta...@vger.kernel.org>
Signed-off-by: Johan Hovold <jo...@kernel.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/usb/serial/option.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index bcb6f5c..006a2a7 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -274,6 +274,7 @@ static void option_instat_callback(struct urb *urb);
#define TELIT_PRODUCT_LE922_USBCFG5 0x1045
#define TELIT_PRODUCT_LE920 0x1200
#define TELIT_PRODUCT_LE910 0x1201
+#define TELIT_PRODUCT_LE910_USBCFG4 0x1206

/* ZTE PRODUCTS */
#define ZTE_VENDOR_ID 0x19d2
@@ -1206,6 +1207,8 @@ static const struct usb_device_id option_ids[] = {
.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
+ .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:36:03 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Xiubo Li, Wei Tang, Zhang Zhuoyu, Paolo Bonzini, Willy Tarreau
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:36:15 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Yuchung Cheng, Neal Cardwell, David S . Miller, Willy Tarreau
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:36:17 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Dmitri Epshtein, Marcin Wojtas, stable@vger.kernel.org#v3.10+, David S . Miller, Willy Tarreau
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:36:25 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, dan.ca...@oracle.com, Mark Brown, Willy Tarreau
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:36:30 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Alex Deucher, Willy Tarreau
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:36:45 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, James Hogan, Paolo Bonzini, Radim Krčmář, Ralf Baechle, linux...@linux-mips.org, k...@vger.kernel.org, Willy Tarreau
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:36:53 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Nicolai Stange, Theodore Ts'o, Willy Tarreau
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:37:04 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Alan Stern, Greg Kroah-Hartman, Luis Henriques, Charles Williams, Willy Tarreau
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:37:08 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vignesh R, Linus Walleij, Willy Tarreau
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:37:12 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vegard Nossum, Darrick J . Wong, Theodore Ts'o, Willy Tarreau
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:37:18 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Chas Williams, Willy Tarreau
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:37:25 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Ping Cheng, Ping Cheng, Dmitry Torokhov, Willy Tarreau
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:37:35 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Nicolai Stange, Theodore Ts'o, Willy Tarreau
From: Nicolai Stange <nics...@gmail.com>

commit 935244cd54b86ca46e69bc6604d2adfb1aec2d42 upstream.

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

do {
...
offset += 1 << (sb->s_blocksize_bits - i);
i++;
} while (i <= sb->s_blocksize_bits + 1);

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

However, at the last iteration, that is at i == sb->s_blocksize_bits + 1,
the shift count becomes equal to (unsigned)-1 > 31 (c.f. C99 6.5.7(3))
and UBSAN reports

UBSAN: Undefined behaviour in fs/ext4/mballoc.c:2621:15
shift exponent 4294967295 is too large for 32-bit type 'int'
[...]
Call Trace:
[<ffffffff818c4d25>] dump_stack+0xbc/0x117
[<ffffffff818c4c69>] ? _atomic_dec_and_lock+0x169/0x169
[<ffffffff819411ab>] ubsan_epilogue+0xd/0x4e
[<ffffffff81941cac>] __ubsan_handle_shift_out_of_bounds+0x1fb/0x254
[<ffffffff81941ab1>] ? __ubsan_handle_load_invalid_value+0x158/0x158
[<ffffffff814b6dc1>] ? kmem_cache_alloc+0x101/0x390
[<ffffffff816fc13b>] ? ext4_mb_init+0x13b/0xfd0
[<ffffffff814293c7>] ? create_cache+0x57/0x1f0
[<ffffffff8142948a>] ? create_cache+0x11a/0x1f0
[<ffffffff821c2168>] ? mutex_lock+0x38/0x60
[<ffffffff821c23ab>] ? mutex_unlock+0x1b/0x50
[<ffffffff814c26ab>] ? put_online_mems+0x5b/0xc0
[<ffffffff81429677>] ? kmem_cache_create+0x117/0x2c0
[<ffffffff816fcc49>] ext4_mb_init+0xc49/0xfd0
[...]

Observe that the mentioned shift exponent, 4294967295, equals (unsigned)-1.

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 offset is never used again.

Silence UBSAN by introducing another variable, offset_incr, holding the
next increment to apply to offset 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 | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index b2e9940..4d73946 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2516,7 +2516,7 @@ int ext4_mb_init(struct super_block *sb)
{
struct ext4_sb_info *sbi = EXT4_SB(sb);
unsigned i, j;
- unsigned offset;
+ unsigned offset, offset_incr;
unsigned max;
int ret;

@@ -2545,11 +2545,13 @@ int ext4_mb_init(struct super_block *sb)

i = 1;
offset = 0;
+ offset_incr = 1 << (sb->s_blocksize_bits - 1);
max = sb->s_blocksize << 2;
do {
sbi->s_mb_offsets[i] = offset;
sbi->s_mb_maxs[i] = max;
- offset += 1 << (sb->s_blocksize_bits - i);
+ offset += offset_incr;
+ offset_incr = offset_incr >> 1;
max = max >> 1;
i++;
} while (i <= sb->s_blocksize_bits + 1);
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:37:54 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vegard Nossum, Jan Kara, Theodore Ts'o, Willy Tarreau
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:37:57 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Antonio Alecrim Jr, David S . Miller, Willy Tarreau
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:38:04 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Wolfgang Grandegger, Marc Kleine-Budde, Willy Tarreau
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:38:23 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Martin Willi, Johannes Berg, Greg Kroah-Hartman, Willy Tarreau
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:38:26 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Masami Hiramatsu, Alexander Shishkin, Andy Lutomirski, Arnaldo Carvalho de Melo, Borislav Petkov, Brian Gerst, Denys Vlasenko, H . Peter Anvin, Jiri Olsa, Linus Torvalds, Peter Zijlstra, Stephane Eranian, Thomas Gleixner, Vince Weaver, syst...@sourceware.org, sta...@vger.kernel.org#allthewaybacktoancientkernels, Ingo Molnar, Willy Tarreau
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:38:46 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Yoshihiro Shimoda, stable@vger.kernel.org#v3.1+, Felipe Balbi, Willy Tarreau
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:38:48 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Tom Goff, David S . Miller, Greg Kroah-Hartman, Willy Tarreau
From: Tom Goff <thoma...@ll.mit.edu>

commit 70a0dec45174c976c64b4c8c1d0898581f759948 upstream.

This fixes wrong-interface signaling on 32-bit platforms for entries
created when jiffies > 2^31 + MFC_ASSERT_THRESH.

Signed-off-by: Tom Goff <thoma...@ll.mit.edu>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
net/ipv4/ipmr.c | 4 +++-
net/ipv6/ip6mr.c | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index b31553d..89570f0 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -881,8 +881,10 @@ static struct mfc_cache *ipmr_cache_alloc(void)
{
struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);

- if (c)
+ if (c) {
+ c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
c->mfc_un.res.minvif = MAXVIFS;
+ }
return c;
}

diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 8d69df1..107f7528 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1077,6 +1077,7 @@ static struct mfc6_cache *ip6mr_cache_alloc(void)
struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
if (c == NULL)
return NULL;
+ c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
c->mfc_un.res.minvif = MAXMIFS;
return c;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:39:00 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:39:35 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Kangjie Lu, Kangjie Lu, Takashi Iwai, Willy Tarreau
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:39:47 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Alex Deucher, Andres Rodriguez, Alex Williamson, Willy Tarreau
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:01 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Tomáš Trnka, J . Bruce Fields, Willy Tarreau
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:52 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, James Hogan, Christopher Ferris, linux...@linux-mips.org, sta...@vger.kernel.org#2.6.30-, Ralf Baechle, Willy Tarreau
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:41:21 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Ricky Liang, Dmitry Torokhov, Willy Tarreau
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:41:38 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vineet Gupta, Willy Tarreau
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:41:44 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:42:09 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, James Hogan, Paolo Bonzini, Radim Krčmář, Ralf Baechle, k...@vger.kernel.org, linux...@linux-mips.org, sta...@vger.kernel.org#3.10.x-, Greg Kroah-Hartman, Willy Tarreau
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:42:51 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Luis de Bethencourt, Sta...@vger.kernel.org, Jonathan Cameron, Willy Tarreau
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:43:01 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Jason Gunthorpe, Doug Ledford, Willy Tarreau
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:43:22 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Paul Moore, Willy Tarreau
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:43:29 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Andy Lutomirski, Andy Lutomirski, Borislav Petkov, Brian Gerst, Dave Hansen, Denys Vlasenko, H . Peter Anvin, Linus Torvalds, Rik van Riel, Thomas Gleixner, Ingo Molnar, Greg Kroah-Hartman, Willy Tarreau
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:43:52 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Tim Gardner, Jayamohan Kallickal, Minh Tran, John Soni Jose, James E.J. Bottomley, Martin K . Petersen, Willy Tarreau
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:44:08 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:44:23 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Dave Jones, Pablo Neira Ayuso, Willy Tarreau
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:44:34 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Willy Tarreau
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:44:51 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Helge Deller, Willy Tarreau
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:45:03 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Raghava Aditya Renukunta, Martin K . Petersen, Willy Tarreau
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:45:16 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Guilherme G. Piccoli, stable@vger.kernel.org#v3.4+, Michael Ellerman, Willy Tarreau
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:45:36 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:45:47 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Takashi Iwai, Willy Tarreau
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:46:01 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Paolo Bonzini, Radim Krčmář, Greg Kroah-Hartman, Willy Tarreau
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:46:16 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vegard Nossum, David S . Miller, Willy Tarreau
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:46:20 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vladimir Davydov, Richard Weinberger, Paul E. McKenney, Andrew Morton, Linus Torvalds, Vinson Lee, Willy Tarreau
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:46:43 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Mark Brown, Sta...@vger.kernel.org, Jonathan Cameron, Willy Tarreau
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, 11:46:51 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Mark Brown, Sta...@vger.kernel.org, Jonathan Cameron, Willy Tarreau
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:47:07 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Yishai Hadas, Leon Romanovsky, Doug Ledford, Willy Tarreau
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:47:09 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, H. Peter Anvin, Willy Tarreau
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:47:29 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Luis Henriques, Johannes Berg, Willy Tarreau
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:47:48 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Simon Horman, David S . Miller, Willy Tarreau
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:48:02 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Paul Burton, Maciej W . Rozycki, James Hogan, linux...@linux-mips.org, Ralf Baechle, Greg Kroah-Hartman, Willy Tarreau
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:48:32 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, James Hogan, Paolo Bonzini, Radim Krčmář, Ralf Baechle, linux...@linux-mips.org, k...@vger.kernel.org, Willy Tarreau
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:48:36 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Soheil Hassas Yeganeh, David S . Miller, Willy Tarreau
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:48:56 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Florian Westphal, Pablo Neira Ayuso, Willy Tarreau
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:49:07 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Javier Martinez Canillas, Sylwester Nawrocki, Willy Tarreau
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:49:21 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Cameron Gutman, Dmitry Torokhov, Greg Kroah-Hartman, Willy Tarreau
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:49:29 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Dave Weinstein, Linus Torvalds, Willy Tarreau
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:49:53 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Bjørn Mork, David S . Miller, Charles Williams, Willy Tarreau
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:04 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Itai Handler, Patrik Jakobsson, Willy Tarreau
From: Itai Handler <itai_h...@hotmail.com>

commit 7ccca1d5bf69fdd1d3c5fcf84faf1659a6e0ad11 upstream.

Fix possible out of bounds read, by adding missing comma.
The code may read pass the end of the dsi_errors array
when the most significant bit (bit #31) in the intr_stat register
is set.
This bug has been detected using CppCheck (static analysis tool).

Cc: sta...@vger.kernel.org
Signed-off-by: Itai Handler <itai_h...@hotmail.com>
Signed-off-by: Patrik Jakobsson <patrik.r....@gmail.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
index 489ffd2..a3d37e4 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
@@ -85,7 +85,7 @@ static const char *const dsi_errors[] = {
"RX Prot Violation",
"HS Generic Write FIFO Full",
"LP Generic Write FIFO Full",
- "Generic Read Data Avail"
+ "Generic Read Data Avail",
"Special Packet Sent",
"Tearing Effect",
};
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:25 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Greg Kroah-Hartman, Dave Chinner, Willy Tarreau, Jiri Slaby
From: Greg Kroah-Hartman <gre...@linuxfoundation.org>

commit 032ac851fd42a62717032a594ac319f8a76b8a7d upstream.

Commit c66edeaf79bb6f0ca688ffec9ca50a61b7569984, which was a backport of
commit b1438f477934f5a4d5a44df26f3079a7575d5946 upstream, needed to have
the error value be positive, not negative, in order to work properly.

Reported-by: "Thomas D." <whi...@whissi.de>
Reported-by: Brad Spender <spe...@grsecurity.net>
Cc: Dave Chinner <da...@fromorbit.com>
Cc: Willy Tarreau <w...@1wt.eu>
Cc: Jiri Slaby <jsl...@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
fs/xfs/xfs_inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 130881e..06dec55 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2779,7 +2779,7 @@ xfs_iflush(
*/
error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK,
0);
- if (error == -EAGAIN) {
+ if (error == EAGAIN) {
xfs_ifunlock(ip);
return error;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:45 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Vegard Nossum, Jens Axboe, Willy Tarreau
From: Vegard Nossum <vegard...@oracle.com>

commit 77da160530dd1dc94f6ae15a981f24e5f0021e84 upstream.

I got a KASAN report of use-after-free:

==================================================================
BUG: KASAN: use-after-free in klist_iter_exit+0x61/0x70 at addr ffff8800b6581508
Read of size 8 by task trinity-c1/315
=============================================================================
BUG kmalloc-32 (Not tainted): kasan: bad access detected
-----------------------------------------------------------------------------

Disabling lock debugging due to kernel taint
INFO: Allocated in disk_seqf_start+0x66/0x110 age=144 cpu=1 pid=315
___slab_alloc+0x4f1/0x520
__slab_alloc.isra.58+0x56/0x80
kmem_cache_alloc_trace+0x260/0x2a0
disk_seqf_start+0x66/0x110
traverse+0x176/0x860
seq_read+0x7e3/0x11a0
proc_reg_read+0xbc/0x180
do_loop_readv_writev+0x134/0x210
do_readv_writev+0x565/0x660
vfs_readv+0x67/0xa0
do_preadv+0x126/0x170
SyS_preadv+0xc/0x10
do_syscall_64+0x1a1/0x460
return_from_SYSCALL_64+0x0/0x6a
INFO: Freed in disk_seqf_stop+0x42/0x50 age=160 cpu=1 pid=315
__slab_free+0x17a/0x2c0
kfree+0x20a/0x220
disk_seqf_stop+0x42/0x50
traverse+0x3b5/0x860
seq_read+0x7e3/0x11a0
proc_reg_read+0xbc/0x180
do_loop_readv_writev+0x134/0x210
do_readv_writev+0x565/0x660
vfs_readv+0x67/0xa0
do_preadv+0x126/0x170
SyS_preadv+0xc/0x10
do_syscall_64+0x1a1/0x460
return_from_SYSCALL_64+0x0/0x6a

CPU: 1 PID: 315 Comm: trinity-c1 Tainted: G B 4.7.0+ #62
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
ffffea0002d96000 ffff880119b9f918 ffffffff81d6ce81 ffff88011a804480
ffff8800b6581500 ffff880119b9f948 ffffffff8146c7bd ffff88011a804480
ffffea0002d96000 ffff8800b6581500 fffffffffffffff4 ffff880119b9f970
Call Trace:
[<ffffffff81d6ce81>] dump_stack+0x65/0x84
[<ffffffff8146c7bd>] print_trailer+0x10d/0x1a0
[<ffffffff814704ff>] object_err+0x2f/0x40
[<ffffffff814754d1>] kasan_report_error+0x221/0x520
[<ffffffff8147590e>] __asan_report_load8_noabort+0x3e/0x40
[<ffffffff83888161>] klist_iter_exit+0x61/0x70
[<ffffffff82404389>] class_dev_iter_exit+0x9/0x10
[<ffffffff81d2e8ea>] disk_seqf_stop+0x3a/0x50
[<ffffffff8151f812>] seq_read+0x4b2/0x11a0
[<ffffffff815f8fdc>] proc_reg_read+0xbc/0x180
[<ffffffff814b24e4>] do_loop_readv_writev+0x134/0x210
[<ffffffff814b4c45>] do_readv_writev+0x565/0x660
[<ffffffff814b8a17>] vfs_readv+0x67/0xa0
[<ffffffff814b8de6>] do_preadv+0x126/0x170
[<ffffffff814b92ec>] SyS_preadv+0xc/0x10

This problem can occur in the following situation:

open()
- pread()
- .seq_start()
- iter = kmalloc() // succeeds
- seqf->private = iter
- .seq_stop()
- kfree(seqf->private)
- pread()
- .seq_start()
- iter = kmalloc() // fails
- .seq_stop()
- class_dev_iter_exit(seqf->private) // boom! old pointer

As the comment in disk_seqf_stop() says, stop is called even if start
failed, so we need to reinitialise the private pointer to NULL when seq
iteration stops.

An alternative would be to set the private pointer to NULL when the
kmalloc() in disk_seqf_start() fails.

Cc: sta...@vger.kernel.org
Signed-off-by: Vegard Nossum <vegard...@oracle.com>
Acked-by: Tejun Heo <t...@kernel.org>
Signed-off-by: Jens Axboe <ax...@fb.com>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
block/genhd.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/block/genhd.c b/block/genhd.c
index b09f5fc..7af2f6a 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -829,6 +829,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v)
if (iter) {
class_dev_iter_exit(iter);
kfree(iter);
+ seqf->private = NULL;
}
}

--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:50:58 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Alexey Brodkin, Alexey Brodkin, Vineet Gupta, Willy Tarreau
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, 11:51:04 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Russell King, Willy Tarreau
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, 11:51:20 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Taras Kondratiuk, Ulf Hansson, Willy Tarreau
From: Taras Kondratiuk <tako...@cisco.com>

commit f68381a70bb2b26c31b13fdaf67c778f92fd32b4 upstream.

The code that fills packed command header assumes that CPU runs in
little-endian mode. Hence the header is malformed in big-endian mode
and causes MMC data transfer errors:

[ 563.200828] mmcblk0: error -110 transferring data, sector 2048, nr 8, cmd response 0x900, card status 0xc40
[ 563.219647] mmcblk0: packed cmd failed, nr 2, sectors 16, failure index: -1

Convert header data to LE.

Signed-off-by: Taras Kondratiuk <tako...@cisco.com>
Fixes: ce39f9d17c14 ("mmc: support packed write command for eMMC4.5 devices")
Cc: <sta...@vger.kernel.org>
Signed-off-by: Ulf Hansson <ulf.h...@linaro.org>
Signed-off-by: Willy Tarreau <w...@1wt.eu>
---
drivers/mmc/card/block.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c6bf235..a2863b7 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1582,8 +1582,8 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,

packed_cmd_hdr = packed->cmd_hdr;
memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr));
- packed_cmd_hdr[0] = (packed->nr_entries << 16) |
- (PACKED_CMD_WR << 8) | PACKED_CMD_VER;
+ packed_cmd_hdr[0] = cpu_to_le32((packed->nr_entries << 16) |
+ (PACKED_CMD_WR << 8) | PACKED_CMD_VER);
hdr_blocks = mmc_large_sector(card) ? 8 : 1;

/*
@@ -1597,14 +1597,14 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
((brq->data.blocks * brq->data.blksz) >=
card->ext_csd.data_tag_unit_size);
/* Argument of CMD23 */
- packed_cmd_hdr[(i * 2)] =
+ packed_cmd_hdr[(i * 2)] = cpu_to_le32(
(do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) |
(do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) |
- blk_rq_sectors(prq);
+ blk_rq_sectors(prq));
/* Argument of CMD18 or CMD25 */
- packed_cmd_hdr[((i * 2)) + 1] =
+ packed_cmd_hdr[((i * 2)) + 1] = cpu_to_le32(
mmc_card_blockaddr(card) ?
- blk_rq_pos(prq) : blk_rq_pos(prq) << 9;
+ blk_rq_pos(prq) : blk_rq_pos(prq) << 9);
packed->blocks += blk_rq_sectors(prq);
i++;
}
--
2.8.0.rc2.1.gbe9624a

Willy Tarreau

unread,
Aug 21, 2016, 11:51:35 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Erez Shitrit, Leon Romanovsky, Doug Ledford, Willy Tarreau
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, 11:51:47 AM8/21/16
to linux-...@vger.kernel.org, sta...@vger.kernel.org, Joseph Salisbury, Kalle Valo, Willy Tarreau
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

It is loading more messages.
0 new messages