3.14.51-stable review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 3.14.51-stable review
This is the start of the stable review cycle for the 3.14.51 release. There are 44 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun Aug 16 17:43:53 UTC 2015. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.51-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 3.14.51-rc1
Michal Hocko <[email protected]>
mm, vmscan: Do not wait for page writeback for GFP_NOFS allocations
NeilBrown <[email protected]>
md/bitmap: return an error when bitmap superblock is corrupt.
Al Viro <[email protected]>
path_openat(): fix double fput()
Paolo Bonzini <[email protected]>
kvm: x86: fix kvm_apic_has_events to check for NULL pointer
Miklos Szeredi <[email protected]>
dcache: don't need rcu in shrink_dentry_list()
Al Viro <[email protected]>
more graceful recovery in umount_collect()
Al Viro <[email protected]>
don't remove from shrink list in select_collect()
Al Viro <[email protected]>
dentry_kill(): don't try to remove from shrink list
Al Viro <[email protected]>
expand the call of dentry_lru_del() in dentry_kill()
Al Viro <[email protected]>
new helper: dentry_free()
Al Viro <[email protected]>
fold try_prune_one_dentry()
Al Viro <[email protected]>
fold d_kill() and d_free()
Amanieu d'Antras <[email protected]>
signal: fix information leak in copy_siginfo_from_user32
Amanieu d'Antras <[email protected]>
signal: fix information leak in copy_siginfo_to_user
Amanieu d'Antras <[email protected]>
signalfd: fix information leak in signalfd_copyinfo
Al Viro <[email protected]>
sg_start_req(): make sure that there's not too many elements in iovec
NeilBrown <[email protected]>
md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies
Michael S. Tsirkin <[email protected]>
PCI: Restore PCI_MSIX_FLAGS_BIRMASK definition
Joseph Qi <[email protected]>
ocfs2: fix BUG in ocfs2_downconvert_thread_do_work()
Marcus Gelderie <[email protected]>
ipc: modify message queue accounting to not take kernel data structures into account
Dan Carpenter <[email protected]>
ALSA: hda - fix cs4210_spdif_automute()
Nicholas Bellinger <[email protected]>
iscsi-target: Fix iscsit_start_kthreads failure OOPs
Roger Quadros <[email protected]>
ARM: OMAP2+: hwmod: Fix _wait_target_ready() for hwmods without sysc
Ilya Dryomov <[email protected]>
rbd: fix copyup completion race
Herbert Xu <[email protected]>
crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer
Marek Marczykowski-Górecki <[email protected]>
xen/gntdevt: Fix race condition in gntdev_release()
Andy Lutomirski <[email protected]>
x86/xen: Probe target addresses in set_aliased_prot() before the hypercall
Axel Lin <[email protected]>
ASoC: pcm1681: Fix setting de-emphasis sampling rate selection
David S. Miller <[email protected]>
sparc64: Fix userspace FPU register corruptions.
Arnd Bergmann <[email protected]>
ARM: sunxi: fix build for THUMB2_KERNEL
Benjamin Randazzo <[email protected]>
md: use kzalloc() when bitmap is disabled
Mimi Zohar <[email protected]>
ima: extend "mask" policy matching support
Mimi Zohar <[email protected]>
ima: add support for new "euid" policy condition
Dirk Behme <[email protected]>
USB: sierra: add 1199:68AB device ID
Mathias Nyman <[email protected]>
xhci: fix off by one error in TRB DMA address boundary check
Brian King <[email protected]>
ipr: Fix invalid array indexing for HRRQ
Brian King <[email protected]>
ipr: Fix incorrect trace indexing
Brian King <[email protected]>
ipr: Fix locking for unit attention handling
Alex Deucher <[email protected]>
drm/radeon/combios: add some validation of lvds values
Jan Kara <[email protected]>
fsnotify: fix oops in fsnotify_clear_marks_by_group_flags()
David Daney <[email protected]>
MIPS: Make set_pte() SMP safe.
Felix Fietkau <[email protected]>
MIPS: Fix sched_getaffinity with MT FPAFF enabled
James Hogan <[email protected]>
MIPS: Malta: Don't reinitialise RTC
Arnd Bergmann <[email protected]>
ARM: realview: fix sparsemem build
-------------
Diffstat:
Documentation/ABI/testing/ima_policy | 6 +- Makefile | 4 +- arch/arm/include/asm/smp.h | 1 + arch/arm/mach-omap2/omap_hwmod.c | 24 +- arch/arm/mach-realview/include/mach/memory.h | 2 + arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/headsmp.S | 9 - arch/arm/mach-sunxi/platsmp.c | 2 +- arch/arm64/kernel/signal32.c | 5 +- arch/mips/include/asm/pgtable.h | 31 +++ arch/mips/kernel/mips-mt-fpaff.c | 5 +- arch/mips/kernel/signal32.c | 2 - arch/mips/mti-malta/malta-time.c | 15 +- arch/powerpc/kernel/signal_32.c | 2 - arch/sparc/include/asm/visasm.h | 16 +- arch/sparc/lib/NG4memcpy.S | 5 +- arch/sparc/lib/VISsave.S | 67 +----- arch/sparc/lib/ksyms.c | 4 - arch/x86/kvm/lapic.h | 2 +- arch/x86/xen/enlighten.c | 40 ++++ drivers/block/rbd.c | 22 +- drivers/crypto/ixp4xx_crypto.c | 1 - drivers/gpu/drm/radeon/radeon_combios.c | 7 +- drivers/md/bitmap.c | 2 + drivers/md/md.c | 3 +- drivers/md/raid1.c | 10 +- drivers/scsi/ipr.c | 28 ++- drivers/scsi/ipr.h | 1 + drivers/scsi/sg.c | 3 + drivers/target/iscsi/iscsi_target.c | 18 +- drivers/target/iscsi/iscsi_target_core.h | 1 + drivers/target/iscsi/iscsi_target_login.c | 43 ++-- drivers/target/iscsi/iscsi_target_login.h | 3 +- drivers/target/iscsi/iscsi_target_nego.c | 34 ++- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/serial/sierra.c | 1 + drivers/xen/gntdev.c | 2 + fs/dcache.c | 316 +++++++++------------------ fs/namei.c | 3 +- fs/notify/mark.c | 30 ++- fs/ocfs2/dlmglue.c | 10 +- fs/signalfd.c | 5 +- include/linux/dcache.h | 2 + include/uapi/linux/pci_regs.h | 1 + ipc/mqueue.c | 5 - kernel/signal.c | 7 +- mm/vmscan.c | 14 +- security/integrity/ima/ima_policy.c | 47 +++- sound/pci/hda/patch_cirrus.c | 4 +- sound/soc/codecs/pcm1681.c | 2 +- 50 files changed, 439 insertions(+), 432 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/44 ARM: realview: fix sparsemem build
3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit dd94d3558947756b102b1487911acd925224a38c upstream.
Commit b713aa0b15 "ARM: fix asm/memory.h build error" broke some configurations on mach-realview with sparsemem enabled, which is missing a definition of PHYS_OFFSET:
arch/arm/include/asm/memory.h:268:42: error: 'PHYS_OFFSET' undeclared (first use in this function)
#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))arch/arm/include/asm/dma-mapping.h:104:9: note: in expansion of macro 'PHYS_PFN_OFFSET'
return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
An easy workaround is for realview to define PHYS_OFFSET itself, in the same way we define it for platforms that don't have a private __virt_to_phys function.
--- arch/arm/mach-realview/include/mach/memory.h | 2 ++ 1 file changed, 2 insertions(+)
arch/arm/mach-realview/include/mach/memory.h +2 -0
@@ -56,6 +56,8 @@#define PAGE_OFFSET1 (PAGE_OFFSET + 0x10000000)#define PAGE_OFFSET2 (PAGE_OFFSET + 0x30000000) +#define PHYS_OFFSET PLAT_PHYS_OFFSET +#define __phys_to_virt (phys) \ ((phys) >= 0x80000000 ? (phys) - 0x80000000 + PAGE_OFFSET2 : \ (phys) >= 0x20000000 ? (phys) - 0x20000000 + PAGE_OFFSET1 : \
Greg Kroah-Hartman
maintainerPATCH 2/44 MIPS: Malta: Dont reinitialise RTC
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hogan <[email protected]>
commit 106eccb4d20f35ebc58ff2286c170d9e79c5ff68 upstream.
On Malta, since commit a87ea88d8f6c ("MIPS: Malta: initialise the RTC at boot"), the RTC is reinitialised and forced into binary coded decimal (BCD) mode during init, even if the bootloader has already initialised it, and may even have already put it into binary mode (as YAMON does). This corrupts the current time, can result in the RTC seconds being an invalid BCD (e.g. 0x1a..0x1f) for up to 6 seconds, as well as confusing YAMON for a while after reset, enough for it to report timeouts when attempting to load from TFTP (it actually uses the RTC in that code).
Therefore only initialise the RTC to the extent that is necessary so that Linux avoids interfering with the bootloader setup, while also allowing it to estimate the CPU frequency without hanging, without a bootloader necessarily having done anything with the RTC (for example when the kernel is loaded via EJTAG).
The divider control is configured for a 32KHZ reference clock if necessary, and the SET bit of the RTC_CONTROL register is cleared if necessary without changing any other bits (this bit will be set when coming out of reset if the battery has been disconnected).
Patchwork: https://patchwork.linux-mips.org/patch/10739/
--- arch/mips/mti-malta/malta-time.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
arch/mips/mti-malta/malta-time.c +9 -6
@@ -168,14 +168,17 @@ unsigned int get_c0_compare_int(void)static void __init init_rtc (void ) { -/* stop the clock whilst setting it up */ -CMOS_WRITE (RTC_SET |RTC_24H ,RTC_CONTROL ); +unsigned char freq, ctrl; -/* 32KHz time base */ -CMOS_WRITE (RTC_REF_CLCK_32KHZ ,RTC_FREQ_SELECT ); +/* Set 32KHz time base if not already set */ + freq =CMOS_READ (RTC_FREQ_SELECT ); +if ((freq &RTC_DIV_CTL ) !=RTC_REF_CLCK_32KHZ ) +CMOS_WRITE (RTC_REF_CLCK_32KHZ ,RTC_FREQ_SELECT ); -/* start the clock */ -CMOS_WRITE (RTC_24H ,RTC_CONTROL ); +/* Ensure SET bit is clear so RTC can run */ + ctrl =CMOS_READ (RTC_CONTROL ); +if (ctrl &RTC_SET ) +CMOS_WRITE (ctrl & ~RTC_SET ,RTC_CONTROL ); }void __init plat_time_init (void )
Greg Kroah-Hartman
maintainerPATCH 3/44 MIPS: Fix sched_getaffinity with MT FPAFF enabled
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
commit 1d62d737555e1378eb62a8bba26644f7d97139d2 upstream.
p->thread.user_cpus_allowed is zero-initialized and is only filled on the first sched_setaffinity call.
To avoid adding overhead in the task initialization codepath, simply OR the returned mask in sched_getaffinity with p->cpus_allowed.
Patchwork: https://patchwork.linux-mips.org/patch/10740/
--- arch/mips/kernel/mips-mt-fpaff.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/mips/kernel/mips-mt-fpaff.c +3 -2
@@ -154,7 +154,7 @@ asmlinkage long mipsmt_sys_sched_getaffi unsigned long __user *user_mask_ptr) {unsigned int real_len; -cpumask_t mask; +cpumask_t allowed, mask;int retval;struct task_struct *p;
@@ -173,7 +173,8 @@ asmlinkage long mipsmt_sys_sched_getaffiif (retval) goto out_unlock; -cpumask_and (&mask, &p->thread.user_cpus_allowed, cpu_possible_mask); +cpumask_or (&allowed, &p->thread.user_cpus_allowed, &p->cpus_allowed); +cpumask_and (&mask, &allowed, cpu_active_mask); out_unlock:read_unlock (&tasklist_lock);
Greg Kroah-Hartman
maintainerPATCH 4/44 MIPS: Make set_pte() SMP safe.
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Daney <[email protected]>
commit 46011e6ea39235e4aca656673c500eac81a07a17 upstream.
On MIPS the GLOBAL bit of the PTE must have the same value in any aligned pair of PTEs. These pairs of PTEs are referred to as "buddies". In a SMP system is is possible for two CPUs to be calling set_pte() on adjacent PTEs at the same time. There is a race between setting the PTE and a different CPU setting the GLOBAL bit in its buddy PTE.
This race can be observed when multiple CPUs are executing vmap()/vfree() at the same time.
Make setting the buddy PTE's GLOBAL bit an atomic operation to close the race condition.
The case of CONFIG_64BIT_PHYS_ADDR && CONFIG_CPU_MIPS32 is *not* handled.
Patchwork: https://patchwork.linux-mips.org/patch/10835/
--- arch/mips/include/asm/pgtable.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
arch/mips/include/asm/pgtable.h +31 -0
@@ -150,8 +150,39 @@ static inline void set_pte(pte_t *ptep,* Make sure the buddy is global too (if it's !none, * it better already be global) */ +#ifdef CONFIG_SMP +/* +* For SMP, multiple CPUs can race, so we need to do +* this atomically. +*/ +#ifdef CONFIG_64BIT +#define LL_INSN "lld" +#define SC_INSN "scd" +#else /* CONFIG_32BIT */ +#define LL_INSN "ll" +#define SC_INSN "sc" +#endif +unsigned long page_global = _PAGE_GLOBAL; +unsigned long tmp; + + __asm__ __volatile__ ( +" .set push\n" +" .set noreorder\n" +"1: " LL_INSN " %[tmp], %[buddy]\n" +" bnez %[tmp], 2f\n" +" or %[tmp], %[tmp], %[global]\n" +" " SC_INSN " %[tmp], %[buddy]\n" +" beqz %[tmp], 1b\n" +" nop\n" +"2:\n" +" .set pop" + : [buddy]"+m" (buddy->pte), + [tmp]"=&r" (tmp) + : [global]"r" (page_global)); +#else /* !CONFIG_SMP */ if (pte_none (*buddy))pte_val (*buddy) =pte_val (*buddy) | _PAGE_GLOBAL; +#endif /* CONFIG_SMP */ }#endif }
Greg Kroah-Hartman
maintainerPATCH 5/44 fsnotify: fix oops in fsnotify_clear_marks_by_group_flags()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <[email protected]>
commit 8f2f3eb59dff4ec538de55f2e0592fec85966aab upstream.
fsnotify_clear_marks_by_group_flags() can race with fsnotify_destroy_marks() so that when fsnotify_destroy_mark_locked() drops mark_mutex, a mark from the list iterated by fsnotify_clear_marks_by_group_flags() can be freed and thus the next entry pointer we have cached may become stale and we dereference free memory.
Fix the problem by first moving marks to free to a special private list and then always free the first entry in the special list. This method is safe even when entries from the list can disappear once we drop the lock.
--- fs/notify/mark.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-)
fs/notify/mark.c +25 -5
@@ -293,16 +293,36 @@ void fsnotify_clear_marks_by_group_flags unsigned int flags) {struct fsnotify_mark *lmark, *mark; +LIST_HEAD (to_free); +/* +* We have to be really careful here. Anytime we drop mark_mutex, e.g. +* fsnotify_clear_marks_by_inode() can come and free marks. Even in our +* to_free list so we have to use mark_mutex even when accessing that +* list. And freeing mark requires us to drop mark_mutex. So we can +* reliably free only the first mark in the list. That's why we first +* move marks to free to to_free list in one go and then free marks in +* to_free list one by one. +*/ mutex_lock_nested (&group->mark_mutex,SINGLE_DEPTH_NESTING );list_for_each_entry_safe (mark, lmark, &group->marks_list, g_list) { -if (mark->flags & flags) { -fsnotify_get_mark (mark); -fsnotify_destroy_mark_locked (mark, group); -fsnotify_put_mark (mark); - } +if (mark->flags & flags) +list_move (&mark->g_list, &to_free); }mutex_unlock (&group->mark_mutex); + +while (1 ) { +mutex_lock_nested (&group->mark_mutex,SINGLE_DEPTH_NESTING ); +if (list_empty (&to_free)) { +mutex_unlock (&group->mark_mutex); +break ; + } + mark = list_first_entry(&to_free, struct fsnotify_mark, g_list); +fsnotify_get_mark (mark); +fsnotify_destroy_mark_locked (mark, group); +mutex_unlock (&group->mark_mutex); +fsnotify_put_mark (mark); + } }/*
Greg Kroah-Hartman
maintainerPATCH 6/44 drm/radeon/combios: add some validation of lvds values
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit 0a90a0cff9f429f886f423967ae053150dce9259 upstream.
Fixes a broken hsync start value uncovered by:abc0b1447d4974963548777a5ba4a4457c82c426 (drm: Perform basic sanity checks on probed modes)
The driver handled the bad hsync start elsewhere, but the above commit prevented it from getting added.
bug:
https://bugs.freedesktop.org/show_bug.cgi?id=91401
--- drivers/gpu/drm/radeon/radeon_combios.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_combios.c +6 -1
@@ -1255,10 +1255,15 @@ struct radeon_encoder_lvds *radeon_combiif ((RBIOS16 (tmp) == lvds->native_mode.hdisplay) && (RBIOS16 (tmp +2 ) == lvds->native_mode.vdisplay)) { +u32 hss = (RBIOS16 (tmp +21 ) -RBIOS16 (tmp +19 ) -1 ) *8 ; + +if (hss > lvds->native_mode.hdisplay) + hss = (10 -1 ) *8 ; + lvds->native_mode.htotal = lvds->native_mode.hdisplay + (RBIOS16 (tmp +17 ) -RBIOS16 (tmp +19 )) *8 ; lvds->native_mode.hsync_start = lvds->native_mode.hdisplay + - (RBIOS16 (tmp +21 ) -RBIOS16 (tmp +19 ) -1 ) *8 ; + hss; lvds->native_mode.hsync_end = lvds->native_mode.hsync_start + (RBIOS8 (tmp +23 ) *8 );
Greg Kroah-Hartman
maintainerPATCH 7/44 ipr: Fix locking for unit attention handling
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian King <[email protected]>
commit 36b8e180e1e929e00b351c3b72aab3147fc14116 upstream.
Make sure we have the host lock held when calling scsi_report_bus_reset. Fixes a crash seen as the __devices list in the scsi host was changing as we were iterating through it.
--- drivers/scsi/ipr.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/scsi/ipr.c +7 -5
@@ -6179,21 +6179,23 @@ static void ipr_scsi_done(struct ipr_cmnstruct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;u32 ioasc =be32_to_cpu (ipr_cmd->s.ioasa.hdr.ioasc); -unsigned long hrrq_flags; +unsigned long lock_flags;scsi_set_resid (scsi_cmd,be32_to_cpu (ipr_cmd->s.ioasa.hdr.residual_data_len));if (likely (IPR_IOASC_SENSE_KEY (ioasc) ==0 )) {scsi_dma_unmap (scsi_cmd); -spin_lock_irqsave (ipr_cmd->hrrq->lock, hrrq_flags); +spin_lock_irqsave (ipr_cmd->hrrq->lock, lock_flags);list_add_tail (&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); scsi_cmd->scsi_done (scsi_cmd); -spin_unlock_irqrestore (ipr_cmd->hrrq->lock, hrrq_flags); +spin_unlock_irqrestore (ipr_cmd->hrrq->lock, lock_flags); }else { -spin_lock_irqsave (ipr_cmd->hrrq->lock, hrrq_flags); +spin_lock_irqsave (ioa_cfg->host->host_lock, lock_flags); +spin_lock (&ipr_cmd->hrrq->_lock);ipr_erp_start (ioa_cfg, ipr_cmd); -spin_unlock_irqrestore (ipr_cmd->hrrq->lock, hrrq_flags); +spin_unlock (&ipr_cmd->hrrq->_lock); +spin_unlock_irqrestore (ioa_cfg->host->host_lock, lock_flags); } }
Greg Kroah-Hartman
maintainerPATCH 8/44 ipr: Fix incorrect trace indexing
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian King <[email protected]>
commit bb7c54339e6a10ecce5c4961adf5e75b3cf0af30 upstream.
When ipr's internal driver trace was changed to an atomic, a signed/unsigned bug slipped in which results in us indexing backwards in our memory buffer writing on memory that does not belong to us. This patch fixes this by removing the modulo and instead just mask off the low bits.
--- drivers/scsi/ipr.c | 5 +++-- drivers/scsi/ipr.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/ipr.c +3 -2
@@ -592,9 +592,10 @@ static void ipr_trc_hook(struct ipr_cmnd {struct ipr_trace_entry *trace_entry;struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; +unsigned int trace_index; - trace_entry = &ioa_cfg->trace[atomic_add_return - (1 , &ioa_cfg->trace_index)%IPR_NUM_TRACE_ENTRIES ]; + trace_index =atomic_add_return (1 , &ioa_cfg->trace_index) &IPR_TRACE_INDEX_MASK ; + trace_entry = &ioa_cfg->trace[trace_index]; trace_entry->time = jiffies; trace_entry->op_code = ipr_cmd->ioarcb.cmd_pkt.cdb[0 ]; trace_entry->type = type;
drivers/scsi/ipr.h +1 -0
@@ -1459,6 +1459,7 @@ struct ipr_ioa_cfg {#define IPR_NUM_TRACE_INDEX_BITS 8#define IPR_NUM_TRACE_ENTRIES (1 << IPR_NUM_TRACE_INDEX_BITS) +#define IPR_TRACE_INDEX_MASK (IPR_NUM_TRACE_ENTRIES - 1)#define IPR_TRACE_SIZE (sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES)char trace_start[8 ];#define IPR_TRACE_START_LABEL "trace"
Greg Kroah-Hartman
maintainerPATCH 9/44 ipr: Fix invalid array indexing for HRRQ
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian King <[email protected]>
commit 3f1c0581310d5d94bd72740231507e763a6252a4 upstream.
Fixes another signed / unsigned array indexing bug in the ipr driver. Currently, when hrrq_index wraps, it becomes a negative number. We do the modulo, but still have a negative number, so we end up indexing backwards in the array. Given where the hrrq array is located in memory, we probably won't actually reference memory we don't own, but nonetheless ipr is still looking at data within struct ipr_ioa_cfg and interpreting it as struct ipr_hrr_queue data, so bad things could certainly happen.
Each ipr adapter has anywhere from 1 to 16 HRRQs. By default, we use 2 on new adapters. Let's take an example:
Assume ioa_cfg->hrrq_index=0x7fffffffe and ioa_cfg->hrrq_num=4:
The atomic_add_return will then return -1. We mod this with 3 and get -2, add one and get -1 for an array index.
On adapters which support more than a single HRRQ, we dedicate HRRQ to adapter initialization and error interrupts so that we can optimize the other queues for fast path I/O. So all normal I/O uses HRRQ 1-15. So we want to spread the I/O requests across those HRRQs.
With the default module parameter settings, this bug won't hit, only when someone sets the ipr.number_of_msix parameter to a value larger than 3 is when bad things start to happen.
--- drivers/scsi/ipr.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/scsi/ipr.c +8 -3
@@ -1045,10 +1045,15 @@ static void ipr_send_blocking_cmd(structstatic int ipr_get_hrrq_index (struct ipr_ioa_cfg *ioa_cfg) { +unsigned int hrrq; +if (ioa_cfg->hrrq_num ==1 ) -return 0 ; -else -return (atomic_add_return (1 , &ioa_cfg->hrrq_index) % (ioa_cfg->hrrq_num -1 )) +1 ; + hrrq =0 ; +else { + hrrq =atomic_add_return (1 , &ioa_cfg->hrrq_index); + hrrq = (hrrq % (ioa_cfg->hrrq_num -1 )) +1 ; + } +return hrrq; }/**
Greg Kroah-Hartman
maintainerPATCH 11/44 USB: sierra: add 1199:68AB device ID
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dirk Behme <[email protected]>
commit 74472233233f577eaa0ca6d6e17d9017b6e53150 upstream.
Add support for the Sierra Wireless AR8550 device with USB descriptor 0x1199, 0x68AB.
It is common with MC879x modules 1199:683c/683d which also are composite devices with 7 interfaces (0..6) and also MDM62xx based as the AR8550.
The major difference are only the interface attributes 02/02/01 on interfaces 3 and 4 on the AR8550. They are vendor specific ff/ff/ff on MC879x modules.
lsusb reports:
Bus 001 Device 004: ID 1199:68ab Sierra Wireless, Inc. Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1199 Sierra Wireless, Inc. idProduct 0x68ab bcdDevice 0.06 iManufacturer 3 Sierra Wireless, Incorporated iProduct 2 AR8550 iSerial 0 bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 198
bNumInterfaces 7
bConfigurationValue 1
iConfiguration 1 Sierra Configuration
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 0mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 4
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x05 EP 5 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 5
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x89 EP 9 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x06 EP 6 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 6
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x8a EP 10 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x8b EP 11 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x07 EP 7 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0001
Self Powered
--- drivers/usb/serial/sierra.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/serial/sierra.c +1 -0
@@ -289,6 +289,7 @@ static const struct usb_device_id id_tab { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68AA, 0xFF, 0xFF, 0xFF), .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, + { USB_DEVICE(0x1199, 0x68AB) }, /* Sierra Wireless AR8550 */ /* AT&T Direct IP LTE modems */ { USB_DEVICE_AND_INTERFACE_INFO(0x0F3D, 0x68AA, 0xFF, 0xFF, 0xFF), .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
Greg Kroah-Hartman
maintainerPATCH 12/44 ima: add support for new "euid" policy condition
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mimi Zohar <[email protected]>
commit 139069eff7388407f19794384c42a534d618ccd7 upstream.
The new "euid" policy condition measures files with the specified effective uid (euid). In addition, for CAP_SETUID files it measures files with the specified uid or suid.
Changelog:
- fixed checkpatch.pl warnings
- fixed avc denied {setuid} messages - based on Roberto's feedback
--- Documentation/ABI/testing/ima_policy | 3 ++- security/integrity/ima/ima_policy.c | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-)
Documentation/ABI/testing/ima_policy +2 -1
@@ -20,7 +20,7 @@ Description: action: measure | dont_measure | appraise | dont_appraise | audit condition:= base | lsm [option] base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=] - [fowner]] + [euid=] [fowner=]] lsm: [[subj_user=] [subj_role=] [subj_type=] [obj_user=] [obj_role=] [obj_type=]] option: [[appraise_type=]] [permit_directio]
@@ -30,6 +30,7 @@ Description: fsmagic:= hex value fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) uid:= decimal value + euid:= decimal value fowner:=decimal value lsm: are LSM specific option: appraise_type:= [imasig]
security/integrity/ima/ima_policy.c +23 -4
@@ -27,6 +27,7 @@#define IMA_UID 0x0008#define IMA_FOWNER 0x0010#define IMA_FSUUID 0x0020 +#define IMA_EUID 0x0080#define UNKNOWN 0#define MEASURE 0x0001/* same as IMA_MEASURE */
@@ -179,6 +180,16 @@ static bool ima_match_rules(struct ima_rreturn false;if ((rule->flags &IMA_UID ) && !uid_eq (rule->uid, cred->uid))return false; +if (rule->flags &IMA_EUID ) { +if (has_capability_noaudit (current,CAP_SETUID )) { +if (!uid_eq (rule->uid, cred->euid) + && !uid_eq (rule->uid, cred->suid) + && !uid_eq (rule->uid, cred->uid)) +return false; + }else if (!uid_eq (rule->uid, cred->euid)) +return false; + } +if ((rule->flags &IMA_FOWNER ) && !uid_eq (rule->fowner, inode->i_uid))return false;for (i =0 ; i <MAX_LSM_RULES ; i++) {
@@ -350,7 +361,8 @@ enum { Opt_audit, Opt_obj_user, Opt_obj_role, Opt_obj_type, Opt_subj_user, Opt_subj_role, Opt_subj_type, - Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner, + Opt_func, Opt_mask, Opt_fsmagic, + Opt_uid, Opt_euid, Opt_fowner, Opt_appraise_type, Opt_fsuuid, Opt_permit_directio };
@@ -371,6 +383,7 @@ static match_table_t policy_tokens = { {Opt_fsmagic, "fsmagic=%s"}, {Opt_fsuuid, "fsuuid=%s"}, {Opt_uid, "uid=%s"}, + {Opt_euid, "euid=%s"}, {Opt_fowner, "fowner=%s"}, {Opt_appraise_type, "appraise_type=%s"}, {Opt_permit_directio, "permit_directio"},
@@ -542,6 +555,9 @@ static int ima_parse_rule(char *rule, stbreak ;case Opt_uid:ima_log_string (ab,"uid" , args[0 ].from); +case Opt_euid: +if (token == Opt_euid) +ima_log_string (ab,"euid" , args[0 ].from);if (uid_valid (entry->uid)) { result = -EINVAL ;
@@ -550,11 +566,14 @@ static int ima_parse_rule(char *rule, st result =strict_strtoul (args[0 ].from,10 , &lnum);if (!result) { - entry->uid =make_kuid (current_user_ns (), (uid_t )lnum); -if (!uid_valid (entry->uid) || (((uid_t )lnum) != lnum)) + entry->uid =make_kuid (current_user_ns (), + (uid_t ) lnum); +if (!uid_valid (entry->uid) || + (uid_t )lnum != lnum) result = -EINVAL ;else - entry->flags |=IMA_UID ; + entry->flags |= (token == Opt_uid) + ?IMA_UID :IMA_EUID ; }break ;case Opt_fowner:
Greg Kroah-Hartman
maintainerPATCH 13/44 ima: extend "mask" policy matching support
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mimi Zohar <[email protected]>
commit 4351c294b8c1028077280f761e158d167b592974 upstream.
The current "mask" policy option matches files opened as MAY_READ, MAY_WRITE, MAY_APPEND or MAY_EXEC. This patch extends the "mask" option to match files opened containing one of these modes. For example, "mask=^MAY_READ" would match files opened read-write.
--- Documentation/ABI/testing/ima_policy | 3 ++- security/integrity/ima/ima_policy.c | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-)
Documentation/ABI/testing/ima_policy +2 -1
@@ -26,7 +26,8 @@ Description: option: [[appraise_type=]] [permit_directio] base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK] - mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] + mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] + [[^]MAY_EXEC] fsmagic:= hex value fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6) uid:= decimal value
security/integrity/ima/ima_policy.c +15 -5
@@ -27,6 +27,7 @@#define IMA_UID 0x0008#define IMA_FOWNER 0x0010#define IMA_FSUUID 0x0020 +#define IMA_INMASK 0x0040#define IMA_EUID 0x0080#define UNKNOWN 0
@@ -172,6 +173,9 @@ static bool ima_match_rules(struct ima_rreturn false;if ((rule->flags &IMA_MASK ) && rule->mask != mask)return false; +if ((rule->flags &IMA_INMASK ) && + (!(rule->mask & mask) && func !=POST_SETATTR )) +return false;if ((rule->flags &IMA_FSMAGIC ) && rule->fsmagic != inode->i_sb->s_magic)return false;
@@ -425,6 +429,7 @@ static void ima_log_string(struct audit_static int ima_parse_rule (char *rule,struct ima_rule_entry *entry) {struct audit_buffer *ab; +char *from;char *p;int result =0 ;
@@ -513,18 +518,23 @@ static int ima_parse_rule(char *rule, stif (entry->mask) result = -EINVAL ; -if ((strcmp (args[0 ].from,"MAY_EXEC" )) ==0 ) + from = args[0 ].from; +if (*from =='^' ) + from++; + +if ((strcmp (from,"MAY_EXEC" )) ==0 ) entry->mask =MAY_EXEC ; -else if (strcmp (args[0 ].from,"MAY_WRITE" ) ==0 ) +else if (strcmp (from,"MAY_WRITE" ) ==0 ) entry->mask =MAY_WRITE ; -else if (strcmp (args[0 ].from,"MAY_READ" ) ==0 ) +else if (strcmp (from,"MAY_READ" ) ==0 ) entry->mask =MAY_READ ; -else if (strcmp (args[0 ].from,"MAY_APPEND" ) ==0 ) +else if (strcmp (from,"MAY_APPEND" ) ==0 ) entry->mask =MAY_APPEND ;else result = -EINVAL ;if (!result) - entry->flags |=IMA_MASK ; + entry->flags |= (*args[0 ].from =='^' ) + ?IMA_INMASK :IMA_MASK ;break ;case Opt_fsmagic:ima_log_string (ab,"fsmagic" , args[0 ].from);
Greg Kroah-Hartman
maintainerPATCH 14/44 md: use kzalloc() when bitmap is disabled
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Randazzo <[email protected]>
commit b6878d9e03043695dbf3fa1caa6dfc09db225b16 upstream.
In drivers/md/md.c get_bitmap_file() uses kmalloc() for creating a mdu_bitmap_file_t called "file".
5769 file = kmalloc(sizeof(*file), GFP_NOIO);
5770 if (!file)
5771 return -ENOMEM;
This structure is copied to user space at the end of the function.
5786 if (err == 0 &&
5787 copy_to_user(arg, file, sizeof(*file)))
5788 err = -EFAULT
But if bitmap is disabled only the first byte of "file" is initialized with zero, so it's possible to read some bytes (up to 4095) of kernel space memory from user space. This is an information leak.
5775 /* bitmap disabled, zero the first byte and copy out */
5776 if (!mddev->bitmap_info.file)
5777 file->pathname[0] = '\0';
--- drivers/md/md.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/md/md.c +1 -2
@@ -5645,8 +5645,7 @@ static int get_bitmap_file(struct mddevchar *ptr, *buf =NULL ;int err = -ENOMEM ; - file =kmalloc (sizeof (*file),GFP_NOIO ); - + file =kzalloc (sizeof (*file),GFP_NOIO );if (!file) goto out;
Greg Kroah-Hartman
maintainerPATCH 15/44 ARM: sunxi: fix build for THUMB2_KERNEL
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 1146b600044de64af0ef775025731eeef1fa2189 upstream.
Building an SMP kernel for the sunxi platform with THUMB2 instructions fails with this error at the moment:
headsmp.S:7: Error: Thumb encoding does not support an immediate here -- `msr cpsr_fsxc,#0xd3'
Since the generic secondary_startup function already does the same thing in a safe way, we can just drop the private sunxi implementation and jump straight to secondary_startup.
--- arch/arm/include/asm/smp.h | 1 + arch/arm/mach-sunxi/Makefile | 2 +- arch/arm/mach-sunxi/headsmp.S | 9 --------- arch/arm/mach-sunxi/platsmp.c | 2 +- 4 files changed, 3 insertions(+), 11 deletions(-)
arch/arm/include/asm/smp.h +1 -0
@@ -74,6 +74,7 @@ struct secondary_data { };extern struct secondary_data secondary_data;extern volatile int pen_release; +extern void secondary_startup (void );extern int __cpu_disable (void );
arch/arm/mach-sunxi/Makefile +1 -1
@@ -1,2 +1,2 @@ obj-$(CONFIG_ARCH_SUNXI) += sunxi.o -obj-$(CONFIG_SMP) += platsmp.o headsmp.o +obj-$(CONFIG_SMP) += platsmp.o
arch/arm/mach-sunxi/headsmp.S deleted +0 -9
@@ -1,9 +0,0 @@ -#include <linux/linkage.h> -#include <linux/init.h> - - .section ".text.head", "ax" - -ENTRY(sun6i_secondary_startup) - msr cpsr_fsxc, #0xd3 - b secondary_startup -ENDPROC(sun6i_secondary_startup)
arch/arm/mach-sunxi/platsmp.c +1 -1
@@ -82,7 +82,7 @@ static int sun6i_smp_boot_secondary(unsispin_lock (&cpu_lock);/* Set CPU boot address */ -writel (virt_to_phys (sun6i_secondary_startup), +writel (virt_to_phys (secondary_startup), cpucfg_membase +CPUCFG_PRIVATE0_REG );/* Assert the CPU core in reset */
Greg Kroah-Hartman
maintainerPATCH 16/44 sparc64: Fix userspace FPU register corruptions.
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <[email protected]>
[ Upstream commit 44922150d87cef616fd183220d43d8fde4d41390 ]
If we have a series of events from userpsace, with %fprs=FPRS_FEF, like follows:
ETRAP
ETRAP VIS_ENTRY(fprs=0x4) VIS_EXIT RTRAP (kernel FPU restore with fpu_saved=0x4) RTRAP
We will not restore the user registers that were clobbered by the FPU using kernel code in the inner-most trap.
Traps allocate FPU save slots in the thread struct, and FPU using sequences save the "dirty" FPU registers only.
This works at the initial trap level because all of the registers get recorded into the top-level FPU save area, and we'll return to userspace with the FPU disabled so that any FPU use by the user will take an FPU disabled trap wherein we'll load the registers back up properly.
But this is not how trap returns from kernel to kernel operate.
The simplest fix for this bug is to always save all FPU register state for anything other than the top-most FPU save area.
Getting rid of the optimized inner-slot FPU saving code ends up making VISEntryHalf degenerate into plain VISEntry.
Longer term we need to do something smarter to reinstate the partial save optimizations. Perhaps the fundament error is having trap entry and exit allocate FPU save slots and restore register state. Instead, the VISEntry et al. calls should be doing that work.
This bug is about two decades old.
--- arch/sparc/include/asm/visasm.h | 16 ++------- arch/sparc/lib/NG4memcpy.S | 5 ++ arch/sparc/lib/VISsave.S | 67 +--------------------------------------- arch/sparc/lib/ksyms.c | 4 -- 4 files changed, 11 insertions(+), 81 deletions(-)
arch/sparc/include/asm/visasm.h +5 -11
@@ -28,16 +28,10 @@* Must preserve %o5 between VISEntryHalf and VISExitHalf */ #define VISEntryHalf \ - rd %fprs, %o5; \ - andcc %o5, FPRS_FEF, %g0; \ - be,pt %icc, 297f; \ - sethi %hi(298f), %g7; \ - sethi %hi(VISenterhalf), %g1; \ - jmpl %g1 + %lo(VISenterhalf), %g0; \ - or %g7, %lo(298f), %g7; \ - clr %o5; \ -297: wr %o5, FPRS_FEF, %fprs; \ -298: + VISEntry + +#define VISExitHalf \ + VISExit#define VISEntryHalfFast (fail_label) \ rd %fprs, %o5; \
@@ -47,7 +41,7 @@ ba,a,pt %xcc, fail_label; \ 297: wr %o5, FPRS_FEF, %fprs; -#define VISExitHalf \ +#define VISExitHalfFast \ wr %o5, 0, %fprs;#ifndef __ASSEMBLY__
arch/sparc/lib/NG4memcpy.S +4 -1
@@ -240,8 +240,11 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len add %o0, 0x40, %o0 bne,pt %icc, 1b LOAD(prefetch, %g1 + 0x200, #n_reads_strong) +#ifdef NON_USER_COPY + VISExitHalfFast +#else VISExitHalf - +#endif brz,pn %o2, .Lexit cmp %o2, 19 ble,pn %icc, .Lsmall_unaligned
arch/sparc/lib/VISsave.S +2 -65
76 lines not on this page · raw message
arch/sparc/lib/ksyms.c +0 -4
@@ -126,10 +126,6 @@ EXPORT_SYMBOL(copy_user_page);void VISenter (void );EXPORT_SYMBOL (VISenter); -/* CRYPTO code needs this */ -void VISenterhalf (void ); -EXPORT_SYMBOL (VISenterhalf); -extern void xor_vis_2 (unsigned long ,unsigned long *,unsigned long *);extern void xor_vis_3 (unsigned long ,unsigned long *,unsigned long *,unsigned long *);
Greg Kroah-Hartman
maintainerPATCH 17/44 ASoC: pcm1681: Fix setting de-emphasis sampling rate selection
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Axel Lin <[email protected]>
commit fa8173a3ef0570affde7da352de202190b3786c2 upstream.
The de-emphasis sampling rate selection is controlled by BIT[3:4] of PCM1681_DEEMPH_CONTROL register. Do proper left shift to set it.
--- sound/soc/codecs/pcm1681.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/pcm1681.c +1 -1
@@ -102,7 +102,7 @@ static int pcm1681_set_deemph(struct sndif (val !=-1 ) {regmap_update_bits (priv->regmap,PCM1681_DEEMPH_CONTROL , -PCM1681_DEEMPH_RATE_MASK , val); +PCM1681_DEEMPH_RATE_MASK , val <<3 ); enable =1 ; }else enable =0 ;
Greg Kroah-Hartman
maintainerPATCH 18/44 x86/xen: Probe target addresses in set_aliased_prot() before the hypercall
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski <[email protected]>
commit aa1acff356bbedfd03b544051f5b371746735d89 upstream.
The update_va_mapping hypercall can fail if the VA isn't present in the guest's page tables. Under certain loads, this can result in an OOPS when the target address is in unpopulated vmap space.
While we're at it, add comments to help explain what's going on.
This isn't a great long-term fix. This code should probably be changed to use something like set_memory_ro.
--- arch/x86/xen/enlighten.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
arch/x86/xen/enlighten.c +40 -0
@@ -481,6 +481,7 @@ static void set_aliased_prot(void *v, pgpte_t pte;unsigned long pfn;struct page *page; +unsigned char dummy; ptep =lookup_address ((unsigned long )v, &level);BUG_ON (ptep ==NULL );
@@ -490,6 +491,32 @@ static void set_aliased_prot(void *v, pg pte =pfn_pte (pfn, prot); +/* +* Careful: update_va_mapping() will fail if the virtual address +* we're poking isn't populated in the page tables. We don't +* need to worry about the direct map (that's always in the page +* tables), but we need to be careful about vmap space. In +* particular, the top level page table can lazily propagate +* entries between processes, so if we've switched mms since we +* vmapped the target in the first place, we might not have the +* top-level page table entry populated. +* +* We disable preemption because we want the same mm active when +* we probe the target and when we issue the hypercall. We'll +* have the same nominal mm, but if we're a kernel thread, lazy +* mm dropping could change our pgd. +* +* Out of an abundance of caution, this uses __get_user() to fault +* in the target address just in case there's some obscure case +* in which the target address isn't readable. +*/ + +preempt_disable (); + +pagefault_disable ();/* Avoid warnings due to being atomic. */ +__get_user (dummy, (unsigned char __user __force *)v); +pagefault_enable (); +if (HYPERVISOR_update_va_mapping ((unsigned long )v, pte,0 ))BUG ();
@@ -501,6 +528,8 @@ static void set_aliased_prot(void *v, pgBUG (); }else kmap_flush_unused (); + +preempt_enable (); }static void xen_alloc_ldt (struct desc_struct *ldt,unsigned entries)
@@ -508,6 +537,17 @@ static void xen_alloc_ldt(struct desc_stconst unsigned entries_per_page =PAGE_SIZE /LDT_ENTRY_SIZE ;int i; +/* +* We need to mark the all aliases of the LDT pages RO. We +* don't need to call vm_flush_aliases(), though, since that's +* only responsible for flushing aliases out the TLBs, not the +* page tables, and Xen will flush the TLB for us if needed. +* +* To avoid confusing future readers: none of this is necessary +* to load the LDT. The hypervisor only checks this when the +* LDT is faulted in due to subsequent descriptor access. +*/ +for (i =0 ; i < entries; i += entries_per_page)set_aliased_prot (ldt + i,PAGE_KERNEL_RO ); }
Greg Kroah-Hartman
maintainerPATCH 20/44 crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit f898c522f0e9ac9f3177d0762b76e2ab2d2cf9c0 upstream.
This patch removes a bogus BUG_ON in the ablkcipher path that triggers when the destination buffer is different from the source buffer and is scattered.
--- drivers/crypto/ixp4xx_crypto.c | 1 - 1 file changed, 1 deletion(-)
drivers/crypto/ixp4xx_crypto.c +0 -1
@@ -904,7 +904,6 @@ static int ablk_perform(struct ablkciphe crypt->mode |=NPE_OP_NOT_IN_PLACE ;/* This was never tested by Intel * for more than one dst buffer, I think. */ -BUG_ON (req->dst->length < nbytes); req_ctx->dst =NULL ;if (!chainup_buffers (dev, req->dst, nbytes, &dst_hook, flags,DMA_FROM_DEVICE ))
Greg Kroah-Hartman
maintainerPATCH 21/44 rbd: fix copyup completion race
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Dryomov <[email protected]>
commit 2761713d35e370fd640b5781109f753066b746c4 upstream.
For write/discard obj_requests that involved a copyup method call, the opcode of the first op is CEPH_OSD_OP_CALL and the ->callback is rbd_img_obj_copyup_callback(). The latter frees copyup pages, sets ->xferred and delegates to rbd_img_obj_callback(), the "normal" image object callback, for reporting to block layer and putting refs.
rbd_osd_req_callback() however treats CEPH_OSD_OP_CALL as a trivial op, which means obj_request is marked done in rbd_osd_trivial_callback(), *before* ->callback is invoked and rbd_img_obj_copyup_callback() has a chance to run. Marking obj_request done essentially means giving rbd_img_obj_callback() a license to end it at any moment, so if another obj_request from the same img_request is being completed concurrently, rbd_img_obj_end_request() may very well be called on such prematurally marked done request:
<obj_request-1/2 reply>handle_reply()
rbd_osd_req_callback()
rbd_osd_trivial_callback()
rbd_obj_request_complete()
rbd_img_obj_copyup_callback()
rbd_img_obj_callback()
<obj_request-2/2 reply>
handle_reply()
rbd_osd_req_callback()
rbd_osd_trivial_callback()
for_each_obj_request(obj_request->img_request) {
rbd_img_obj_end_request(obj_request-1/2)
rbd_img_obj_end_request(obj_request-2/2) <--
}Calling rbd_img_obj_end_request() on such a request leads to trouble, in particular because its ->xfferred is 0. We report 0 to the block layer with blk_update_request(), get back 1 for "this request has more data in flight" and then trip on
rbd_assert(more ^ (which == img_request->obj_request_count));
with rhs (which == ...) being 1 because rbd_img_obj_end_request() has been called for both requests and lhs (more) being 1 because we haven't got a chance to set ->xfferred in rbd_img_obj_copyup_callback() yet.
To fix this, leverage that rbd wants to call class methods in only two
cases: one is a generic method call wrapper (obj_request is standalone) and the other is a copyup (obj_request is part of an img_request). So make a dedicated handler for CEPH_OSD_OP_CALL and directly invoke rbd_img_obj_copyup_callback() from it if obj_request is part of an img_request, similar to how CEPH_OSD_OP_READ handler invokes rbd_img_obj_request_read_callback().
Since rbd_img_obj_copyup_callback() is now being called from the OSD request callback (only), it is renamed to rbd_osd_copyup_callback().
--- drivers/block/rbd.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
drivers/block/rbd.c +17 -5
@@ -508,6 +508,7 @@ void rbd_warn(struct rbd_device *rbd_dev# define rbd_assert (expr) ((void) 0)#endif /* !RBD_DEBUG */ +static void rbd_osd_copyup_callback (struct rbd_obj_request *obj_request);static int rbd_img_obj_request_submit (struct rbd_obj_request *obj_request);static void rbd_img_parent_read (struct rbd_obj_request *obj_request);static void rbd_dev_remove_parent (struct rbd_device *rbd_dev);
@@ -1651,6 +1652,16 @@ static void rbd_osd_stat_callback(structobj_request_done_set (obj_request); } +static void rbd_osd_call_callback (struct rbd_obj_request *obj_request) +{ +dout ("%s: obj %p\n" , __func__, obj_request); + +if (obj_request_img_data_test (obj_request)) +rbd_osd_copyup_callback (obj_request); +else +obj_request_done_set (obj_request); +} +static void rbd_osd_req_callback (struct ceph_osd_request *osd_req,struct ceph_msg *msg) {
@@ -1689,6 +1700,8 @@ static void rbd_osd_req_callback(structrbd_osd_stat_callback (obj_request);break ;case CEPH_OSD_OP_CALL : +rbd_osd_call_callback (obj_request); +break ;case CEPH_OSD_OP_NOTIFY_ACK :case CEPH_OSD_OP_WATCH :rbd_osd_trivial_callback (obj_request);
@@ -2275,13 +2288,15 @@ out_unwind: }static void -rbd_img_obj_copyup_callback (struct rbd_obj_request *obj_request) +rbd_osd_copyup_callback (struct rbd_obj_request *obj_request) {struct rbd_img_request *img_request;struct rbd_device *rbd_dev;struct page **pages;u32 page_count; +dout ("%s: obj %p\n" , __func__, obj_request); +rbd_assert (obj_request->type ==OBJ_REQUEST_BIO );rbd_assert (obj_request_img_data_test (obj_request)); img_request = obj_request->img_request;
@@ -2307,9 +2322,7 @@ rbd_img_obj_copyup_callback(struct rbd_oif (!obj_request->result) obj_request->xferred = obj_request->length; -/* Finish up with the normal image object callback */ - -rbd_img_obj_callback (obj_request); +obj_request_done_set (obj_request); } static void
@@ -2406,7 +2419,6 @@ rbd_img_obj_parent_read_full_callback(st/* All set, send it off. */ - orig_request->callback = rbd_img_obj_copyup_callback; osdc = &rbd_dev->rbd_client->client->osdc; img_result =rbd_obj_request_submit (osdc, orig_request);if (!img_result)
Greg Kroah-Hartman
maintainerPATCH 22/44 ARM: OMAP2+: hwmod: Fix _wait_target_ready() for hwmods without sysc
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Quadros <[email protected]>
commit 9a258afa928b45e6dd2efcac46ccf7eea705d35a upstream.
For hwmods without sysc, _init_mpu_rt_base(oh) won't be called and so _find_mpu_rt_port(oh) will return NULL thus preventing ready state check on those modules after the module is enabled.
This can potentially cause a bus access error if the module is accessed before the module is ready.
Fix this by unconditionally calling _init_mpu_rt_base() during hwmod _init(). Do ioremap only if we need SYSC access.
Eventhough _wait_target_ready() check doesn't really need MPU RT port but just the PRCM registers, we still mandate that the hwmod must have an MPU RT port if ready state check needs to be done. Else it would mean that the module is not accessible by MPU so there is no point in waiting for target to be ready.
e.g. this fixes the below DCAN bus access error on AM437x-gp-evm.
[ 16.672978] ------------[ cut here ]------------ [ 16.677885] WARNING: CPU: 0 PID: 1580 at drivers/bus/omap_l3_noc.c:147 l3_interrupt_handler+0x234/0x35c() [ 16.687946] 44000000.ocp:L3 Custom Error: MASTER M2 (64-bit) TARGET L4_PER_0 (Read): Data Access in User mode during Functional access [ 16.700654] Modules linked in: xhci_hcd btwilink ti_vpfe dwc3 videobuf2_core ov2659 bluetooth v4l2_common videodev ti_am335x_adc kfifo_buf industrialio c_can_platform videobuf2_dma_contig media snd_soc_tlv320aic3x pixcir_i2c_ts c_can dc [ 16.731144] CPU: 0 PID: 1580 Comm: rpc.statd Not tainted 3.14.26-02561-gf733aa036398 #180 [ 16.739747] Backtrace: [ 16.742336] [<c0011108>] (dump_backtrace) from [<c00112a4>] (show_stack+0x18/0x1c) [ 16.750285] r6:00000093 r5:00000009 r4:eab5b8a8 r3:00000000 [ 16.756252] [<c001128c>] (show_stack) from [<c05a4418>] (dump_stack+0x20/0x28) [ 16.763870] [<c05a43f8>] (dump_stack) from [<c0037120>] (warn_slowpath_common+0x6c/0x8c) [ 16.772408] [<c00370b4>] (warn_slowpath_common) from [<c00371e4>] (warn_slowpath_fmt+0x38/0x40) [ 16.781550] r8:c05d1f90 r7:c0730844 r6:c0730448 r5:80080003 r4:ed0cd210 [ 16.788626] [<c00371b0>] (warn_slowpath_fmt) from [<c027fa94>] (l3_interrupt_handler+0x234/0x35c) [ 16.797968] r3:ed0cd480 r2:c0730508 [ 16.801747] [<c027f860>] (l3_interrupt_handler) from [<c0063758>] (handle_irq_event_percpu+0x54/0x1bc) [ 16.811533] r10:ed005600 r9:c084855b r8:0000002a r7:00000000 r6:00000000 r5:0000002a [ 16.819780] r4:ed0e6d80 [ 16.822453] [<c0063704>] (handle_irq_event_percpu) from [<c00638f0>] (handle_irq_event+0x30/0x40) [ 16.831789] r10:eb2b6938 r9:eb2b6960 r8:bf011420 r7:fa240100 r6:00000000 r5:0000002a [ 16.840052] r4:ed005600 [ 16.842744] [<c00638c0>] (handle_irq_event) from [<c00661d8>] (handle_fasteoi_irq+0x74/0x128) [ 16.851702] r4:ed005600 r3:00000000 [ 16.855479] [<c0066164>] (handle_fasteoi_irq) from [<c0063068>] (generic_handle_irq+0x28/0x38) [ 16.864523] r4:0000002a r3:c0066164 [ 16.868294] [<c0063040>] (generic_handle_irq) from [<c000ef60>] (handle_IRQ+0x38/0x8c) [ 16.876612] r4:c081c640 r3:00000202 [ 16.880380] [<c000ef28>] (handle_IRQ) from [<c00084f0>] (gic_handle_irq+0x30/0x5c) [ 16.888328] r6:eab5ba38 r5:c0804460 r4:fa24010c r3:00000100 [ 16.894303] [<c00084c0>] (gic_handle_irq) from [<c05a8d80>] (__irq_svc+0x40/0x50) [ 16.902193] Exception stack(0xeab5ba38 to 0xeab5ba80) [ 16.907499] ba20: 00000000 00000006 [ 16.916108] ba40: fa1d0000 fa1d0008 ed3d3000 eab5bab4 ed3d3460 c0842af4 bf011420 eb2b6960 [ 16.924716] ba60: eb2b6938 eab5ba8c eab5ba90 eab5ba80 bf035220 bf07702c 600f0013 ffffffff [ 16.933317] r7:eab5ba6c r6:ffffffff r5:600f0013 r4:bf07702c [ 16.939317] [<bf077000>] (c_can_plat_read_reg_aligned_to_16bit [c_can_platform]) from [<bf035220>] (c_can_get_berr_counter+0x38/0x64 [c_can]) [ 16.952696] [<bf0351e8>] (c_can_get_berr_counter [c_can]) from [<bf010294>] (can_fill_info+0x124/0x15c [can_dev]) [ 16.963480] r5:ec8c9740 r4:ed3d3000 [ 16.967253] [<bf010170>] (can_fill_info [can_dev]) from [<c0502fa8>] (rtnl_fill_ifinfo+0x58c/0x8fc) [ 16.976749] r6:ec8c9740 r5:ed3d3000 r4:eb2b6780 [ 16.981613] [<c0502a1c>] (rtnl_fill_ifinfo) from [<c0503408>] (rtnl_dump_ifinfo+0xf0/0x1dc) [ 16.990401] r10:ec8c9740 r9:00000000 r8:00000000 r7:00000000 r6:ebd4d1b4 r5:ed3d3000 [ 16.998671] r4:00000000 [ 17.001342] [<c0503318>] (rtnl_dump_ifinfo) from [<c050e6e4>] (netlink_dump+0xa8/0x1e0) [ 17.009772] r10:00000000 r9:00000000 r8:c0503318 r7:ebf3e6c0 r6:ebd4d1b4 r5:ec8c9740 [ 17.018050] r4:ebd4d000 [ 17.020714] [<c050e63c>] (netlink_dump) from [<c050ec10>] (__netlink_dump_start+0x104/0x154) [ 17.029591] r6:eab5bd34 r5:ec8c9980 r4:ebd4d000 [ 17.034454] [<c050eb0c>] (__netlink_dump_start) from [<c0505604>] (rtnetlink_rcv_msg+0x110/0x1f4) [ 17.043778] r7:00000000 r6:ec8c9980 r5:00000f40 r4:ebf3e6c0 [ 17.049743] [<c05054f4>] (rtnetlink_rcv_msg) from [<c05108e8>] (netlink_rcv_skb+0xb4/0xc8) [ 17.058449] r8:eab5bdac r7:ec8c9980 r6:c05054f4 r5:ec8c9980 r4:ebf3e6c0 [ 17.065534] [<c0510834>] (netlink_rcv_skb) from [<c0504134>] (rtnetlink_rcv+0x24/0x2c) [ 17.073854] r6:ebd4d000 r5:00000014 r4:ec8c9980 r3:c0504110 [ 17.079846] [<c0504110>] (rtnetlink_rcv) from [<c05102ac>] (netlink_unicast+0x180/0x1ec) [ 17.088363] r4:ed0c6800 r3:c0504110 [ 17.092113] [<c051012c>] (netlink_unicast) from [<c0510670>] (netlink_sendmsg+0x2ac/0x380) [ 17.100813] r10:00000000 r8:00000008 r7:ec8c9980 r6:ebd4d000 r5:eab5be70 r4:eab5bee4 [ 17.109083] [<c05103c4>] (netlink_sendmsg) from [<c04dfdb4>] (sock_sendmsg+0x90/0xb0) [ 17.117305] r10:00000000 r9:eab5a000 r8:becdda3c r7:0000000c r6:ea978400 r5:eab5be70 [ 17.125563] r4:c05103c4 [ 17.128225] [<c04dfd24>] (sock_sendmsg) from [<c04e1c28>] (SyS_sendto+0xb8/0xdc) [ 17.136001] r6:becdda5c r5:00000014 r4:ecd37040 [ 17.140876] [<c04e1b70>] (SyS_sendto) from [<c000e680>] (ret_fast_syscall+0x0/0x30) [ 17.148923] r10:00000000 r8:c000e804 r7:00000122 r6:becdda5c r5:0000000c r4:becdda5c [ 17.157169] ---[ end trace 2b71e15b38f58bad ]---
--- arch/arm/mach-omap2/omap_hwmod.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +16 -8
@@ -2452,6 +2452,9 @@ static int of_dev_hwmod_lookup(struct de* registers. This address is needed early so the OCP registers that * are part of the device's address space can be ioremapped properly. * +* If SYSC access is not needed, the registers will not be remapped +* and non-availability of MPU access is not treated as an error. +* * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and * -ENXIO on absent or invalid register target address space. */
@@ -2466,6 +2469,11 @@ static int __init _init_mpu_rt_base(stru_save_mpu_port_index (oh); +/* if we don't need sysc access we don't need to ioremap */ +if (!oh->class->sysc) +return 0 ; + +/* we can't continue without MPU PORT if we need sysc access */ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)return -ENXIO ;
@@ -2475,8 +2483,10 @@ static int __init _init_mpu_rt_base(stru oh->name);/* Extract the IO space from device tree blob */ -if (!np) +if (!np) { +pr_err ("omap_hwmod: %s: no dt node\n" , oh->name);return -ENXIO ; + } va_start =of_iomap (np, index + oh->mpu_rt_idx); }else {
@@ -2535,13 +2545,11 @@ static int __init _init(struct omap_hwmo oh->name, np->name); } -if (oh->class->sysc) { - r =_init_mpu_rt_base (oh,NULL , index, np); -if (r <0 ) { -WARN (1 ,"omap_hwmod: %s: doesn't have mpu register target base\n" , - oh->name); -return 0 ; - } + r =_init_mpu_rt_base (oh,NULL , index, np); +if (r <0 ) { +WARN (1 ,"omap_hwmod: %s: doesn't have mpu register target base\n" , + oh->name); +return 0 ; } r =_init_clocks (oh,NULL );
Greg Kroah-Hartman
maintainerPATCH 23/44 iscsi-target: Fix iscsit_start_kthreads failure OOPs
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bellinger <[email protected]>
commit e54198657b65625085834847ab6271087323ffea upstream.
This patch fixes a regression introduced with the following commit in v4.0-rc1 code, where a iscsit_start_kthreads() failure triggers a NULL pointer dereference OOPs:
commit 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca
Author: Nicholas Bellinger <[email protected]>
Date: Thu Feb 26 22:19:15 2015 -0800
iscsi-target: Convert iscsi_thread_set usage to kthread.h
To address this bug, move iscsit_start_kthreads() immediately preceeding the transmit of last login response, before signaling a successful transition into full-feature-phase within existing iscsi_target_do_tx_login_io() logic.
This ensures that no target-side resource allocation failures can occur after the final login response has been successfully sent.
Also, it adds a iscsi_conn->rx_login_comp to allow the RX thread to sleep to prevent other socket related failures until the final iscsi_post_login_handler() call is able to complete.
--- drivers/target/iscsi/iscsi_target.c | 18 ++++++++++-- drivers/target/iscsi/iscsi_target_core.h | 1 drivers/target/iscsi/iscsi_target_login.c | 43 +++++++++++------------------- drivers/target/iscsi/iscsi_target_login.h | 3 +- drivers/target/iscsi/iscsi_target_nego.c | 34 +++++++++++++++++++++++ 5 files changed, 67 insertions(+), 32 deletions(-)
drivers/target/iscsi/iscsi_target.c +15 -3
@@ -3937,7 +3937,13 @@ get_immediate: } transport_err: -iscsit_take_action_for_connection_exit (conn); +/* +* Avoid the normal connection failure code-path if this connection +* is still within LOGIN mode, and iscsi_np process context is +* responsible for cleaning up the early connection failure. +*/ +if (conn->conn_state !=TARG_CONN_STATE_IN_LOGIN ) +iscsit_take_action_for_connection_exit (conn); out:return 0 ; }
@@ -4023,7 +4029,7 @@ reject:int iscsi_target_rx_thread (void *arg) { -int ret; +int ret, rc;u8 buffer[ISCSI_HDR_LEN ], opcode;u32 checksum =0 , digest =0 ;struct iscsi_conn *conn = arg;
@@ -4033,10 +4039,16 @@ int iscsi_target_rx_thread(void *arg)* connection recovery / failure event can be triggered externally. */ allow_signal (SIGINT ); +/* +* Wait for iscsi_post_login_handler() to complete before allowing +* incoming iscsi/tcp socket I/O, and/or failing the connection. +*/ + rc =wait_for_completion_interruptible (&conn->rx_login_comp); +if (rc <0 ) +return 0 ;if (conn->conn_transport->transport_type ==ISCSI_INFINIBAND ) {struct completion comp; -int rc;init_completion (&comp); rc =wait_for_completion_interruptible (&comp);
drivers/target/iscsi/iscsi_target_core.h +1 -0
@@ -604,6 +604,7 @@ struct iscsi_conn {int bitmap_id;int rx_thread_active;struct task_struct *rx_thread; +struct completion rx_login_comp;int tx_thread_active;struct task_struct *tx_thread;/* list_head for session connection list */
drivers/target/iscsi/iscsi_target_login.c +16 -27
110 lines not on this page · raw message
drivers/target/iscsi/iscsi_target_login.h +2 -1
@@ -12,7 +12,8 @@ extern int iscsit_accept_np(struct iscsiextern int iscsit_get_login_rx (struct iscsi_conn *,struct iscsi_login *);extern int iscsit_put_login_tx (struct iscsi_conn *,struct iscsi_login *,u32 );extern void iscsit_free_conn (struct iscsi_np *,struct iscsi_conn *); -extern int iscsi_post_login_handler (struct iscsi_np *,struct iscsi_conn *,u8 ); +extern int iscsit_start_kthreads (struct iscsi_conn *); +extern void iscsi_post_login_handler (struct iscsi_np *,struct iscsi_conn *,u8 );extern void iscsi_target_login_sess_out (struct iscsi_conn *,struct iscsi_np *,bool ,bool );extern int iscsi_target_login_thread (void *);
drivers/target/iscsi/iscsi_target_nego.c +33 -1
@@ -17,6 +17,7 @@******************************************************************************/ #include <linux/ctype.h> +#include <linux/kthread.h> #include <scsi/iscsi_proto.h> #include <target/target_core_base.h> #include <target/target_core_fabric.h>
@@ -361,10 +362,24 @@ static int iscsi_target_do_tx_login_io(s ntohl(login_rsp->statsn), login->rsp_length); padding = ((-login->rsp_length) &3 ); +/* +* Before sending the last login response containing the transition +* bit for full-feature-phase, go ahead and start up TX/RX threads +* now to avoid potential resource allocation failures after the +* final login response has been sent. +*/ +if (login->login_complete) { +int rc =iscsit_start_kthreads (conn); +if (rc) { +iscsit_tx_login_rsp (conn,ISCSI_STATUS_CLS_TARGET_ERR , +ISCSI_LOGIN_STATUS_NO_RESOURCES ); +return -1 ; + } + }if (conn->conn_transport->iscsit_put_login_tx (conn, login, login->rsp_length + padding) <0 ) -return -1 ; + goto err; login->rsp_length =0 ;mutex_lock (&sess->cmdsn_mutex);
@@ -373,6 +388,23 @@ static int iscsi_target_do_tx_login_io(smutex_unlock (&sess->cmdsn_mutex);return 0 ; + +err: +if (login->login_complete) { +if (conn->rx_thread && conn->rx_thread_active) { +send_sig (SIGINT , conn->rx_thread,1 ); +kthread_stop (conn->rx_thread); + } +if (conn->tx_thread && conn->tx_thread_active) { +send_sig (SIGINT , conn->tx_thread,1 ); +kthread_stop (conn->tx_thread); + } +spin_lock (&iscsit_global->ts_bitmap_lock); +bitmap_release_region (iscsit_global->ts_bitmap, conn->bitmap_id, +get_order (1 )); +spin_unlock (&iscsit_global->ts_bitmap_lock); + } +return -1 ; }static void iscsi_target_sk_data_ready (struct sock *sk,int count)
Greg Kroah-Hartman
maintainerPATCH 24/44 ALSA: hda - fix cs4210_spdif_automute()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 44008f0896ae205b02b0882dbf807f0de149efc4 upstream.
Smatch complains that we have nested checks for "spdif_present". It turns out the current behavior isn't correct, we should remove the first check and keep the second.
--- sound/pci/hda/patch_cirrus.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
sound/pci/hda/patch_cirrus.c +1 -3
@@ -1002,9 +1002,7 @@ static void cs4210_spdif_automute(struct spec->spdif_present = spdif_present;/* SPDIF TX on/off */ -if (spdif_present) -snd_hda_set_pin_ctl (codec, spdif_pin, - spdif_present ?PIN_OUT :0 ); +snd_hda_set_pin_ctl (codec, spdif_pin, spdif_present ?PIN_OUT :0 );cs_automute (codec); }
Greg Kroah-Hartman
maintainerPATCH 25/44 ipc: modify message queue accounting to not take kernel data structures into account
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcus Gelderie <[email protected]>
commit de54b9ac253787c366bbfb28d901a31954eb3511 upstream.
A while back, the message queue implementation in the kernel was improved to use btrees to speed up retrieval of messages, in commit d6629859b36d ("ipc/mqueue: improve performance of send/recv").
That patch introducing the improved kernel handling of message queues (using btrees) has, as a by-product, changed the meaning of the QSIZE field in the pseudo-file created for the queue. Before, this field reflected the size of the user-data in the queue. Since, it also takes kernel data structures into account. For example, if 13 bytes of user data are in the queue, on my machine the file reports a size of 61 bytes.
There was some discussion on this topic before (for example
https://lkml.org/lkml/2014/10/1/115). Commenting on a th lkml, Michael Kerrisk gave the following background
(https://lkml.org/lkml/2015/6/16/74):
The pseudofiles in the mqueue filesystem (usually mounted at /dev/mqueue) expose fields with metadata describing a message queue. One of these fields, QSIZE, as originally implemented, showed the total number of bytes of user data in all messages in the message queue, and this feature was documented from the beginning in the mq_overview(7) page. In 3.5, some other (useful) work happened to break the user-space API in a couple of places, including the value exposed via QSIZE, which now includes a measure of kernel overhead bytes for the queue, a figure that renders QSIZE useless for its original purpose, since there's no way to deduce the number of overhead bytes consumed by the implementation. (The other user-space breakage was subsequently fixed.)
This patch removes the accounting of kernel data structures in the queue. Reporting the size of these data-structures in the QSIZE field was a breaking change (see Michael's comment above). Without the QSIZE field reporting the total size of user-data in the queue, there is no way to deduce this number.
It should be noted that the resource limit RLIMIT_MSGQUEUE is counted against the worst-case size of the queue (in both the old and the new implementation). Therefore, the kernel overhead accounting in QSIZE is not necessary to help the user understand the limitations RLIMIT imposes on the processes.
--- ipc/mqueue.c | 5 ----- 1 file changed, 5 deletions(-)
ipc/mqueue.c +0 -5
@@ -143,7 +143,6 @@ static int msg_insert(struct msg_msg *msif (!leaf)return -ENOMEM ;INIT_LIST_HEAD (&leaf->msg_list); - info->qsize +=sizeof (*leaf); } leaf->priority = msg->m_type;rb_link_node (&leaf->rb_node, parent, p);
@@ -188,7 +187,6 @@ try_again: "lazy leaf delete!\n");rb_erase (&leaf->rb_node, &info->msg_tree);if (info->node_cache) { - info->qsize -=sizeof (*leaf);kfree (leaf); }else { info->node_cache = leaf;
@@ -201,7 +199,6 @@ try_again:if (list_empty (&leaf->msg_list)) {rb_erase (&leaf->rb_node, &info->msg_tree);if (info->node_cache) { - info->qsize -=sizeof (*leaf);kfree (leaf); }else { info->node_cache = leaf;
@@ -1026,7 +1023,6 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqd/* Save our speculative allocation into the cache */ INIT_LIST_HEAD (&new_leaf->msg_list); info->node_cache = new_leaf; - info->qsize +=sizeof (*new_leaf); new_leaf =NULL ; }else {kfree (new_leaf);
@@ -1133,7 +1129,6 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t,/* Save our speculative allocation into the cache */ INIT_LIST_HEAD (&new_leaf->msg_list); info->node_cache = new_leaf; - info->qsize +=sizeof (*new_leaf); }else {kfree (new_leaf); }
Greg Kroah-Hartman
maintainerPATCH 26/44 ocfs2: fix BUG in ocfs2_downconvert_thread_do_work()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <[email protected]>
commit 209f7512d007980fd111a74a064d70a3656079cf upstream.
The "BUG_ON(list_empty(&osb->blocked_lock_list))" in ocfs2_downconvert_thread_do_work can be triggered in the following case:
ocfs2dc has firstly saved osb->blocked_lock_count to local varibale processed, and then processes the dentry lockres. During the dentry put, it calls iput and then deletes rw, inode and open lockres from blocked list in ocfs2_mark_lockres_freeing. And this causes the variable `processed' to not reflect the number of blocked lockres to be processed, which triggers the BUG.
--- fs/ocfs2/dlmglue.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
fs/ocfs2/dlmglue.c +7 -3
@@ -3973,9 +3973,13 @@ static void ocfs2_downconvert_thread_do_ osb->dc_work_sequence = osb->dc_wake_sequence; processed = osb->blocked_lock_count; -while (processed) { -BUG_ON (list_empty (&osb->blocked_lock_list)); - +/* +* blocked lock processing in this loop might call iput which can +* remove items off osb->blocked_lock_list. Downconvert up to +* 'processed' number of locks, but stop short if we had some +* removed in ocfs2_mark_lockres_freeing when downconverting. +*/ +while (processed && !list_empty (&osb->blocked_lock_list)) { lockres =list_entry (osb->blocked_lock_list.next, struct ocfs2_lock_res, l_blocked_list);list_del_init (&lockres->l_blocked_list);
Greg Kroah-Hartman
maintainerPATCH 27/44 PCI: Restore PCI_MSIX_FLAGS_BIRMASK definition
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Michael S. Tsirkin" <[email protected]>
commit c9ddbac9c89110f77cb0fa07e634aaf1194899aa upstream.
09a2c73ddfc7 ("PCI: Remove unused PCI_MSIX_FLAGS_BIRMASK definition") removed PCI_MSIX_FLAGS_BIRMASK from an exported header because it was unused in the kernel. But that breaks user programs that were using it (QEMU in particular).
Restore the PCI_MSIX_FLAGS_BIRMASK definition.
--- include/uapi/linux/pci_regs.h | 1 + 1 file changed, 1 insertion(+)
include/uapi/linux/pci_regs.h +1 -0
@@ -319,6 +319,7 @@#define PCI_MSIX_PBA 8/* Pending Bit Array offset */ #define PCI_MSIX_PBA_BIR 0x00000007/* BAR index */ #define PCI_MSIX_PBA_OFFSET 0xfffffff8/* Offset into specified BAR */ +#define PCI_MSIX_FLAGS_BIRMASK PCI_MSIX_PBA_BIR/* deprecated */ #define PCI_CAP_MSIX_SIZEOF 12/* size of MSIX registers */ /* MSI-X Table entry format */
Greg Kroah-Hartman
maintainerPATCH 28/44 md/raid1: extend spinlock to protect raid1_end_read_request against inconsistencies
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 423f04d63cf421ea436bcc5be02543d549ce4b28 upstream.
raid1_end_read_request() assumes that the In_sync bits are consistent with the ->degaded count.raid1_spare_active updates the In_sync bit before the ->degraded count and so exposes an inconsistency, as does error()
So extend the spinlock in raid1_spare_active() and error() to hide those inconsistencies.
This should probably be part of
Commit: 34cab6f42003 ("md/raid1: fix test for 'was read error from last working device'.")
as it addresses the same issue. It fixes the same bug and should go to -stable for same reasons.
--- drivers/md/raid1.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/md/raid1.c +6 -4
@@ -1477,6 +1477,7 @@ static void error(struct mddev *mddev, s {char b[BDEVNAME_SIZE ];struct r1conf *conf = mddev->private; +unsigned long flags;/* * If it is not operational, then we have already marked it as dead
@@ -1496,14 +1497,13 @@ static void error(struct mddev *mddev, sreturn ; }set_bit (Blocked, &rdev->flags); +spin_lock_irqsave (&conf->device_lock, flags);if (test_and_clear_bit (In_sync, &rdev->flags)) { -unsigned long flags; -spin_lock_irqsave (&conf->device_lock, flags); mddev->degraded++;set_bit (Faulty, &rdev->flags); -spin_unlock_irqrestore (&conf->device_lock, flags); }else set_bit (Faulty, &rdev->flags); +spin_unlock_irqrestore (&conf->device_lock, flags);/* * if recovery is running, make sure it aborts. */
@@ -1569,7 +1569,10 @@ static int raid1_spare_active(struct mdd* Find all failed disks within the RAID1 configuration * and mark them readable. * Called under mddev lock, so rcu protection not needed. +* device_lock used to avoid races with raid1_end_read_request +* which expects 'In_sync' flags and ->degraded to be consistent. */ +spin_lock_irqsave (&conf->device_lock, flags);for (i =0 ; i < conf->raid_disks; i++) {struct md_rdev *rdev = conf->mirrors[i].rdev;struct md_rdev *repl = conf->mirrors[conf->raid_disks + i].rdev;
@@ -1599,7 +1602,6 @@ static int raid1_spare_active(struct mddsysfs_notify_dirent_safe (rdev->sysfs_state); } } -spin_lock_irqsave (&conf->device_lock, flags); mddev->degraded -= count;spin_unlock_irqrestore (&conf->device_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 29/44 sg_start_req(): make sure that theres not too many elements in iovec
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 451a2886b6bf90e2fb378f7c46c655450fb96e81 upstream.
unfortunately, allowing an arbitrary 16bit value means a possibility of overflow in the calculation of total number of pages in bio_map_user_iov() - we rely on there being no more than PAGE_SIZE members of sum in the first loop there. If that sum wraps around, we end up allocating too small array of pointers to pages and it's easy to overflow it in the second loop.
X-Coverup: TINC (and there's no lumber cartel either)
[bwh: s/MAX_UIOVEC/UIO_MAXIOV/. This was fixed upstream by commit
fdc81f45e9f5 ("sg_start_req(): use import_iovec()"), but we don't have
that function.]
--- drivers/scsi/sg.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/scsi/sg.c +3 -0
@@ -1694,6 +1694,9 @@ static int sg_start_req(Sg_request *srp, md->from_user =0 ; } +if (unlikely (iov_count >UIO_MAXIOV )) +return -EINVAL ; +if (iov_count) {int len, size =sizeof (struct sg_iovec ) * iov_count;struct iovec *iov;
Greg Kroah-Hartman
maintainerPATCH 30/44 signalfd: fix information leak in signalfd_copyinfo
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amanieu d'Antras <[email protected]>
commit 3ead7c52bdb0ab44f4bb1feed505a8323cc12ba7 upstream.
This function may copy the si_addr_lsb field to user mode when it hasn't been initialized, which can leak kernel stack data to user mode.
Just checking the value of si_code is insufficient because the same si_code value is shared between multiple signals. This is solved by checking the value of si_signo in addition to si_code.
--- fs/signalfd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/signalfd.c +3 -2
@@ -121,8 +121,9 @@ static int signalfd_copyinfo(struct sign* Other callers might not initialize the si_lsb field, * so check explicitly for the right codes here. */ -if (kinfo->si_code ==BUS_MCEERR_AR || - kinfo->si_code ==BUS_MCEERR_AO ) +if (kinfo->si_signo ==SIGBUS && + (kinfo->si_code ==BUS_MCEERR_AR || + kinfo->si_code ==BUS_MCEERR_AO )) err |=__put_user ((short ) kinfo->si_addr_lsb, &uinfo->ssi_addr_lsb);#endif
Re: [PATCH 3.14 30/44] signalfd: fix information leak in signalfd_copyinfo
Quoted 2 lines · Greg Kroah-Hartman
3.14-stable review patch. If anyone has any objections, please let me know.
These 3 patches seem to be relevant to other stable trees as well. I'm queuing them for the 3.16 kernel.
Cheers,
--
Lu�s
Quoted 44 lines
------------------
From: Amanieu d'Antras <[email protected]>
commit
3ead7c52bdb0ab44f4bb1feed505a8323cc12ba7upstream.This function may copy the
si_addr_lsbfield to user mode when it hasn't been initialized, which can leak kernel stack data to user mode.Just checking the value of
si_codeis insufficient because the samesi_codevalue is shared between multiple signals. This is solved by checking the value ofsi_signoin addition tosi_code.Signed-off-by Amanieu d'Antras <[email protected]>Cc Oleg Nesterov <[email protected]>Cc Ingo Molnar <[email protected]>Signed-off-by Andrew Morton <[email protected]>Signed-off-by Linus Torvalds <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/signalfd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)fs/signalfd.c +3
-3@@ -121,8 +121,9 @@ static int signalfd_copyinfo(struct sign* Other callers might not initialize the si_lsb field, * so check explicitly for the right codes here. */ -if (kinfo->si_code ==BUS_MCEERR_AR || - kinfo->si_code ==BUS_MCEERR_AO ) +if (kinfo->si_signo ==SIGBUS && + (kinfo->si_code ==BUS_MCEERR_AR || + kinfo->si_code ==BUS_MCEERR_AO )) err |=__put_user ((short ) kinfo->si_addr_lsb, &uinfo->ssi_addr_lsb);#endif --To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Greg Kroah-Hartman
maintainerPATCH 31/44 signal: fix information leak in copy_siginfo_to_user
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amanieu d'Antras <[email protected]>
commit 26135022f85105ad725cda103fa069e29e83bd16 upstream.
This function may copy the si_addr_lsb, si_lower and si_upper fields to user mode when they haven't been initialized, which can leak kernel stack data to user mode.
Just checking the value of si_code is insufficient because the same si_code value is shared between multiple signals. This is solved by checking the value of si_signo in addition to si_code.
--- arch/arm64/kernel/signal32.c | 3 ++- kernel/signal.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
arch/arm64/kernel/signal32.c +2 -1
@@ -165,7 +165,8 @@ int copy_siginfo_to_user32(compat_siginf* Other callers might not initialize the si_lsb field, * so check explicitely for the right codes here. */ -if (from->si_code ==BUS_MCEERR_AR || from->si_code ==BUS_MCEERR_AO ) +if (from->si_signo ==SIGBUS && + (from->si_code ==BUS_MCEERR_AR || from->si_code ==BUS_MCEERR_AO )) err |=__put_user (from->si_addr_lsb, &to->si_addr_lsb);#endif break ;
kernel/signal.c +2 -1
@@ -2768,7 +2768,8 @@ int copy_siginfo_to_user(siginfo_t __use* Other callers might not initialize the si_lsb field, * so check explicitly for the right codes here. */ -if (from->si_code ==BUS_MCEERR_AR || from->si_code ==BUS_MCEERR_AO ) +if (from->si_signo ==SIGBUS && + (from->si_code ==BUS_MCEERR_AR || from->si_code ==BUS_MCEERR_AO )) err |=__put_user (from->si_addr_lsb, &to->si_addr_lsb);#endif break ;
Greg Kroah-Hartman
maintainerPATCH 32/44 signal: fix information leak in copy_siginfo_from_user32
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amanieu d'Antras <[email protected]>
commit 3c00cb5e68dc719f2fc73a33b1b230aadfcb1309 upstream.
This function can leak kernel stack data when the user siginfo_t has a positive si_code value. The top 16 bits of si_code descibe which fields in the siginfo_t union are active, but they are treated inconsistently between copy_siginfo_from_user32, copy_siginfo_to_user32 and copy_siginfo_to_user.
copy_siginfo_from_user32 is called from rt_sigqueueinfo and rt_tgsigqueueinfo in which the user has full control overthe top 16 bits of si_code.
This fixes the following information leaks:
x86: 8 bytes leaked when sending a signal from a 32-bit process to
itself. This leak grows to 16 bytes if the process uses x32. (si_code = __SI_CHLD)
x86: 100 bytes leaked when sending a signal from a 32-bit process to
a 64-bit process. (si_code = -1)
sparc: 4 bytes leaked when sending a signal from a 32-bit process to a
64-bit process. (si_code = any)parsic and s390 have similar bugs, but they are not vulnerable because rt_[tg]sigqueueinfo have checks that prevent sending a positive si_code to a different process. These bugs are also fixed for consistency.
--- arch/arm64/kernel/signal32.c | 2 -- arch/mips/kernel/signal32.c | 2 -- arch/powerpc/kernel/signal_32.c | 2 -- kernel/signal.c | 4 ++-- 4 files changed, 2 insertions(+), 8 deletions(-)
arch/arm64/kernel/signal32.c +0 -2
@@ -193,8 +193,6 @@ int copy_siginfo_to_user32(compat_siginfint copy_siginfo_from_user32 (siginfo_t *to,compat_siginfo_t __user *from) { -memset (to,0 ,sizeof *to); -if (copy_from_user (to, from, __ARCH_SI_PREAMBLE_SIZE) ||copy_from_user (to->_sifields._pad, from->_sifields._pad,SI_PAD_SIZE ))
arch/mips/kernel/signal32.c +0 -2
@@ -370,8 +370,6 @@ int copy_siginfo_to_user32(compat_siginfint copy_siginfo_from_user32 (siginfo_t *to,compat_siginfo_t __user *from) { -memset (to,0 ,sizeof *to); -if (copy_from_user (to, from,3 *sizeof (int )) ||copy_from_user (to->_sifields._pad, from->_sifields._pad,SI_PAD_SIZE32 ))
arch/powerpc/kernel/signal_32.c +0 -2
@@ -967,8 +967,6 @@ int copy_siginfo_to_user32(struct compatint copy_siginfo_from_user32 (siginfo_t *to,struct compat_siginfo __user *from) { -memset (to,0 ,sizeof *to); -if (copy_from_user (to, from,3 *sizeof (int )) ||copy_from_user (to->_sifields._pad, from->_sifields._pad,SI_PAD_SIZE32 ))
kernel/signal.c +2 -2
@@ -3036,7 +3036,7 @@ COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo, int, sig, struct compat_siginfo __user *, uinfo) { - siginfo_t info; + siginfo_t info = {};int ret =copy_siginfo_from_user32 (&info, uinfo);if (unlikely (ret))return ret;
@@ -3082,7 +3082,7 @@ COMPAT_SYSCALL_DEFINE4(rt_tgsigqueueinfo int, sig, struct compat_siginfo __user *, uinfo) { - siginfo_t info; + siginfo_t info = {};if (copy_siginfo_from_user32 (&info, uinfo))return -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 33/44 fold d_kill() and d_free()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 03b3b889e79cdb6b806fc0ba9be0d71c186bbfaa upstream.
--- fs/dcache.c | 77 ++++++++++++++++++------------------------------------------ 1 file changed, 24 insertions(+), 53 deletions(-)
fs/dcache.c +24 -53
@@ -244,24 +244,6 @@ static void __d_free(struct rcu_head *hekmem_cache_free (dentry_cache, dentry); } -/* -* no locks, please. -*/ -static void d_free (struct dentry *dentry) -{ -WARN_ON (!hlist_unhashed (&dentry->d_u.d_alias)); -BUG_ON ((int )dentry->d_lockref.count >0 ); -this_cpu_dec (nr_dentry); -if (dentry->d_op && dentry->d_op->d_release) - dentry->d_op->d_release (dentry); - -/* if dentry was never visible to RCU, immediate free is OK */ -if (!(dentry->d_flags &DCACHE_RCUACCESS )) -__d_free (&dentry->d_u.d_rcu); -else -call_rcu (&dentry->d_u.d_rcu, __d_free); -} -/** * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups * @dentry: the target dentry
@@ -419,40 +401,6 @@ static void dentry_lru_del(struct dentry }/** -* d_kill - kill dentry and return parent -* @dentry: dentry to kill -* @parent: parent dentry -* -* The dentry must already be unhashed and removed from the LRU. -* -* If this is the root of the dentry tree, return NULL. -* -* dentry->d_lock and parent->d_lock must be held by caller, and are dropped by -* d_kill. -*/ -static struct dentry *d_kill (struct dentry *dentry,struct dentry *parent) - __releases(dentry->d_lock) - __releases(parent->d_lock) - __releases(dentry->d_inode->i_lock) -{ -__list_del_entry (&dentry->d_child); -/* -* Inform d_walk() that we are no longer attached to the -* dentry tree -*/ - dentry->d_flags |=DCACHE_DENTRY_KILLED ; -if (parent) -spin_unlock (&parent->d_lock); -dentry_iput (dentry); -/* -* dentry_iput drops the locks, at which point nobody (except -* transient RCU lookups) can reach this dentry. -*/ -d_free (dentry); -return parent; -} - -/** * d_drop - drop a dentry * @dentry: dentry to drop *
@@ -545,7 +493,30 @@ relock:dentry_lru_del (dentry);/* if it was on the hash then remove it */ __d_drop (dentry); -return d_kill (dentry, parent); +__list_del_entry (&dentry->d_child); +/* +* Inform d_walk() that we are no longer attached to the +* dentry tree +*/ + dentry->d_flags |=DCACHE_DENTRY_KILLED ; +if (parent) +spin_unlock (&parent->d_lock); +dentry_iput (dentry); +/* +* dentry_iput drops the locks, at which point nobody (except +* transient RCU lookups) can reach this dentry. +*/ +BUG_ON ((int )dentry->d_lockref.count >0 ); +this_cpu_dec (nr_dentry); +if (dentry->d_op && dentry->d_op->d_release) + dentry->d_op->d_release (dentry); + +/* if dentry was never visible to RCU, immediate free is OK */ +if (!(dentry->d_flags &DCACHE_RCUACCESS )) +__d_free (&dentry->d_u.d_rcu); +else +call_rcu (&dentry->d_u.d_rcu, __d_free); +return parent; }/*
Greg Kroah-Hartman
maintainerPATCH 34/44 fold try_prune_one_dentry()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 5c47e6d0ad608987b91affbcf7d1fc12dfbe8fb4 upstream.
--- fs/dcache.c | 75 ++++++++++++++++++++---------------------------------------- 1 file changed, 25 insertions(+), 50 deletions(-)
fs/dcache.c +25 -50
@@ -788,47 +788,9 @@ restart: }EXPORT_SYMBOL (d_prune_aliases); -/* -* Try to throw away a dentry - free the inode, dput the parent. -* Requires dentry->d_lock is held, and dentry->d_count == 0. -* Releases dentry->d_lock. -* -* This may fail if locks cannot be acquired no problem, just try again. -*/ -static struct dentry *try_prune_one_dentry (struct dentry *dentry) - __releases(dentry->d_lock) -{ -struct dentry *parent; - - parent =dentry_kill (dentry,0 ); -/* -* If dentry_kill returns NULL, we have nothing more to do. -* if it returns the same dentry, trylocks failed. In either -* case, just loop again. -* -* Otherwise, we need to prune ancestors too. This is necessary -* to prevent quadratic behavior of shrink_dcache_parent(), but -* is also expected to be beneficial in reducing dentry cache -* fragmentation. -*/ -if (!parent) -return NULL ; -if (parent == dentry) -return dentry; - -/* Prune ancestors. */ - dentry = parent; -while (dentry) { -if (lockref_put_or_lock (&dentry->d_lockref)) -return NULL ; - dentry =dentry_kill (dentry,1 ); - } -return NULL ; -} -static void shrink_dentry_list (struct list_head *list) { -struct dentry *dentry; +struct dentry *dentry, *parent;rcu_read_lock ();for (;;) {
@@ -864,22 +826,35 @@ static void shrink_dentry_list(struct li }rcu_read_unlock (); + parent =dentry_kill (dentry,0 );/* -* If 'try_to_prune()' returns a dentry, it will -* be the same one we passed in, and d_lock will -* have been held the whole time, so it will not -* have been added to any other lists. We failed -* to get the inode lock. -* -* We just add it back to the shrink list. +* If dentry_kill returns NULL, we have nothing more to do. */ - dentry =try_prune_one_dentry (dentry); - -rcu_read_lock (); -if (dentry) { +if (!parent) { +rcu_read_lock (); +continue ; + } +if (unlikely (parent == dentry)) { +/* +* trylocks have failed and d_lock has been held the +* whole time, so it could not have been added to any +* other lists. Just add it back to the shrink list. +*/ +rcu_read_lock ();d_shrink_add (dentry, list);spin_unlock (&dentry->d_lock); +continue ; } +/* +* We need to prune ancestors too. This is necessary to prevent +* quadratic behavior of shrink_dcache_parent(), but is also +* expected to be beneficial in reducing dentry cache +* fragmentation. +*/ + dentry = parent; +while (dentry && !lockref_put_or_lock (&dentry->d_lockref)) + dentry =dentry_kill (dentry,1 ); +rcu_read_lock (); }rcu_read_unlock (); }
Greg Kroah-Hartman
maintainerPATCH 35/44 new helper: dentry_free()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit b4f0354e968f5fabd39bc85b99fedae4a97589fe upstream.
The part of old d_free() that dealt with actual freeing of dentry. Taken out of dentry_kill() into a separate function.
--- fs/dcache.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
fs/dcache.c +10 -5
@@ -244,6 +244,15 @@ static void __d_free(struct rcu_head *hekmem_cache_free (dentry_cache, dentry); } +static void dentry_free (struct dentry *dentry) +{ +/* if dentry was never visible to RCU, immediate free is OK */ +if (!(dentry->d_flags &DCACHE_RCUACCESS )) +__d_free (&dentry->d_u.d_rcu); +else +call_rcu (&dentry->d_u.d_rcu, __d_free); +} +/** * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups * @dentry: the target dentry
@@ -511,11 +520,7 @@ relock:if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release (dentry); -/* if dentry was never visible to RCU, immediate free is OK */ -if (!(dentry->d_flags &DCACHE_RCUACCESS )) -__d_free (&dentry->d_u.d_rcu); -else -call_rcu (&dentry->d_u.d_rcu, __d_free); +dentry_free (dentry);return parent; }
Greg Kroah-Hartman
maintainerPATCH 36/44 expand the call of dentry_lru_del() in dentry_kill()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 01b6035190b024240a43ac1d8e9c6f964f5f1c63 upstream.
--- fs/dcache.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
fs/dcache.c +6 -1
@@ -499,7 +499,12 @@ relock:if ((dentry->d_flags &DCACHE_OP_PRUNE ) && !d_unhashed (dentry)) dentry->d_op->d_prune (dentry); -dentry_lru_del (dentry); +if (dentry->d_flags &DCACHE_LRU_LIST ) { +if (!(dentry->d_flags &DCACHE_SHRINK_LIST )) +d_lru_del (dentry); +else +d_shrink_del (dentry); + }/* if it was on the hash then remove it */ __d_drop (dentry);__list_del_entry (&dentry->d_child);
Greg Kroah-Hartman
maintainerPATCH 37/44 dentry_kill(): dont try to remove from shrink list
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 41edf278fc2f042f4e22a12ed87d19c5201210e1 upstream.
If the victim in on the shrink list, don't remove it from there. If shrink_dentry_list() manages to remove it from the list before we are done - fine, we'll just free it as usual. If not - mark it with new flag (DCACHE_MAY_FREE) and leave it there.
Eventually, shrink_dentry_list() will get to it, remove the sucker from shrink list and call dentry_kill(dentry, 0). Which is where we'll deal with freeing.
Since now dentry_kill(dentry, 0) may happen after or during dentry_kill(dentry, 1), we need to recognize that (by seeing DCACHE_DENTRY_KILLED already set), unlock everything and either free the sucker (in case DCACHE_MAY_FREE has been set) or leave it for ongoing dentry_kill(dentry, 1) to deal with.
--- fs/dcache.c | 27 +++++++++++++++++++-------- include/linux/dcache.h | 2 ++ 2 files changed, 21 insertions(+), 8 deletions(-)
fs/dcache.c +19 -8
@@ -466,7 +466,14 @@ dentry_kill(struct dentry *dentry, int u __releases(dentry->d_lock) {struct inode *inode; -struct dentry *parent; +struct dentry *parent =NULL ; +bool can_free = true; + +if (unlikely (dentry->d_flags &DCACHE_DENTRY_KILLED )) { + can_free = dentry->d_flags &DCACHE_MAY_FREE ; +spin_unlock (&dentry->d_lock); + goto out; + } inode = dentry->d_inode;if (inode && !spin_trylock (&inode->i_lock)) {
@@ -477,9 +484,7 @@ relock: }return dentry;/* try again with same dentry */ } -if (IS_ROOT (dentry)) - parent =NULL ; -else +if (!IS_ROOT (dentry)) parent = dentry->d_parent;if (parent && !spin_trylock (&parent->d_lock)) {if (inode)
@@ -502,8 +507,6 @@ relock:if (dentry->d_flags &DCACHE_LRU_LIST ) {if (!(dentry->d_flags &DCACHE_SHRINK_LIST ))d_lru_del (dentry); -else -d_shrink_del (dentry); }/* if it was on the hash then remove it */ __d_drop (dentry);
@@ -525,7 +528,15 @@ relock:if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release (dentry); -dentry_free (dentry); +spin_lock (&dentry->d_lock); +if (dentry->d_flags &DCACHE_SHRINK_LIST ) { + dentry->d_flags |=DCACHE_MAY_FREE ; + can_free = false; + } +spin_unlock (&dentry->d_lock); +out: +if (likely (can_free)) +dentry_free (dentry);return parent; }
@@ -830,7 +841,7 @@ static void shrink_dentry_list(struct li* We found an inuse dentry which was not removed from * the LRU because of laziness during lookup. Do not free it. */ -if (dentry->d_lockref.count) { +if ((int )dentry->d_lockref.count >0 ) {spin_unlock (&dentry->d_lock);continue ; }
include/linux/dcache.h +2 -0
@@ -221,6 +221,8 @@ struct dentry_operations {#define DCACHE_SYMLINK_TYPE 0x00300000/* Symlink */ #define DCACHE_FILE_TYPE 0x00400000/* Other file type */ +#define DCACHE_MAY_FREE 0x00800000 +extern seqlock_t rename_lock;static inline int dname_external (const struct dentry *dentry)
Greg Kroah-Hartman
maintainerPATCH 38/44 dont remove from shrink list in select_collect()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit fe91522a7ba82ca1a51b07e19954b3825e4aaa22 upstream.
If we find something already on a shrink list, just incrementdata->found and do nothing else. Loops in shrink_dcache_parent() and check_submounts_and_drop() will do the right thing - everything we did put into our list will be evicted and if there had been nothing, but data->found got non-zero, well, we have somebody else shrinking those guys; just try again.
--- fs/dcache.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-)
fs/dcache.c +10 -21
@@ -1231,34 +1231,23 @@ static enum d_walk_ret select_collect(voif (data->start == dentry) goto out; -/* -* move only zero ref count dentries to the dispose list. -* -* Those which are presently on the shrink list, being processed -* by shrink_dentry_list(), shouldn't be moved. Otherwise the -* loop in shrink_dcache_parent() might not make any progress -* and loop forever. -*/ -if (dentry->d_lockref.count) { -dentry_lru_del (dentry); - }else if (!(dentry->d_flags &DCACHE_SHRINK_LIST )) { -/* -* We can't use d_lru_shrink_move() because we -* need to get the global LRU lock and do the -* LRU accounting. -*/ -d_lru_del (dentry); -d_shrink_add (dentry, &data->dispose); +if (dentry->d_flags &DCACHE_SHRINK_LIST ) { data->found++; - ret =D_WALK_NORETRY ; + }else { +if (dentry->d_flags &DCACHE_LRU_LIST ) +d_lru_del (dentry); +if (!dentry->d_lockref.count) { +d_shrink_add (dentry, &data->dispose); + data->found++; + } }/* * We can return to the caller if we have found some (this * ensures forward progress). We'll be coming back to find * the rest. */ -if (data->found &&need_resched ()) - ret =D_WALK_QUIT ; +if (!list_empty (&data->dispose)) + ret =need_resched () ?D_WALK_QUIT :D_WALK_NORETRY ; out:return ret; }
Greg Kroah-Hartman
maintainerPATCH 39/44 more graceful recovery in umount_collect()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 9c8c10e262e0f62cb2530f1b076de979123183dd upstream.
Start with shrink_dcache_parent(), then scan what remains.
First of all, BUG() is very much an overkill here; we are holding ->s_umount, and hitting BUG() means that a lot of interesting stuff will be hanging after that point (sync(2), for example). Moreover, in cases when there had been more than one leak, we'll be better off reporting all of them. And more than just the last component of pathname - %pd is there for just such uses...
That was the last user of dentry_lru_del(), so kill it off...
--- fs/dcache.c | 101 ++++++++++++++---------------------------------------------- 1 file changed, 25 insertions(+), 76 deletions(-)
fs/dcache.c +25 -76
@@ -393,22 +393,6 @@ static void dentry_lru_add(struct dentryd_lru_add (dentry); } -/* -* Remove a dentry with references from the LRU. -* -* If we are on the shrink list, then we can get to try_prune_one_dentry() and -* lose our last reference through the parent walk. In this case, we need to -* remove ourselves from the shrink list, not the LRU. -*/ -static void dentry_lru_del (struct dentry *dentry) -{ -if (dentry->d_flags &DCACHE_LRU_LIST ) { -if (dentry->d_flags &DCACHE_SHRINK_LIST ) -return d_shrink_del (dentry); -d_lru_del (dentry); - } -} -/** * d_drop - drop a dentry * @dentry: dentry to drop
@@ -1277,45 +1261,35 @@ void shrink_dcache_parent(struct dentry }EXPORT_SYMBOL (shrink_dcache_parent); -static enum d_walk_ret umount_collect (void *_data,struct dentry *dentry) +static enum d_walk_ret umount_check (void *_data,struct dentry *dentry) { -struct select_data *data = _data; -enum d_walk_ret ret =D_WALK_CONTINUE ; +/* it has busy descendents; complain about those instead */ +if (!list_empty (&dentry->d_subdirs)) +return D_WALK_CONTINUE ; + +/* root with refcount 1 is fine */ +if (dentry == _data && dentry->d_lockref.count ==1 ) +return D_WALK_CONTINUE ; -if (dentry->d_lockref.count) { -dentry_lru_del (dentry); -if (likely (!list_empty (&dentry->d_subdirs))) - goto out; -if (dentry == data->start && dentry->d_lockref.count ==1 ) - goto out; -printk (KERN_ERR -"BUG: Dentry %p{i=%lx,n=%s}" -" still in use (%d)" -" [unmount of %s %s]\n" , +printk (KERN_ERR "BUG: Dentry %p{i=%lx,n=%pd} " +" still in use (%d) [unmount of %s %s]\n" , dentry, dentry->d_inode ? dentry->d_inode->i_ino :0UL , - dentry->d_name.name, + dentry, dentry->d_lockref.count, dentry->d_sb->s_type->name, dentry->d_sb->s_id); -BUG (); - }else if (!(dentry->d_flags &DCACHE_SHRINK_LIST )) { -/* -* We can't use d_lru_shrink_move() because we -* need to get the global LRU lock and do the -* LRU accounting. -*/ -if (dentry->d_flags &DCACHE_LRU_LIST ) -d_lru_del (dentry); -d_shrink_add (dentry, &data->dispose); - data->found++; - ret =D_WALK_NORETRY ; - } -out: -if (data->found &&need_resched ()) - ret =D_WALK_QUIT ; -return ret; +WARN_ON (1 ); +return D_WALK_CONTINUE ; +} + +static void do_one_tree (struct dentry *dentry) +{ +shrink_dcache_parent (dentry); +d_walk (dentry, dentry, umount_check,NULL ); +d_drop (dentry); +dput (dentry); }/*
@@ -1325,40 +1299,15 @@ void shrink_dcache_for_umount(struct sup {struct dentry *dentry; -if (down_read_trylock (&sb->s_umount)) -BUG (); +WARN (down_read_trylock (&sb->s_umount),"s_umount should've been locked" ); dentry = sb->s_root; sb->s_root =NULL ; -for (;;) { -struct select_data data; - -INIT_LIST_HEAD (&data.dispose); - data.start = dentry; - data.found =0 ; - -d_walk (dentry, &data, umount_collect,NULL ); -if (!data.found) -break ; - -shrink_dentry_list (&data.dispose); -cond_resched (); - } -d_drop (dentry); -dput (dentry); +do_one_tree (dentry);while (!hlist_bl_empty (&sb->s_anon)) { -struct select_data data; - dentry = hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash); - -INIT_LIST_HEAD (&data.dispose); - data.start =NULL ; - data.found =0 ; - -d_walk (dentry, &data, umount_collect,NULL ); -if (data.found) -shrink_dentry_list (&data.dispose); -cond_resched (); + dentry = dget(hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash)); +do_one_tree (dentry); } }
Greg Kroah-Hartman
maintainerPATCH 40/44 dcache: dont need rcu in shrink_dentry_list()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit 60942f2f235ce7b817166cdf355eed729094834d upstream.
Since now the shrink list is private and nobody can free the dentry while it is on the shrink list, we can remove RCU protection from this.
--- fs/dcache.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-)
fs/dcache.c +4 -23
@@ -797,23 +797,9 @@ static void shrink_dentry_list(struct li {struct dentry *dentry, *parent; -rcu_read_lock (); -for (;;) { - dentry = list_entry_rcu(list->prev, struct dentry, d_lru); -if (&dentry->d_lru == list) -break ;/* empty */ - -/* -* Get the dentry lock, and re-verify that the dentry is -* this on the shrinking list. If it is, we know that -* DCACHE_SHRINK_LIST and DCACHE_LRU_LIST are set. -*/ +while (!list_empty (list)) { + dentry = list_entry(list->prev, struct dentry, d_lru);spin_lock (&dentry->d_lock); - if (dentry != list_entry(list->prev, struct dentry, d_lru)) { -spin_unlock (&dentry->d_lock); -continue ; - } -/* * The dispose list is isolated and dentries are not accounted * to the LRU here, so we can simply remove it from the list
@@ -829,23 +815,20 @@ static void shrink_dentry_list(struct lispin_unlock (&dentry->d_lock);continue ; } -rcu_read_unlock (); parent =dentry_kill (dentry,0 );/* * If dentry_kill returns NULL, we have nothing more to do. */ -if (!parent) { -rcu_read_lock (); +if (!parent)continue ; - } +if (unlikely (parent == dentry)) {/* * trylocks have failed and d_lock has been held the * whole time, so it could not have been added to any * other lists. Just add it back to the shrink list. */ -rcu_read_lock ();d_shrink_add (dentry, list);spin_unlock (&dentry->d_lock);continue ;
@@ -859,9 +842,7 @@ static void shrink_dentry_list(struct li dentry = parent;while (dentry && !lockref_put_or_lock (&dentry->d_lockref)) dentry =dentry_kill (dentry,1 ); -rcu_read_lock (); } -rcu_read_unlock (); } static enum lru_status
Greg Kroah-Hartman
maintainerPATCH 41/44 kvm: x86: fix kvm_apic_has_events to check for NULL pointer
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Bonzini <[email protected]>
commit ce40cd3fc7fa40a6119e5fe6c0f2bc0eb4541009 upstream.
Malicious (or egregiously buggy) userspace can trigger it, but it should never happen in normal operation.
--- arch/x86/kvm/lapic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/lapic.h +1 -1
@@ -165,7 +165,7 @@ static inline u16 apic_logical_id(structstatic inline bool kvm_apic_has_events (struct kvm_vcpu *vcpu) { -return vcpu->arch.apic->pending_events; +return kvm_vcpu_has_lapic (vcpu) && vcpu->arch.apic->pending_events; }bool kvm_apic_pending_eoi (struct kvm_vcpu *vcpu,int vector);
Greg Kroah-Hartman
maintainerPATCH 42/44 path_openat(): fix double fput()
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit f15133df088ecadd141ea1907f2c96df67c729f0 upstream.
path_openat() jumps to the wrong place after do_tmpfile() - it has already done path_cleanup() (as part of path_lookupat() called by do_tmpfile()), so doing that again can lead to double fput().
--- fs/namei.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/namei.c +2 -1
@@ -3171,7 +3171,7 @@ static struct file *path_openat(int dfd,if (unlikely (file->f_flags & __O_TMPFILE)) { error =do_tmpfile (dfd, pathname, nd, flags, op, file, &opened); - goto out; + goto out2; } error =path_init (dfd, pathname->name, flags |LOOKUP_PARENT , nd, &base);
@@ -3209,6 +3209,7 @@ out:path_put (&nd->root);if (base)fput (base); +out2:if (!(opened &FILE_OPENED )) {BUG_ON (!error);put_filp (file);
Greg Kroah-Hartman
maintainerPATCH 43/44 md/bitmap: return an error when bitmap superblock is corrupt.
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit b97e92574c0bf335db1cd2ec491d8ff5cd5d0b49 upstream
Use separate bitmaps for each nodes in the cluster
bitmap_read_sb() validates the bitmap superblock that it reads in. If it finds an inconsistency like a bad magic number or out-of-range version number, it prints an error and returns, but it incorrectly returns zero, so the array is still assembled with the (invalid) bitmap.
This means it could try to use a bitmap with a new version number which it therefore does not understand.
This bug was introduced in 3.5 and fix as part of a larger patch in 4.1. So the patch is suitable for any -stable kernel in that range.
--- drivers/md/bitmap.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/md/bitmap.c +2 -0
@@ -564,6 +564,8 @@ static int bitmap_read_sb(struct bitmapif (err)return err; + err = -EINVAL ; + sb =kmap_atomic (sb_page); chunksize =le32_to_cpu (sb->chunksize);
Greg Kroah-Hartman
maintainerPATCH 44/44 mm, vmscan: Do not wait for page writeback for GFP_NOFS allocations
In reply to Greg Kroah-Hartman3.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <[email protected]>
commit ecf5fc6e9654cd7a268c782a523f072b2f1959f9 upstream.
Nikolay has reported a hang when a memcg reclaim got stuck with the following backtrace:
PID: 18308 TASK: ffff883d7c9b0a30 CPU: 1 COMMAND: "rsync"
#0 __schedule at ffffffff815ab152
#1 schedule at ffffffff815ab76e
#2 schedule_timeout at ffffffff815ae5e5
#3 io_schedule_timeout at ffffffff815aad6a #4 bit_wait_io at ffffffff815abfc6
#5 __wait_on_bit at ffffffff815abda5
#6 wait_on_page_bit at ffffffff8111fd4f
#7 shrink_page_list at ffffffff81135445
#8 shrink_inactive_list at ffffffff81135845 #9 shrink_lruvec at ffffffff81135ead
#10 shrink_zone at ffffffff811360c3
#11 shrink_zones at ffffffff81136eff
#12 do_try_to_free_pages at ffffffff8113712f #13 try_to_free_mem_cgroup_pages at ffffffff811372be #14 try_charge at ffffffff81189423
#15 mem_cgroup_try_charge at ffffffff8118c6f5 #16 __add_to_page_cache_locked at ffffffff8112137d #17 add_to_page_cache_lru at ffffffff81121618 #18 pagecache_get_page at ffffffff8112170b #19 grow_dev_page at ffffffff811c8297
#20 __getblk_slow at ffffffff811c91d6
#21 __getblk_gfp at ffffffff811c92c1
#22 ext4_ext_grow_indepth at ffffffff8124565c #23 ext4_ext_create_new_leaf at ffffffff81246ca8 #24 ext4_ext_insert_extent at ffffffff81246f09 #25 ext4_ext_map_blocks at ffffffff8124a848 #26 ext4_map_blocks at ffffffff8121a5b7
#27 mpage_map_one_extent at ffffffff8121b1fa #28 mpage_map_and_submit_extent at ffffffff8121f07b #29 ext4_writepages at ffffffff8121f6d5
#30 do_writepages at ffffffff8112c490
#31 __filemap_fdatawrite_range at ffffffff81120199 #32 filemap_flush at ffffffff8112041c
#33 ext4_alloc_da_blocks at ffffffff81219da1 #34 ext4_rename at ffffffff81229b91
#35 ext4_rename2 at ffffffff81229e32
#36 vfs_rename at ffffffff811a08a5
#37 SYSC_renameat2 at ffffffff811a3ffc
#38 sys_renameat2 at ffffffff811a408e
#39 sys_rename at ffffffff8119e51e
#40 system_call_fastpath at ffffffff815afa89
Dave Chinner has properly pointed out that this is a deadlock in the reclaim code because ext4 doesn't submit pages which are marked by PG_writeback right away.
The heuristic was introduced by commit e62e384e9da8 ("memcg: prevent OOM with too many dirty pages") and it was applied only when may_enter_fs was specified. The code has been changed by c3b94f44fcb0 ("memcg:
further prevent OOM with too many dirty pages") which has removed the __GFP_FS restriction with a reasoning that we do not get into the fs code. But this is not sufficient apparently because the fs doesn't necessarily submit pages marked PG_writeback for IO right away.
ext4_bio_write_page calls io_submit_add_bh but that doesn't necessarily submit the bio. Instead it tries to map more pages into the bio and mpage_map_one_extent might trigger memcg charge which might end up waiting on a page which is marked PG_writeback but hasn't been submitted yet so we would end up waiting for something that never finishes.
Fix this issue by replacing __GFP_IO by may_enter_fs check (for case 2) before we go to wait on the writeback. The page fault path, which is the only path that triggers memcg oom killer since 3.12, shouldn't require GFP_NOFS and so we shouldn't reintroduce the premature OOM killer issue which was originally addressed by the heuristic.
As per David Chinner the xfs is doing similar thing since 2.6.15 already so ext4 is not the only affected filesystem. Moreover he notes:
: For example: IO completion might require unwritten extent conversion : which executes filesystem transactions and GFP_NOFS allocations. The : writeback flag on the pages can not be cleared until unwritten : extent conversion completes. Hence memory reclaim cannot wait on : page writeback to complete in GFP_NOFS context because it is not : safe to do so, memcg reclaim or otherwise.
--- mm/vmscan.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
mm/vmscan.c +5 -9
@@ -871,21 +871,17 @@ static unsigned long shrink_page_list(st* * 2) Global reclaim encounters a page, memcg encounters a * page that is not marked for immediate reclaim or -* the caller does not have __GFP_IO. In this case mark +* the caller does not have __GFP_FS (or __GFP_IO if it's +* simply going to swap, not to fs). In this case mark * the page for immediate reclaim and continue scanning. * -* __GFP_IO is checked because a loop driver thread might +* Require may_enter_fs because we would wait on fs, which +* may not have submitted IO yet. And the loop driver might * enter reclaim, and deadlock if it waits on a page for * which it is needed to do the write (loop masks off * __GFP_IO|__GFP_FS for this reason); but more thought * would probably show more reasons. * -* Don't require __GFP_FS, since we're not going into the -* FS, just waiting on its writeback completion. Worryingly, -* ext4 gfs2 and xfs allocate pages with -* grab_cache_page_write_begin(,,AOP_FLAG_NOFS), so testing -* may_enter_fs here is liable to OOM on them. -* * 3) memcg encounters a page that is not already marked * PageReclaim. memcg does not have any dirty pages * throttling so we could easily OOM just because too many
@@ -902,7 +898,7 @@ static unsigned long shrink_page_list(st/* Case 2 above */ }else if (global_reclaim (sc) || - !PageReclaim (page) || !(sc->gfp_mask & __GFP_IO)) { + !PageReclaim (page) || !may_enter_fs) {/* * This is slightly racy - end_page_writeback() * might have just cleared PageReclaim, then
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.14.51 release. There are 44 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun Aug 16 17:43:53 UTC 2015. Anything received after that time might be too late.
Quoted 8 lines
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v3.x/stable-review/patch-3.14.51-rc1.gzand the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Signature · 5 lines
Shuah Khan Sr. Linux Kernel Developer Open Source Innovation Group Samsung Research America (Silicon Valley) [email protected] | (970) 217-8978
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 14 lines · kernelci.org bot
stable-queue boot: 183 boots: 0 failed, 182 passed with 1 conflict (v3.14.50-44-g7a148040468f)
Full Boot Summary: http://kernelci.org/boot/all/job/stable-queue/kernel/v3.14.50-44-g7a148040468f/
Full Build Summary: http://kernelci.org/build/stable-queue/kernel/v3.14.50-44-g7a148040468f/Tree: stable-queue
Branch: local/linux-3.14.y-queue
Git Describe: v3.14.50-44-g7a148040468f
Git Commit:7a148040468f41b14d8c3859cde00d15318f83d5
Git URL:git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-stable.git
Tested: 48 unique boards, 16 SoC families, 23 builds out of 140Conflicting Boot Failure Detected: (These likely are not failures as other labs are reporting PASS. Needs review.)
Quoted 7 lines
arm:
multi_v7_defconfig: am335x-boneblack: lab-khilman: PASS lab-cambridge: FAIL lab-tbaker: PASS
The same board working in 2 of 3 labs usually indicates some lab-specifiic issue, so this shouldn't be considered a new failure. We'll look into the lab.
Kevin
Greg Kroah-Hartman
maintainerQuoted 23 lines · Kevin Hilman
Quoted 14 lines · kernelci.org bot
stable-queue boot: 183 boots: 0 failed, 182 passed with 1 conflict (v3.14.50-44-g7a148040468f)
Full Boot Summary: http://kernelci.org/boot/all/job/stable-queue/kernel/v3.14.50-44-g7a148040468f/
Full Build Summary: http://kernelci.org/build/stable-queue/kernel/v3.14.50-44-g7a148040468f/Tree: stable-queue
Branch: local/linux-3.14.y-queue
Git Describe: v3.14.50-44-g7a148040468f
Git Commit:7a148040468f41b14d8c3859cde00d15318f83d5
Git URL:git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-stable.git
Tested: 48 unique boards, 16 SoC families, 23 builds out of 140Conflicting Boot Failure Detected: (These likely are not failures as other labs are reporting PASS. Needs review.)
Quoted 7 lines
arm:
multi_v7_defconfig: am335x-boneblack: lab-khilman: PASS lab-cambridge: FAIL lab-tbaker: PASS
Quoted 3 lines
The same board working in 2 of 3 labs usually indicates some lab-specifiic issue, so this shouldn't be considered a new failure. We'll look into the lab.
Thanks for the testing.
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 3.14.51 release. There are 44 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun Aug 16 17:43:53 UTC 2015. Anything received after that time might be too late.
Build results:
total: 128 pass: 128 fail: 0 Qemu test results: total: 77 pass: 77 fail: 0
Details are available at http://server.roeck-us.net:8010/builders.
Guenter