4.17.6-stable review
Subsystems (2)
Greg Kroah-Hartman
maintainercover 4.17.6-stable review
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.17.6-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.17.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.17.6-rc1
Sebastian Andrzej Siewior <[email protected]>
Revert mm/vmstat.c: fix vmstat_update() preemption BUG
Dan Carpenter <[email protected]>
staging: comedi: quatech_daqp_cs: fix no-op loop daqp_ao_insn_write()
Jann Horn <[email protected]>
netfilter: nf_log: don't hold nf_log_mutex during user access
Tokunori Ikegami <[email protected]>
mtd: cfi_cmdset_0002: Change erase functions to check chip good only
Tokunori Ikegami <[email protected]>
mtd: cfi_cmdset_0002: Change erase functions to retry for error
Tokunori Ikegami <[email protected]>
mtd: cfi_cmdset_0002: Change definition naming to retry write operation
Ross Zwisler <[email protected]>
dm: prevent DAX mounts if not supported
Ross Zwisler <[email protected]>
dax: check for QUEUE_FLAG_DAX in bdev_dax_supported()
Dave Jiang <[email protected]>
dax: change bdev_dax_supported() to support boolean returns
Darrick J. Wong <[email protected]>
fs: allow per-device dax status checking for filesystems
Peter Rosin <[email protected]>
i2c: smbus: kill memory leak on emulated and failed DMA SMBus xfers
Wenwen Wang <[email protected]>
i2c: core: smbus: fix a potential missing-check bug
Benjamin Tissoires <[email protected]>
HID: core: allow concurrent registration of drivers
Daniel Rosenberg <[email protected]>
HID: debug: check length before copy_to_user()
Gustavo A. R. Silva <[email protected]>
HID: hiddev: fix potential Spectre v1
Jason Andryuk <[email protected]>
HID: i2c-hid: Fix "incomplete report" noise
Jon Derrick <[email protected]>
ext4: check superblock mapped prior to committing
Theodore Ts'o <[email protected]>
ext4: add more mount time checks of the superblock
Theodore Ts'o <[email protected]>
ext4: add more inode number paranoia checks
Theodore Ts'o <[email protected]>
ext4: avoid running out of journal credits when appending to an inline file
Theodore Ts'o <[email protected]>
ext4: never move the system.data xattr out of the inode body
Theodore Ts'o <[email protected]>
ext4: clear i_data in ext4_inode_info when removing inline data
Theodore Ts'o <[email protected]>
ext4: include the illegal physical block in the bad map ext4_error msg
Theodore Ts'o <[email protected]>
ext4: verify the depth of extent tree in ext4_find_extent()
Theodore Ts'o <[email protected]>
ext4: only look at the bg_flags field if it is valid
Theodore Ts'o <[email protected]>
ext4: always check block group bounds in ext4_init_block_bitmap()
Theodore Ts'o <[email protected]>
ext4: make sure bitmaps and the inode table don't overlap with bg descriptors
Theodore Ts'o <[email protected]>
ext4: always verify the magic number in xattr blocks
Theodore Ts'o <[email protected]>
ext4: add corruption check in ext4_xattr_set_entry()
Theodore Ts'o <[email protected]>
jbd2: don't mark block as modified if the handle is out of credits
Lyude Paul <[email protected]>
drm/amdgpu: Dynamically probe for ATIF handle (v2)
Lyude Paul <[email protected]>
drm/amdgpu: Add amdgpu_atpx_get_dhandle()
Mikulas Patocka <[email protected]>
drm/udl: fix display corruption of the last line
Michel Dänzer <[email protected]>
drm: Use kvzalloc for allocating blob property memory
Paulo Alcantara <[email protected]>
cifs: Fix infinite loop when using hard mount option
Stefano Brivio <[email protected]>
cifs: Fix slab-out-of-bounds in send_set_info() on SMB2 ACE setting
Paulo Alcantara <[email protected]>
cifs: Fix memory leak in smb2_set_ea()
Lars Persson <[email protected]>
cifs: Fix use after free of a mid_q_entry
Roger Quadros <[email protected]>
ARM: dts: dra7: Disable metastability workaround for USB2
Adam Ford <[email protected]>
ARM: dts: omap3: Fix am3517 mdio and emac clock references
Nick Dyer <[email protected]>
ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl
Jason Gunthorpe <[email protected]>
vfio: Use get_user_pages_longterm correctly
Lars Ellenberg <[email protected]>
drbd: fix access after free
Christian Borntraeger <[email protected]>
s390: Correct register corruption in critical section cleanup
David Disseldorp <[email protected]>
scsi: target: Fix truncated PR-in ReadKeys response
Raghava Aditya Renukunta <[email protected]>
scsi: aacraid: Fix PD performance regression over incorrect qd being set
Jann Horn <[email protected]>
scsi: sg: mitigate read/write abuse
Changbin Du <[email protected]>
tracing: Fix missing return symbol in function_graph output
Arnd Bergmann <[email protected]>
tracing: Avoid string overflow
Lyude Paul <[email protected]>
drm/amdgpu: Make struct amdgpu_atif private to amdgpu_acpi.c
Jouke Witteveen <[email protected]>
ACPI / battery: Safe unregistering of hooks
Rafael J. Wysocki <[email protected]>
ACPICA: Drop leading newlines from error messages
Rafael J. Wysocki <[email protected]>
PCI / ACPI / PM: Resume bridges w/o drivers on suspend-to-RAM
Pavel Tatashin <[email protected]>
mm: teach dump_page() to correctly output poisoned struct pages
Cannon Matthews <[email protected]>
mm: hugetlb: yield when prepping struct pages
Janosch Frank <[email protected]>
userfaultfd: hugetlbfs: fix userfaultfd_huge_must_wait() pte access
-------------
Diffstat:
Makefile | 4 +- arch/arm/boot/dts/am3517.dtsi | 4 + arch/arm/boot/dts/dra7.dtsi | 2 +- arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +- arch/s390/kernel/entry.S | 4 +- drivers/acpi/acpica/uterror.c | 6 +- drivers/acpi/battery.c | 9 +- drivers/block/drbd/drbd_worker.c | 2 +- drivers/dax/super.c | 48 +++++---- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 46 ++------ drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 131 +++++++++++++++++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 6 ++ drivers/gpu/drm/drm_property.c | 6 +- drivers/gpu/drm/udl/udl_fb.c | 5 +- drivers/gpu/drm/udl/udl_transfer.c | 11 +- drivers/hid/hid-core.c | 5 +- drivers/hid/hid-debug.c | 8 +- drivers/hid/i2c-hid/i2c-hid.c | 2 +- drivers/hid/usbhid/hiddev.c | 11 ++ drivers/i2c/i2c-core-smbus.c | 12 ++- drivers/md/dm-table.c | 7 +- drivers/md/dm.c | 3 +- drivers/mtd/chips/cfi_cmdset_0002.c | 30 ++++-- drivers/pci/pci-acpi.c | 12 +++ drivers/scsi/aacraid/aachba.c | 15 ++- drivers/scsi/sg.c | 42 +++++++- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 2 +- drivers/target/target_core_pr.c | 15 ++- drivers/vfio/vfio_iommu_type1.c | 16 ++- fs/cifs/cifsglob.h | 1 + fs/cifs/cifsproto.h | 1 + fs/cifs/cifssmb.c | 10 +- fs/cifs/connect.c | 8 +- fs/cifs/smb1ops.c | 1 + fs/cifs/smb2ops.c | 3 + fs/cifs/smb2pdu.c | 25 +++-- fs/cifs/smb2transport.c | 1 + fs/cifs/transport.c | 18 +++- fs/ext2/super.c | 3 +- fs/ext4/balloc.c | 21 ++-- fs/ext4/ext4.h | 8 -- fs/ext4/ext4_extents.h | 1 + fs/ext4/extents.c | 6 ++ fs/ext4/ialloc.c | 14 ++- fs/ext4/inline.c | 39 +------ fs/ext4/inode.c | 7 +- fs/ext4/mballoc.c | 6 +- fs/ext4/super.c | 89 ++++++++++++--- fs/ext4/xattr.c | 40 ++++--- fs/jbd2/transaction.c | 9 +- fs/userfaultfd.c | 12 ++- fs/xfs/xfs_ioctl.c | 3 +- fs/xfs/xfs_iops.c | 30 +++++- fs/xfs/xfs_super.c | 10 +- include/linux/dax.h | 11 +- include/linux/hid.h | 3 +- kernel/trace/trace_events_hist.c | 2 +- kernel/trace/trace_functions_graph.c | 5 +- mm/debug.c | 18 +++- mm/hugetlb.c | 1 + mm/vmstat.c | 2 - net/netfilter/nf_log.c | 9 +- 62 files changed, 596 insertions(+), 287 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/56 userfaultfd: hugetlbfs: fix userfaultfd_huge_must_wait() pte access
4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Janosch Frank <[email protected]>
commit 1e2c043628c7736dd56536d16c0ce009bc834ae7 upstream.
Use huge_ptep_get() to translate huge ptes to normal ptes so we can check them with the huge_pte_* functions. Otherwise some architectures will check the wrong values and will not wait for userspace to bring in the memory.
--- fs/userfaultfd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
fs/userfaultfd.c +7 -5
@@ -220,24 +220,26 @@ static inline bool userfaultfd_huge_must unsigned long reason) {struct mm_struct *mm = ctx->mm; -pte_t *pte; +pte_t *ptep, pte;bool ret = true;VM_BUG_ON (!rwsem_is_locked (&mm->mmap_sem)); - pte =huge_pte_offset (mm, address,vma_mmu_pagesize (vma)); -if (!pte) + ptep =huge_pte_offset (mm, address,vma_mmu_pagesize (vma)); + +if (!ptep) goto out; ret = false; + pte =huge_ptep_get (ptep);/* * Lockless access: we're in a wait_event so it's ok if it * changes under us. */ -if (huge_pte_none (*pte)) +if (huge_pte_none (pte)) ret = true; -if (!huge_pte_write (*pte) && (reason &VM_UFFD_WP )) +if (!huge_pte_write (pte) && (reason &VM_UFFD_WP )) ret = true; out:return ret;
Greg Kroah-Hartman
maintainerPATCH 2/56 mm: hugetlb: yield when prepping struct pages
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cannon Matthews <[email protected]>
commit 520495fe96d74e05db585fc748351e0504d8f40d upstream.
When booting with very large numbers of gigantic (i.e. 1G) pages, the operations in the loop of gather_bootmem_prealloc, and specifically prep_compound_gigantic_page, takes a very long time, and can cause a softlockup if enough pages are requested at boot.
For example booting with 3844 1G pages requires prepping (set_compound_head, init the count) over 1 billion 4K tail pages, which takes considerable time.
Add a cond_resched() to the outer loop in gather_bootmem_prealloc() to prevent this lockup.
Tested: Booted with softlockup_panic=1 hugepagesz=1G hugepages=3844 and no softlockup is reported, and the hugepages are reported as successfully setup.
--- mm/hugetlb.c | 1 + 1 file changed, 1 insertion(+)
mm/hugetlb.c +1 -0
@@ -2163,6 +2163,7 @@ static void __init gather_bootmem_preall*/ if (hstate_is_gigantic (h))adjust_managed_page_count (page,1 << h->order); +cond_resched (); } }
Greg Kroah-Hartman
maintainerPATCH 3/56 mm: teach dump_page() to correctly output poisoned struct pages
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Tatashin <[email protected]>
commit fc36def997cfd6cbff3eda4f82853a5c311c5466 upstream.
If struct page is poisoned, and uninitialized access is detected via PF_POISONED_CHECK(page) dump_page() is called to output the page. But, the dump_page() itself accesses struct page to determine how to print it, and therefore gets into a recursive loop.
For example:
dump_page()
__dump_page()
PageSlab(page)
PF_POISONED_CHECK(page)
VM_BUG_ON_PGFLAGS(PagePoisoned(page), page)
dump_page() recursion loop.
--- mm/debug.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
mm/debug.c +16 -2
@@ -43,12 +43,25 @@ const struct trace_print_flags vmaflag_nvoid __dump_page (struct page *page,const char *reason) { +bool page_poisoned =PagePoisoned (page); +int mapcount; + +/* +* If struct page is poisoned don't access Page*() functions as that +* leads to recursive loop. Page*() check for poisoned pages, and calls +* dump_page() when detected. +*/ +if (page_poisoned) { +pr_emerg ("page:%px is uninitialized and poisoned" , page); + goto hex_only; + } +/* * Avoid VM_BUG_ON() in page_mapcount(). * page->_mapcount space in struct page is used by sl[aou]b pages to * encode own info. */ -int mapcount =PageSlab (page) ?0 :page_mapcount (page); + mapcount =PageSlab (page) ?0 :page_mapcount (page); pr_emerg("page:%px count:%d mapcount:%d mapping:%px index:%#lx", page, page_ref_count(page), mapcount,
@@ -60,6 +73,7 @@ void __dump_page(struct page *page, conspr_emerg ("flags: %#lx(%pGp)\n" , page->flags, &page->flags); +hex_only:print_hex_dump (KERN_ALERT ,"raw: " ,DUMP_PREFIX_NONE ,32 ,sizeof (unsigned long ), page,sizeof (struct page ), false);
@@ -68,7 +82,7 @@ void __dump_page(struct page *page, conspr_alert ("page dumped because: %s\n" , reason);#ifdef CONFIG_MEMCG -if (page->mem_cgroup) +if (!page_poisoned && page->mem_cgroup)pr_alert ("page->mem_cgroup:%px\n" , page->mem_cgroup);#endif }
Greg Kroah-Hartman
maintainerPATCH 4/56 PCI / ACPI / PM: Resume bridges w/o drivers on suspend-to-RAM
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit 26112ddc254c98681b224aa9ededefc01b6e02d2 upstream.
It is reported that commit c62ec4610c40 (PM / core: Fix direct_complete handling for devices with no callbacks) introduced a system suspend regression on Samsung 305V4A by allowing a PCI bridge (not a PCIe port) to stay in D3 over suspend-to-RAM, which is a side effect of setting power.direct_complete for the children of that bridge that have no PM callbacks.
On the majority of systems PCI bridges are not allowed to be runtime-suspended (the power/control sysfs attribute is set to "on" for them by default), but user space can change that setting and if it does so and a given bridge has no children with PM callbacks, the direct_complete optimization will be applied to it and it will stay in suspend over system suspend. Apparently, that confuses the platform firmware on the affected machine and that may very well happen elsewhere, so avoid the direct_complete optimization for PCI bridges with no drivers (if there is a driver, it should take care of the PM handling) on suspend-to-RAM altogether (that should not matter for suspend-to-idle as platform firmware is not involved in it).
--- drivers/pci/pci-acpi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/pci/pci-acpi.c +12 -0
@@ -598,6 +598,18 @@ static bool acpi_pci_need_resume(struct {struct acpi_device *adev =ACPI_COMPANION (&dev->dev); +/* +* In some cases (eg. Samsung 305V4A) leaving a bridge in suspend over +* system-wide suspend/resume confuses the platform firmware, so avoid +* doing that, unless the bridge has a driver that should take care of +* the PM handling. According to Section 16.1.6 of ACPI 6.2, endpoint +* devices are expected to be in D3 before invoking the S3 entry path +* from the firmware, so they should not be affected by this issue. +*/ +if (pci_is_bridge (dev) && !dev->driver && +acpi_target_system_state () !=ACPI_STATE_S0 ) +return true; +if (!adev || !acpi_device_power_manageable (adev))return false;
Greg Kroah-Hartman
maintainerPATCH 5/56 ACPICA: Drop leading newlines from error messages
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit a0d5f3b69af7733f3173a8e19d51f68a08017c76 upstream.
Commit 5088814a6e93 (ACPICA: AML parser: attempt to continue loading table after error) unintentionally added leading newlines to error messages emitted by ACPICA which caused unexpected things to be printed to the kernel log. Drop these newlines (which effectively reverts the part of commit 5088814a6e93 adding them).
--- drivers/acpi/acpica/uterror.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/acpi/acpica/uterror.c +3 -3
@@ -182,19 +182,19 @@ acpi_ut_prefixed_namespace_error(const cswitch (lookup_status) {case AE_ALREADY_EXISTS : -acpi_os_printf ("\n" ACPI_MSG_BIOS_ERROR ); +acpi_os_printf (ACPI_MSG_BIOS_ERROR ); message ="Failure creating" ;break ;case AE_NOT_FOUND : -acpi_os_printf ("\n" ACPI_MSG_BIOS_ERROR ); +acpi_os_printf (ACPI_MSG_BIOS_ERROR ); message ="Could not resolve" ;break ;default : -acpi_os_printf ("\n" ACPI_MSG_ERROR ); +acpi_os_printf (ACPI_MSG_ERROR ); message ="Failure resolving" ;break ; }
Greg Kroah-Hartman
maintainerPATCH 6/56 ACPI / battery: Safe unregistering of hooks
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouke Witteveen <[email protected]>
commit 673b4271665a12fa839a12abb50e6f6e9953c081 upstream.
A hooking API was implemented for 4.17 in fa93854f7a7ed63d followed by hooks for Thinkpad laptops in 2801b9683f740012. The Thinkpad drivers did not support the Thinkpad 13 and the hooking API crashes on unsupported batteries by altering a list of hooks during unsafe iteration. Thus, Thinkpad 13 laptops could no longer boot.
Additionally, a lock was kept in place and debugging information was printed out of order.
--- drivers/acpi/battery.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/acpi/battery.c +5 -4
@@ -709,10 +709,11 @@ void battery_hook_register(struct acpi_b*/ pr_err ("extension failed to load: %s" , hook->name);__battery_hook_unregister (hook,0 ); -return ; + goto end; } }pr_info ("new extension: %s\n" , hook->name); +end:mutex_unlock (&hook_mutex); }EXPORT_SYMBOL_GPL (battery_hook_register);
@@ -724,7 +725,7 @@ EXPORT_SYMBOL_GPL(battery_hook_register)*/ static void battery_hook_add_battery (struct acpi_battery *battery) { -struct acpi_battery_hook *hook_node; +struct acpi_battery_hook *hook_node, *tmp;mutex_lock (&hook_mutex);INIT_LIST_HEAD (&battery->list);
@@ -736,15 +737,15 @@ static void battery_hook_add_battery(str* when a battery gets hotplugged or initialized * during the battery module initialization. */ -list_for_each_entry (hook_node, &battery_hook_list, list) { +list_for_each_entry_safe (hook_node, tmp, &battery_hook_list, list) {if (hook_node->add_battery (battery->bat)) {/* * The notification of the extensions has failed, to * prevent further errors we will unload the extension. */ -__battery_hook_unregister (hook_node,0 );pr_err ("error in extension, unloading: %s" , hook_node->name); +__battery_hook_unregister (hook_node,0 ); } }mutex_unlock (&hook_mutex);
Greg Kroah-Hartman
maintainerPATCH 7/56 drm/amdgpu: Make struct amdgpu_atif private to amdgpu_acpi.c
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude Paul <[email protected]>
commit 2cd5fe22d9a45cdf11c62bbe8db3ce9101207510 upstream.
Currently, there is nothing in amdgpu that actually uses these structs other than amdgpu_acpi.c. Additionally, since we're about to start saving the correct ACPI handle to use for calling ATIF in this struct this saves us from having to handle making sure that the acpi_handle (and by proxy, the type definition for acpi_handle and all of the other acpi headers) doesn't need to be included within the amdgpu_drv struct itself. This follows the example set by amdgpu_atpx_handler.c.
--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 40 +--------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 54 +++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 41 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu.h +2 -38
@@ -188,6 +188,7 @@ struct amdgpu_job;struct amdgpu_irq_src ;struct amdgpu_fpriv ;struct amdgpu_bo_va_mapping ; +struct amdgpu_atif ;enum amdgpu_cp_irq {AMDGPU_CP_IRQ_GFX_EOP =0 ,
@@ -1246,43 +1247,6 @@ struct amdgpu_vram_scratch {/* * ACPI */ -struct amdgpu_atif_notification_cfg { -bool enabled; -int command_code; -}; - -struct amdgpu_atif_notifications { -bool display_switch; -bool expansion_mode_change; -bool thermal_state; -bool forced_power_state; -bool system_power_state; -bool display_conf_change; -bool px_gfx_switch; -bool brightness_change; -bool dgpu_display_event; -}; - -struct amdgpu_atif_functions { -bool system_params; -bool sbios_requests; -bool select_active_disp; -bool lid_state; -bool get_tv_standard; -bool set_tv_standard; -bool get_panel_expansion_mode; -bool set_panel_expansion_mode; -bool temperature_change; -bool graphics_device_types; -}; - -struct amdgpu_atif { -struct amdgpu_atif_notifications notifications; -struct amdgpu_atif_functions functions; -struct amdgpu_atif_notification_cfg notification_cfg; -struct amdgpu_encoder *encoder_for_bl; -}; -struct amdgpu_atcs_functions {bool get_ext_state;bool pcie_perf_req;
@@ -1430,7 +1394,7 @@ struct amdgpu_device {#if defined(CONFIG_DEBUG_FS )struct dentry *debugfs_regs[AMDGPU_DEBUGFS_MAX_COMPONENTS ];#endif -struct amdgpu_atif atif; +struct amdgpu_atif *atif;struct amdgpu_atcs atcs;struct mutex srbm_mutex;/* GRBM index mutex. Protects concurrent access to GRBM index */
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +51 -3
93 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 8/56 tracing: Avoid string overflow
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit cf4d418e653afc84c9c873236033e06be5d58f1c upstream.
'err' is used as a NUL-terminated string, but using strncpy() with the length equal to the buffer size may result in lack of the termination:
kernel/trace/trace_events_hist.c: In function 'hist_err_event':kernel/trace/trace_events_hist.c:396:3: error: 'strncpy' specified bound 256 equals destination size [-Werror=stringop-truncation]
strncpy(err, var, MAX_FILTER_STR_VAL);
This changes it to use the safer strscpy() instead.
--- kernel/trace/trace_events_hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_events_hist.c +1 -1
@@ -393,7 +393,7 @@ static void hist_err_event(char *str, chelse if (system)snprintf (err,MAX_FILTER_STR_VAL ,"%s.%s" , system, event);else -strncpy (err, var,MAX_FILTER_STR_VAL ); +strscpy (err, var,MAX_FILTER_STR_VAL );hist_err (str, err); }
Greg Kroah-Hartman
maintainerPATCH 9/56 tracing: Fix missing return symbol in function_graph output
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Changbin Du <[email protected]>
commit 1fe4293f4b8de75824935f8d8e9a99c7fc6873da upstream.
The function_graph tracer does not show the interrupt return marker for the leaf entry. On leaf entries, we see an unbalanced interrupt marker (the interrupt was entered, but nevern left).
Before:
1) | SyS_write() {
1) | __fdget_pos() {
1) 0.061 us | __fget_light();
1) 0.289 us | }
1) | vfs_write() {
1) 0.049 us | rw_verify_area();
1) + 15.424 us | __vfs_write();
1) ==========> |
1) 6.003 us | smp_apic_timer_interrupt();
1) 0.055 us | __fsnotify_parent();
1) 0.073 us | fsnotify();
1) + 23.665 us | }
1) + 24.501 us | }After:
0) | SyS_write() {
0) | __fdget_pos() {
0) 0.052 us | __fget_light();
0) 0.328 us | }
0) | vfs_write() {
0) 0.057 us | rw_verify_area();
0) | __vfs_write() {
0) ==========> |
0) 8.548 us | smp_apic_timer_interrupt();
0) <========== |
0) + 36.507 us | } /* __vfs_write */
0) 0.049 us | __fsnotify_parent();
0) 0.066 us | fsnotify();
0) + 50.064 us | }
0) + 50.952 us | }--- kernel/trace/trace_functions_graph.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/trace/trace_functions_graph.c +4 -1
@@ -831,6 +831,7 @@ print_graph_entry_leaf(struct trace_iterstruct ftrace_graph_ret *graph_ret;struct ftrace_graph_ent *call;unsigned long long duration; +int cpu = iter->cpu;int i; graph_ret = &ret_entry->ret;
@@ -839,7 +840,6 @@ print_graph_entry_leaf(struct trace_iterif (data) {struct fgraph_cpu_data *cpu_data; -int cpu = iter->cpu; cpu_data =per_cpu_ptr (data->cpu_data, cpu);
@@ -869,6 +869,9 @@ print_graph_entry_leaf(struct trace_itertrace_seq_printf (s,"%ps();\n" , (void *)call->func); +print_graph_irq (iter, graph_ret->func,TRACE_GRAPH_RET , + cpu, iter->ent->pid, flags); +return trace_handle_return (s); }
Greg Kroah-Hartman
maintainerPATCH 10/56 scsi: sg: mitigate read/write abuse
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 26b5b874aff5659a7e26e5b1997e3df2c41fa7fd upstream.
As Al Viro noted in commit 128394eff343 ("sg_write()/bsg_write() is not fit to be called under KERNEL_DS"), sg improperly accesses userspace memory outside the provided buffer, permitting kernel memory corruption via splice(). But it doesn't just do it on ->write(), also on ->read().
As a band-aid, make sure that the ->read() and ->write() handlers can not be called in weird contexts (kernel context or credentials different from file opener), like for ib_safe_file_access().
If someone needs to use these interfaces from different security contexts, a new interface should be written that goes through the ->ioctl() handler.
I've mostly copypasted ib_safe_file_access() over as sg_safe_file_access() because I couldn't find a good common header - please tell me if you know a better way.
[mkp: s/_safe_/_check_/]
--- drivers/scsi/sg.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-)
drivers/scsi/sg.c +40 -2
@@ -51,6 +51,7 @@ static int sg_version_num = 30536; /* 2#include <linux/atomic.h> #include <linux/ratelimit.h> #include <linux/uio.h> +#include <linux/cred.h> /* for sg_check_file_access() */ #include "scsi.h" #include <scsi/scsi_dbg.h>
@@ -210,6 +211,33 @@ static void sg_device_destroy(struct kre sdev_prefix_printk(prefix, (sdp)->device, \ (sdp)->disk->disk_name, fmt, ##a) +/* +* The SCSI interfaces that use read() and write() as an asynchronous variant of +* ioctl(..., SG_IO, ...) are fundamentally unsafe, since there are lots of ways +* to trigger read() and write() calls from various contexts with elevated +* privileges. This can lead to kernel memory corruption (e.g. if these +* interfaces are called through splice()) and privilege escalation inside +* userspace (e.g. if a process with access to such a device passes a file +* descriptor to a SUID binary as stdin/stdout/stderr). +* +* This function provides protection for the legacy API by restricting the +* calling context. +*/ +static int sg_check_file_access (struct file *filp,const char *caller) +{ +if (filp->f_cred !=current_real_cred ()) { +pr_err_once ("%s: process %d (%s) changed security contexts after opening file descriptor, this is not allowed.\n" , + caller,task_tgid_vnr (current), current->comm); +return -EPERM ; + } +if (uaccess_kernel ()) { +pr_err_once ("%s: process %d (%s) called from kernel context, this is not allowed.\n" , + caller,task_tgid_vnr (current), current->comm); +return -EACCES ; + } +return 0 ; +} +static int sg_allow_access (struct file *filp,unsigned char *cmd) {struct sg_fd *sfp = filp->private_data;
@@ -394,6 +422,14 @@ sg_read(struct file *filp, char __user *struct sg_header *old_hdr =NULL ;int retval =0 ; +/* +* This could cause a response to be stranded. Close the associated +* file descriptor to free up any resources being held. +*/ + retval =sg_check_file_access (filp, __func__); +if (retval) +return retval; +if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))return -ENXIO ; SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
@@ -581,9 +617,11 @@ sg_write(struct file *filp, const char _struct sg_header old_hdr;sg_io_hdr_t *hp;unsigned char cmnd[SG_MAX_CDB_SIZE ]; +int retval; -if (unlikely (uaccess_kernel ())) -return -EINVAL ; + retval =sg_check_file_access (filp, __func__); +if (retval) +return retval;if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))return -ENXIO ;
Greg Kroah-Hartman
maintainerPATCH 11/56 scsi: aacraid: Fix PD performance regression over incorrect qd being set
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Raghava Aditya Renukunta <[email protected]>
commit 59b433c825569ce251371485f0e29fca888b549d upstream.
The driver fails to set the correct queue depth for native devices, due to failing to set the device type prior to calling aac_set_safw_target_qd(). This results in slave configure setting the queue depth to 1.
This causes around 30% performance degradation. Fixed by setting the dev type before trying to set queue depth.
--- drivers/scsi/aacraid/aachba.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/scsi/aacraid/aachba.c +7 -8
@@ -1974,7 +1974,6 @@ static void aac_set_safw_attr_all_targetu32 lun_count, nexus;u32 i, bus, target;u8 expose_flag, attribs; -u8 devtype; lun_count =aac_get_safw_phys_lun_count (dev);
@@ -1992,23 +1991,23 @@ static void aac_set_safw_attr_all_targetcontinue ;if (expose_flag !=0 ) { - devtype =AAC_DEVTYPE_RAID_MEMBER ; - goto update_devtype; + dev->hba_map[bus][target].devtype = +AAC_DEVTYPE_RAID_MEMBER ; +continue ; }if (nexus !=0 && (attribs &8 )) { - devtype =AAC_DEVTYPE_NATIVE_RAW ; + dev->hba_map[bus][target].devtype = +AAC_DEVTYPE_NATIVE_RAW ; dev->hba_map[bus][target].rmw_nexus = nexus; }else - devtype =AAC_DEVTYPE_ARC_RAW ; + dev->hba_map[bus][target].devtype = +AAC_DEVTYPE_ARC_RAW ; dev->hba_map[bus][target].scan_counter = dev->scan_counter;aac_set_safw_target_qd (dev, bus, target); - -update_devtype: - dev->hba_map[bus][target].devtype = devtype; } }
Greg Kroah-Hartman
maintainerPATCH 12/56 scsi: target: Fix truncated PR-in ReadKeys response
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Disseldorp <[email protected]>
commit 63ce3c384db26494615e3c8972bcd419ed71f4c4 upstream.
SPC5r17 states that the contents of the ADDITIONAL LENGTH field are not altered based on the allocation length, so always calculate and pack the full key list length even if the list itself is truncated.
According to Maged:
Yes it fixes the "Storage Spaces Persistent Reservation" test in the Windows 2016 Server Failover Cluster validation suites when having many connections that result in more than 8 registrations. I tested your patch on 4.17 with iblock.
This behaviour can be tested using the libiscsi PrinReadKeys.Truncate test.
--- drivers/target/target_core_pr.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/target/target_core_pr.c +10 -5
@@ -3727,11 +3727,16 @@ core_scsi3_pri_read_keys(struct se_cmd ** Check for overflow of 8byte PRI READ_KEYS payload and * next reservation key list descriptor. */ -if ((add_len +8 ) > (cmd->data_length -8 )) -break ; - -put_unaligned_be64 (pr_reg->pr_res_key, &buf[off]); - off +=8 ; +if (off +8 <= cmd->data_length) { +put_unaligned_be64 (pr_reg->pr_res_key, &buf[off]); + off +=8 ; + } +/* +* SPC5r17: 6.16.2 READ KEYS service action +* The ADDITIONAL LENGTH field indicates the number of bytes in +* the Reservation key list. The contents of the ADDITIONAL +* LENGTH field are not altered based on the allocation length +*/ add_len +=8 ; }spin_unlock (&dev->t10_pr.registration_lock);
Greg Kroah-Hartman
maintainerPATCH 13/56 s390: Correct register corruption in critical section cleanup
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Borntraeger <[email protected]>
commit 891f6a726cacbb87e5b06076693ffab53bd378d7 upstream.
In the critical section cleanup we must not mess with r1. For march=z9 or older, larl + ex (instead of exrl) are used with r1 as a temporary register. This can clobber r1 in several interrupt handlers. Fix this by using r11 as a temp register. r11 is being saved by all callers of cleanup_critical.
--- arch/s390/kernel/entry.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/s390/kernel/entry.S +2 -2
@@ -1265,7 +1265,7 @@ cleanup_critical: jl 0f clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end jl .Lcleanup_load_fpu_regs -0: BR_EX %r14 +0: BR_EX %r14,%r11 .align 8 .Lcleanup_table:
@@ -1301,7 +1301,7 @@ cleanup_critical: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE lctlg %c1,%c1,__LC_USER_ASCE # load primary asce larl %r9,sie_exit # skip forward to sie_exit - BR_EX %r14 + BR_EX %r14,%r11 #endif .Lcleanup_system_call:
Greg Kroah-Hartman
maintainerPATCH 14/56 drbd: fix access after free
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lars Ellenberg <[email protected]>
commit 64dafbc9530c10300acffc57fae3269d95fa8f93 upstream.
We have
struct drbd_requests { ... struct bio *private_bio; ... }
to hold a bio clone for local submission.
On local IO completion, we put that bio, and in case we want to use the result later, we overload that member to hold the ERR_PTR() of the completion result,
Which, before v4.3, used to be the passed in "int error", so we could first bio_put(), then assign.
v4.3-rc1~100^2~21 4246a0b63bd8 block: add a bi_error field to struct bio changed that:
bio_put(req->private_bio);
- req->private_bio = ERR_PTR(error);
+ req->private_bio = ERR_PTR(bio->bi_error);
Which introduces an access after free,
because it was non obvious that req->private_bio == bio.
Impact of that was mostly unnoticable, because we only use that value in a multiple-failure case, and even then map any "unexpected" error code to EIO, so worst case we could potentially mask a more specific error with EIO in a multiple failure case.
Unless the pointed to memory region was unmapped, as is the case with CONFIG_DEBUG_PAGEALLOC, in which case this results in
BUG: unable to handle kernel paging request
v4.13-rc1~70^2~75 4e4cbee93d56 block: switch bios to blk_status_t changes it further to
bio_put(req->private_bio);
req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status));
And blk_status_to_errno() now contains a WARN_ON_ONCE() for unexpected values, which catches this "sometimes", if the memory has been reused quickly enough for other things.
Should also go into stable since 4.3, with the trivial change around 4.13.
--- drivers/block/drbd/drbd_worker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/drbd/drbd_worker.c +1 -1
@@ -282,8 +282,8 @@ void drbd_request_endio(struct bio *bio) what =COMPLETED_OK ; } -bio_put (req->private_bio); req->private_bio =ERR_PTR (blk_status_to_errno (bio->bi_status)); +bio_put (bio);/* not req_mod(), we need irqsave here! */ spin_lock_irqsave (&device->resource->req_lock, flags);
Greg Kroah-Hartman
maintainerPATCH 15/56 vfio: Use get_user_pages_longterm correctly
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
commit bb94b55af3461e26b32f0e23d455abeae0cfca5d upstream.
The patch noted in the fixes below converted get_user_pages_fast() to get_user_pages_longterm(), however the two calls differ in a few ways.
First _fast() is documented to not require the mmap_sem, while _longterm() is documented to need it. Hold the mmap sem as required.
Second, _fast accepts an 'int write' while _longterm uses 'unsigned int gup_flags', so the expression '!!(prot & IOMMU_WRITE)' is only working by luck as FOLL_WRITE is currently == 0x1. Use the expected FOLL_WRITE constant instead.
--- drivers/vfio/vfio_iommu_type1.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
drivers/vfio/vfio_iommu_type1.c +7 -9
@@ -346,18 +346,16 @@ static int vaddr_get_pfn(struct mm_strucstruct page *page[1 ];struct vm_area_struct *vma;struct vm_area_struct *vmas[1 ]; +unsigned int flags =0 ;int ret; +if (prot &IOMMU_WRITE ) + flags |=FOLL_WRITE ; + +down_read (&mm->mmap_sem);if (mm == current->mm) { - ret =get_user_pages_longterm (vaddr,1 , !!(prot &IOMMU_WRITE ), - page, vmas); + ret =get_user_pages_longterm (vaddr,1 , flags, page, vmas); }else { -unsigned int flags =0 ; - -if (prot &IOMMU_WRITE ) - flags |=FOLL_WRITE ; - -down_read (&mm->mmap_sem); ret =get_user_pages_remote (NULL , mm, vaddr,1 , flags, page, vmas,NULL );/*
@@ -371,8 +369,8 @@ static int vaddr_get_pfn(struct mm_struc ret = -EOPNOTSUPP ;put_page (page[0 ]); } -up_read (&mm->mmap_sem); } +up_read (&mm->mmap_sem);if (ret ==1 ) { *pfn =page_to_pfn (page[0 ]);
Greg Kroah-Hartman
maintainerPATCH 16/56 ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nick Dyer <[email protected]>
commit 06d793b114e9d922c03aa077ac6c5c51fdda2722 upstream.
The pinctrl settings were incorrect for the touchscreen interrupt line, causing an interrupt storm. This change has been tested with both the atmel_mxt_ts and RMI4 drivers on the RDU1 units.
The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8 from the old vendor kernel.
--- arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx51-zii-rdu1.dts +1 -1
@@ -768,7 +768,7 @@ pinctrl_ts: tsgrp { fsl,pins = < - MX51_PAD_CSI1_D8__GPIO3_12 0x85 + MX51_PAD_CSI1_D8__GPIO3_12 0x04 MX51_PAD_CSI1_D9__GPIO3_13 0x85 >; };
Greg Kroah-Hartman
maintainerPATCH 17/56 ARM: dts: omap3: Fix am3517 mdio and emac clock references
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Ford <[email protected]>
commit 0144eb204cdcdf09a76794b4a294291388e739bc upstream.
A previous patch removed OMAP clock aliases that were perceived to be unnecessary. Unfortunately, it broke the ethernet on the am3517-evm. This patch enables the MDIO clock and EMAC clock.
--- arch/arm/boot/dts/am3517.dtsi | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm/boot/dts/am3517.dtsi +4 -0
@@ -39,6 +39,8 @@ ti,davinci-ctrl-ram-size = <0x2000>; ti,davinci-rmii-en = /bits/ 8 <1>; local-mac-address = [ 00 00 00 00 00 00 ]; + clocks = <&emac_ick>; + clock-names = "ick"; }; davinci_mdio: ethernet@5c030000 {
@@ -49,6 +51,8 @@ bus_freq = <1000000>; #address-cells = <1>; #size-cells = <0>; + clocks = <&emac_fck>; + clock-names = "fck"; }; uart4: serial@4809e000 {
Greg Kroah-Hartman
maintainerPATCH 18/56 ARM: dts: dra7: Disable metastability workaround for USB2
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Quadros <[email protected]>
commit 07eaa43e66f505980d00e0f5fe697f3da7c6a730 upstream.
Disable the metastability workaround for USB2. The original patch disabled the workaround on the wrong USB port.
--- arch/arm/boot/dts/dra7.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/dra7.dtsi +1 -1
@@ -1582,7 +1582,6 @@ dr_mode = "otg"; snps,dis_u3_susphy_quirk; snps,dis_u2_susphy_quirk; - snps,dis_metastability_quirk; }; };
@@ -1610,6 +1609,7 @@ dr_mode = "otg"; snps,dis_u3_susphy_quirk; snps,dis_u2_susphy_quirk; + snps,dis_metastability_quirk; }; };
Greg Kroah-Hartman
maintainerPATCH 19/56 cifs: Fix use after free of a mid_q_entry
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lars Persson <[email protected]>
commit 696e420bb2a6624478105651d5368d45b502b324 upstream.
With protocol version 2.0 mounts we have seen crashes with corrupt mid entries. Either the server->pending_mid_q list becomes corrupt with a cyclic reference in one element or a mid object fetched by the demultiplexer thread becomes overwritten during use.
Code review identified a race between the demultiplexer thread and the request issuing thread. The demultiplexer thread seems to be written with the assumption that it is the sole user of the mid object until it calls the mid callback which either wakes the issuer task or deletes the mid.
This assumption is not true because the issuer task can be woken up earlier by a signal. If the demultiplexer thread has proceeded as far as setting the mid_state to MID_RESPONSE_RECEIVED then the issuer thread will happily end up calling cifs_delete_mid while the demultiplexer thread still is using the mid object.
Inserting a delay in the cifs demultiplexer thread widens the race window and makes reproduction of the race very easy:
if (server->large_buf) buf = server->bigbuf;
+ usleep_range(500, 4000);
server->lstrp = jiffies;
To resolve this I think the proper solution involves putting a reference count on the mid object. This patch makes sure that the demultiplexer thread holds a reference until it has finished processing the transaction.
--- fs/cifs/cifsglob.h | 1 + fs/cifs/cifsproto.h | 1 + fs/cifs/connect.c | 8 +++++++- fs/cifs/smb1ops.c | 1 + fs/cifs/smb2ops.c | 1 + fs/cifs/smb2transport.c | 1 + fs/cifs/transport.c | 18 +++++++++++++++++- 7 files changed, 29 insertions(+), 2 deletions(-)
fs/cifs/cifsglob.h +1 -0
@@ -1362,6 +1362,7 @@ typedef int (mid_handle_t)(struct TCP_Se/* one of these for every pending CIFS request to the server */ struct mid_q_entry {struct list_head qhead;/* mids waiting on reply from this server */ +struct kref refcount;struct TCP_Server_Info *server;/* server corresponding to this mid */ __u64 mid;/* multiplex id */ __u32 pid;/* process id */
fs/cifs/cifsproto.h +1 -0
@@ -76,6 +76,7 @@ extern struct mid_q_entry *AllocMidQEntr struct TCP_Server_Info *server);extern void DeleteMidQEntry (struct mid_q_entry *midEntry);extern void cifs_delete_mid (struct mid_q_entry *mid); +extern void cifs_mid_q_entry_release (struct mid_q_entry *midEntry);extern void cifs_wake_up_task (struct mid_q_entry *mid);extern int cifs_handle_standard (struct TCP_Server_Info *server,struct mid_q_entry *mid);
fs/cifs/connect.c +7 -1
@@ -906,6 +906,7 @@ cifs_demultiplex_thread(void *p)continue ; server->total_read += length; + mid_entry =NULL ;if (server->ops->is_transform_hdr && server->ops->receive_transform && server->ops->is_transform_hdr (buf)) {
@@ -920,8 +921,11 @@ cifs_demultiplex_thread(void *p) length = mid_entry->receive (server, mid_entry); } -if (length <0 ) +if (length <0 ) { +if (mid_entry) +cifs_mid_q_entry_release (mid_entry);continue ; + }if (server->large_buf) buf = server->bigbuf;
@@ -938,6 +942,8 @@ cifs_demultiplex_thread(void *p)if (!mid_entry->multiRsp || mid_entry->multiEnd) mid_entry->callback (mid_entry); + +cifs_mid_q_entry_release (mid_entry); }else if (server->ops->is_oplock_break && server->ops->is_oplock_break (buf, server)) {cifs_dbg (FYI ,"Received oplock break\n" );
fs/cifs/smb1ops.c +1 -0
@@ -107,6 +107,7 @@ cifs_find_mid(struct TCP_Server_Info *seif (compare_mid (mid->mid, buf) && mid->mid_state ==MID_REQUEST_SUBMITTED &&le16_to_cpu (mid->command) == buf->Command) { +kref_get (&mid->refcount);spin_unlock (&GlobalMid_Lock);return mid; }
fs/cifs/smb2ops.c +1 -0
@@ -203,6 +203,7 @@ smb2_find_mid(struct TCP_Server_Info *seif ((mid->mid == wire_mid) && (mid->mid_state ==MID_REQUEST_SUBMITTED ) && (mid->command == shdr->Command)) { +kref_get (&mid->refcount);spin_unlock (&GlobalMid_Lock);return mid; }
fs/cifs/smb2transport.c +1 -0
@@ -548,6 +548,7 @@ smb2_mid_entry_alloc(const struct smb2_s temp =mempool_alloc (cifs_mid_poolp,GFP_NOFS );memset (temp,0 ,sizeof (struct mid_q_entry )); +kref_init (&temp->refcount); temp->mid =le64_to_cpu (shdr->MessageId); temp->pid = current->pid; temp->command = shdr->Command;/* Always LE */
fs/cifs/transport.c +17 -1
@@ -61,6 +61,7 @@ AllocMidQEntry(const struct smb_hdr *smb temp =mempool_alloc (cifs_mid_poolp,GFP_NOFS );memset (temp,0 ,sizeof (struct mid_q_entry )); +kref_init (&temp->refcount); temp->mid =get_mid (smb_buffer); temp->pid = current->pid; temp->command =cpu_to_le16 (smb_buffer->Command);
@@ -82,6 +83,21 @@ AllocMidQEntry(const struct smb_hdr *smbreturn temp; } +static void _cifs_mid_q_entry_release (struct kref *refcount) +{ + struct mid_q_entry *mid = container_of(refcount, struct mid_q_entry, + refcount); + +mempool_free (mid, cifs_mid_poolp); +} + +void cifs_mid_q_entry_release (struct mid_q_entry *midEntry) +{ +spin_lock (&GlobalMid_Lock); +kref_put (&midEntry->refcount, _cifs_mid_q_entry_release); +spin_unlock (&GlobalMid_Lock); +} +void DeleteMidQEntry (struct mid_q_entry *midEntry) {
@@ -110,7 +126,7 @@ DeleteMidQEntry(struct mid_q_entry *midE } }#endif -mempool_free (midEntry, cifs_mid_poolp); +cifs_mid_q_entry_release (midEntry); }void
Greg Kroah-Hartman
maintainerPATCH 20/56 cifs: Fix memory leak in smb2_set_ea()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 6aa0c114eceec8cc61715f74a4ce91b048d7561c upstream.
This patch fixes a memory leak when doing a setxattr(2) in SMB2+.
--- fs/cifs/smb2ops.c | 2 ++ 1 file changed, 2 insertions(+)
fs/cifs/smb2ops.c +2 -0
@@ -655,6 +655,8 @@ smb2_set_ea(const unsigned int xid, stru rc =SMB2_set_ea (xid, tcon, fid.persistent_fid, fid.volatile_fid, ea, len); +kfree (ea); +SMB2_close (xid, tcon, fid.persistent_fid, fid.volatile_fid);return rc;
Greg Kroah-Hartman
maintainerPATCH 21/56 cifs: Fix slab-out-of-bounds in send_set_info() on SMB2 ACE setting
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Brivio <[email protected]>
commit f46ecbd97f508e68a7806291a139499794874f3d upstream.
A "small" CIFS buffer is not big enough in general to hold a setacl request for SMB2, and we end up overflowing the buffer in send_set_info(). For instance:
# mount.cifs //127.0.0.1/test /mnt/test -o username=test,password=test,nounix,cifsacl # touch /mnt/test/acltest # getcifsacl /mnt/test/acltest REVISION:0x1 CONTROL:0x9004 OWNER:S-1-5-21-2926364953-924364008-418108241-1000 GROUP:S-1-22-2-1001 ACL:S-1-5-21-2926364953-924364008-418108241-1000:ALLOWED/0x0/0x1e01ff ACL:S-1-22-2-1001:ALLOWED/0x0/R ACL:S-1-22-2-1001:ALLOWED/0x0/R ACL:S-1-5-21-2926364953-924364008-418108241-1000:ALLOWED/0x0/0x1e01ff ACL:S-1-1-0:ALLOWED/0x0/R # setcifsacl -a "ACL:S-1-22-2-1004:ALLOWED/0x0/R" /mnt/test/acltest
this setacl will cause the following KASAN splat:
[ 330.777927] BUG: KASAN: slab-out-of-bounds in send_set_info+0x4dd/0xc20 [cifs] [ 330.779696] Write of size 696 at addr ffff88010d5e2860 by task setcifsacl/1012
[ 330.781882] CPU: 1 PID: 1012 Comm: setcifsacl Not tainted 4.18.0-rc2+ #2 [ 330.783140] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [ 330.784395] Call Trace: [ 330.784789] dump_stack+0xc2/0x16b [ 330.786777] print_address_description+0x6a/0x270 [ 330.787520] kasan_report+0x258/0x380 [ 330.788845] memcpy+0x34/0x50 [ 330.789369] send_set_info+0x4dd/0xc20 [cifs] [ 330.799511] SMB2_set_acl+0x76/0xa0 [cifs] [ 330.801395] set_smb2_acl+0x7ac/0xf30 [cifs] [ 330.830888] cifs_xattr_set+0x963/0xe40 [cifs] [ 330.840367] __vfs_setxattr+0x84/0xb0 [ 330.842060] __vfs_setxattr_noperm+0xe6/0x370 [ 330.843848] vfs_setxattr+0xc2/0xd0 [ 330.845519] setxattr+0x258/0x320 [ 330.859211] path_setxattr+0x15b/0x1b0 [ 330.864392] __x64_sys_setxattr+0xc0/0x160 [ 330.866133] do_syscall_64+0x14e/0x4b0 [ 330.876631] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 330.878503] RIP: 0033:0x7ff2e507db0a [ 330.880151] Code: 48 8b 0d 89 93 2c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 bc 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 56 93 2c 00 f7 d8 64 89 01 48 [ 330.885358] RSP: 002b:00007ffdc4903c18 EFLAGS: 00000246 ORIG_RAX: 00000000000000bc [ 330.887733] RAX: ffffffffffffffda RBX: 000055d1170de140 RCX: 00007ff2e507db0a [ 330.890067] RDX: 000055d1170de7d0 RSI: 000055d115b39184 RDI: 00007ffdc4904818 [ 330.892410] RBP: 0000000000000001 R08: 0000000000000000 R09: 000055d1170de7e4 [ 330.894785] R10: 00000000000002b8 R11: 0000000000000246 R12: 0000000000000007 [ 330.897148] R13: 000055d1170de0c0 R14: 0000000000000008 R15: 000055d1170de550
[ 330.901057] Allocated by task 1012: [ 330.902888] kasan_kmalloc+0xa0/0xd0 [ 330.904714] kmem_cache_alloc+0xc8/0x1d0 [ 330.906615] mempool_alloc+0x11e/0x380 [ 330.908496] cifs_small_buf_get+0x35/0x60 [cifs] [ 330.910510] smb2_plain_req_init+0x4a/0xd60 [cifs] [ 330.912551] send_set_info+0x198/0xc20 [cifs] [ 330.914535] SMB2_set_acl+0x76/0xa0 [cifs] [ 330.916465] set_smb2_acl+0x7ac/0xf30 [cifs] [ 330.918453] cifs_xattr_set+0x963/0xe40 [cifs] [ 330.920426] __vfs_setxattr+0x84/0xb0 [ 330.922284] __vfs_setxattr_noperm+0xe6/0x370 [ 330.924213] vfs_setxattr+0xc2/0xd0 [ 330.926008] setxattr+0x258/0x320 [ 330.927762] path_setxattr+0x15b/0x1b0 [ 330.929592] __x64_sys_setxattr+0xc0/0x160 [ 330.931459] do_syscall_64+0x14e/0x4b0 [ 330.933314] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 330.936843] Freed by task 0: [ 330.938588] (stack is not available)
[ 330.941886] The buggy address belongs to the object at ffff88010d5e2800 which belongs to the cache cifs_small_rq of size 448 [ 330.946362] The buggy address is located 96 bytes inside of 448-byte region [ffff88010d5e2800, ffff88010d5e29c0) [ 330.950722] The buggy address belongs to the page: [ 330.952789] page:ffffea0004357880 count:1 mapcount:0 mapping:ffff880108fdca80 index:0x0 compound_mapcount: 0 [ 330.955665] flags: 0x17ffffc0008100(slab|head) [ 330.957760] raw: 0017ffffc0008100 dead000000000100 dead000000000200 ffff880108fdca80 [ 330.960356] raw: 0000000000000000 0000000080100010 00000001ffffffff 0000000000000000 [ 330.963005] page dumped because: kasan: bad access detected
[ 330.967039] Memory state around the buggy address: [ 330.969255] ffff88010d5e2880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 330.971833] ffff88010d5e2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 330.974397] >ffff88010d5e2980: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc [ 330.976956] ^ [ 330.979226] ffff88010d5e2a00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 330.981755] ffff88010d5e2a80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 330.984225] ==================================================================
Fix this by allocating a regular CIFS buffer in smb2_plain_req_init() if the request command is SMB2_SET_INFO.
--- fs/cifs/smb2pdu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/cifs/smb2pdu.c +5 -2
@@ -339,7 +339,10 @@ smb2_plain_req_init(__le16 smb2_command,return rc;/* BB eventually switch this to SMB2 specific small buf size */ - *request_buf =cifs_small_buf_get (); +if (smb2_command ==SMB2_SET_INFO ) + *request_buf =cifs_buf_get (); +else + *request_buf =cifs_small_buf_get ();if (*request_buf ==NULL ) {/* BB should we add a retry in here if not a writepage? */ return -ENOMEM ;
@@ -3363,7 +3366,7 @@ send_set_info(const unsigned int xid, st rc =smb2_send_recv (xid, ses, iov, num, &resp_buftype, flags, &rsp_iov); -cifs_small_buf_release (req); +cifs_buf_release (req); rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base;if (rc !=0 )
Greg Kroah-Hartman
maintainerPATCH 22/56 cifs: Fix infinite loop when using hard mount option
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <[email protected]>
commit 7ffbe65578b44fafdef577a360eb0583929f7c6e upstream.
For every request we send, whether it is SMB1 or SMB2+, we attempt to reconnect tcon (cifs_reconnect_tcon or smb2_reconnect) before carrying out the request.
So, while server->tcpStatus != CifsNeedReconnect, we wait for the reconnection to succeed on wait_event_interruptible_timeout(). If it returns, that means that either the condition was evaluated to true, or timeout elapsed, or it was interrupted by a signal.
Since we're not handling the case where the process woke up due to a received signal (-ERESTARTSYS), the next call to wait_event_interruptible_timeout() will _always_ fail and we end up looping forever inside either cifs_reconnect_tcon() or smb2_reconnect().
Here's an example of how to trigger that:
$ mount.cifs //foo/share /mnt/test -o username=foo,password=foo,vers=1.0,hard
(break connection to server before executing bellow cmd)
$ stat -f /mnt/test & sleep 140 [1] 2511
$ ps -aux -q 2511 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2511 0.0 0.0 12892 1008 pts/0 S 12:24 0:00 stat -f /mnt/test
$ kill -9 2511
(wait for a while; process is stuck in the kernel)
$ ps -aux -q 2511 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 2511 83.2 0.0 12892 1008 pts/0 R 12:24 30:01 stat -f /mnt/test
By using 'hard' mount point means that cifs.ko will keep retrying indefinitely, however we must allow the process to be killed otherwise it would hang the system.
--- fs/cifs/cifssmb.c | 10 ++++++++-- fs/cifs/smb2pdu.c | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-)
fs/cifs/cifssmb.c +8 -2
@@ -151,8 +151,14 @@ cifs_reconnect_tcon(struct cifs_tcon *tc* greater than cifs socket timeout which is 7 seconds */ while (server->tcpStatus == CifsNeedReconnect) { -wait_event_interruptible_timeout (server->response_q, - (server->tcpStatus != CifsNeedReconnect),10 *HZ ); + rc =wait_event_interruptible_timeout (server->response_q, + (server->tcpStatus != CifsNeedReconnect), +10 *HZ ); +if (rc <0 ) { +cifs_dbg (FYI ,"%s: aborting reconnect due to a received" +" signal by the process\n" , __func__); +return -ERESTARTSYS ; + }/* are we still trying to reconnect? */ if (server->tcpStatus != CifsNeedReconnect)
fs/cifs/smb2pdu.c +12 -6
@@ -154,7 +154,7 @@ out:static int smb2_reconnect (__le16 smb2_command,struct cifs_tcon *tcon) { -int rc =0 ; +int rc;struct nls_table *nls_codepage;struct cifs_ses *ses;struct TCP_Server_Info *server;
@@ -165,10 +165,10 @@ smb2_reconnect(__le16 smb2_command, stru* for those three - in the calling routine. */ if (tcon ==NULL ) -return rc; +return 0 ;if (smb2_command ==SMB2_TREE_CONNECT ) -return rc; +return 0 ;if (tcon->tidStatus == CifsExiting) {/*
@@ -211,8 +211,14 @@ smb2_reconnect(__le16 smb2_command, strureturn -EAGAIN ; } -wait_event_interruptible_timeout (server->response_q, - (server->tcpStatus != CifsNeedReconnect),10 *HZ ); + rc =wait_event_interruptible_timeout (server->response_q, + (server->tcpStatus != CifsNeedReconnect), +10 *HZ ); +if (rc <0 ) { +cifs_dbg (FYI ,"%s: aborting reconnect due to a received" +" signal by the process\n" , __func__); +return -ERESTARTSYS ; + }/* are we still trying to reconnect? */ if (server->tcpStatus != CifsNeedReconnect)
@@ -230,7 +236,7 @@ smb2_reconnect(__le16 smb2_command, stru }if (!tcon->ses->need_reconnect && !tcon->need_reconnect) -return rc; +return 0 ; nls_codepage =load_nls_default ();
Greg Kroah-Hartman
maintainerPATCH 23/56 drm: Use kvzalloc for allocating blob property memory
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michel Dänzer <[email protected]>
commit 718b5406cd76f1aa6434311241b7febf0e8571ff upstream.
The property size may be controlled by userspace, can be large (I've seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be physically contiguous.
--- drivers/gpu/drm/drm_property.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/drm_property.c +3 -3
@@ -533,7 +533,7 @@ static void drm_property_free_blob(strucdrm_mode_object_unregister (blob->dev, &blob->base); -kfree (blob); +kvfree (blob); }/**
@@ -560,7 +560,7 @@ drm_property_create_blob(struct drm_deviif (!length || length >ULONG_MAX -sizeof (struct drm_property_blob ))return ERR_PTR (-EINVAL ); - blob =kzalloc (sizeof (struct drm_property_blob )+length,GFP_KERNEL ); + blob =kvzalloc (sizeof (struct drm_property_blob )+length,GFP_KERNEL );if (!blob)return ERR_PTR (-ENOMEM );
@@ -577,7 +577,7 @@ drm_property_create_blob(struct drm_devi ret =__drm_mode_object_add (dev, &blob->base,DRM_MODE_OBJECT_BLOB , true, drm_property_free_blob);if (ret) { -kfree (blob); +kvfree (blob);return ERR_PTR (-EINVAL ); }
Greg Kroah-Hartman
maintainerPATCH 24/56 drm/udl: fix display corruption of the last line
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 99ec9e77511dea55d81729fc80b6c63a61bfa8e0 upstream.
The displaylink hardware has such a peculiarity that it doesn't render a command until next command is received. This produces occasional corruption, such as when setting 22x11 font on the console, only the first line of the cursor will be blinking if the cursor is located at some specific columns.
When we end up with a repeating pixel, the driver has a bug that it leaves one uninitialized byte after the command (and this byte is enough to flush the command and render it - thus it fixes the screen corruption), however whe we end up with a non-repeating pixel, there is no byte appended and this results in temporary screen corruption.
This patch fixes the screen corruption by always appending a byte 0xAF at the end of URB. It also removes the uninitialized byte.
--- drivers/gpu/drm/udl/udl_fb.c | 5 ++++- drivers/gpu/drm/udl/udl_transfer.c | 11 +++++++---- 2 files changed, 11 insertions(+), 5 deletions(-)
drivers/gpu/drm/udl/udl_fb.c +4 -1
@@ -137,7 +137,10 @@ int udl_handle_damage(struct udl_framebuif (cmd > (char *) urb->transfer_buffer) {/* Send partial buffer remaining before exiting */ -int len = cmd - (char *) urb->transfer_buffer; +int len; +if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length) + *cmd++ =0xAF ; + len = cmd - (char *) urb->transfer_buffer; ret =udl_submit_urb (dev, urb, len); bytes_sent += len; }else
drivers/gpu/drm/udl/udl_transfer.c +7 -4
@@ -153,11 +153,11 @@ static void udl_compress_hline16( raw_pixels_count_byte = cmd++;/* we'll know this later */ raw_pixel_start = pixel; - cmd_pixel_end = pixel + (min (MAX_CMD_PIXELS +1 , -min ((int )(pixel_end - pixel) / bpp, - (int )(cmd_buffer_end - cmd) /2 ))) * bpp; + cmd_pixel_end = pixel +min3 (MAX_CMD_PIXELS +1UL , + (unsigned long )(pixel_end - pixel) / bpp, + (unsigned long )(cmd_buffer_end -1 - cmd) /2 ) * bpp; -prefetch_range ((void *) pixel, (cmd_pixel_end - pixel) * bpp); +prefetch_range ((void *) pixel, cmd_pixel_end - pixel); pixel_val16 =get_pixel_val16 (pixel, bpp);while (pixel < cmd_pixel_end) {
@@ -193,6 +193,9 @@ static void udl_compress_hline16(if (pixel > raw_pixel_start) {/* finalize last RAW span */ *raw_pixels_count_byte = ((pixel-raw_pixel_start) / bpp) &0xFF ; + }else { +/* undo unused byte */ + cmd--; } *cmd_pixels_count_byte = ((pixel - cmd_pixel_start) / bpp) &0xFF ;
Greg Kroah-Hartman
maintainerPATCH 25/56 drm/amdgpu: Add amdgpu_atpx_get_dhandle()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude Paul <[email protected]>
commit 4aa5d5eb82bb237d0bb3a38b2a7555054d018081 upstream.
Since it seems that some vendors are storing the ATIF ACPI methods under the same handle that ATPX lives under instead of the device's own handle, we're going to need to be able to retrieve this handle later so we can probe for ATIF there.
--- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 6 ++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c | 6 ++++++ 2 files changed, 12 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu.h +6 -0
@@ -1819,6 +1819,12 @@ static inline bool amdgpu_atpx_dgpu_req_static inline bool amdgpu_has_atpx (void ) {return false; }#endif +#if defined(CONFIG_VGA_SWITCHEROO ) && defined(CONFIG_ACPI ) +void *amdgpu_atpx_get_dhandle (void ); +#else +static inline void *amdgpu_atpx_get_dhandle (void ) {return NULL ; } +#endif +/* * KMS */
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +6 -0
@@ -90,6 +90,12 @@ bool amdgpu_atpx_dgpu_req_power_for_dispreturn amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays; } +#if defined(CONFIG_ACPI ) +void *amdgpu_atpx_get_dhandle (void ) { +return amdgpu_atpx_priv.dhandle; +} +#endif +/** * amdgpu_atpx_call - call an ATPX method *
Greg Kroah-Hartman
maintainerPATCH 26/56 drm/amdgpu: Dynamically probe for ATIF handle (v2)
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lyude Paul <[email protected]>
commit f9ff68521a5541e1fdaeb0ef11871c035b30e409 upstream.
The other day I was testing one of the HP laptops at my office with an i915/amdgpu hybrid setup and noticed that hotplugging was non-functional on almost all of the display outputs. I eventually discovered that all of the external outputs were connected to the amdgpu device instead of i915, and that the hotplugs weren't being detected so long as the GPU was in runtime suspend. After some talking with folks at AMD, I learned that amdgpu is actually supposed to support hotplug detection in runtime suspend so long as the OEM has implemented it properly in the firmware.
On this HP ZBook 15 G4 (the machine in question), amdgpu wasn't managing to find the ATIF handle at all despite the fact that I could see acpi events being sent in response to any hotplugging. After going through dumps of the firmware, I discovered that this machine did in fact support ATIF, but that it's ATIF method lived in an entirely different namespace than this device's handle (the device handle was \_SB_.PCI0.PEG0.PEGP, but ATIF lives in ATPX's handle at \_SB_.PCI0.GFX0).
So, fix this by probing ATPX's ACPI parent's namespace if we can't find ATIF elsewhere, along with storing a pointer to the proper handle to use for ATIF and using that instead of the device's handle.
This fixes HPD detection while in runtime suspend for this ZBook!
v2: Update the comment to reflect how the namespaces are arranged based on the system configuration. (Alex)
--- drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 79 ++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 21 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +58 -21
@@ -65,6 +65,8 @@ struct amdgpu_atif_functions { };struct amdgpu_atif { +acpi_handle handle; +struct amdgpu_atif_notifications notifications;struct amdgpu_atif_functions functions;struct amdgpu_atif_notification_cfg notification_cfg;
@@ -83,8 +85,9 @@ struct amdgpu_atif {* Executes the requested ATIF function (all asics). * Returns a pointer to the acpi output buffer. */ -static union acpi_object *amdgpu_atif_call (acpi_handle handle,int function, -struct acpi_buffer *params) +static union acpi_object *amdgpu_atif_call (struct amdgpu_atif *atif, +int function, +struct acpi_buffer *params) {acpi_status status;union acpi_object atif_arg_elements[2 ];
@@ -107,7 +110,8 @@ static union acpi_object *amdgpu_atif_ca atif_arg_elements[1 ].integer.value =0 ; } - status =acpi_evaluate_object (handle,"ATIF" , &atif_arg, &buffer); + status =acpi_evaluate_object (atif->handle,NULL , &atif_arg, + &buffer);/* Fail only if calling the method fails and ATIF is supported */ if (ACPI_FAILURE (status) && status !=AE_NOT_FOUND ) {
@@ -178,15 +182,14 @@ static void amdgpu_atif_parse_functions(* (all asics). * returns 0 on success, error on failure. */ -static int amdgpu_atif_verify_interface (acpi_handle handle, -struct amdgpu_atif *atif) +static int amdgpu_atif_verify_interface (struct amdgpu_atif *atif) {union acpi_object *info;struct atif_verify_interface output;size_t size;int err =0 ; - info =amdgpu_atif_call (handle,ATIF_FUNCTION_VERIFY_INTERFACE ,NULL ); + info =amdgpu_atif_call (atif,ATIF_FUNCTION_VERIFY_INTERFACE ,NULL );if (!info)return -EIO ;
@@ -213,6 +216,35 @@ out:return err; } +static acpi_handle amdgpu_atif_probe_handle (acpi_handle dhandle) +{ +acpi_handle handle =NULL ; +char acpi_method_name[255 ] = {0 }; +struct acpi_buffer buffer = {sizeof (acpi_method_name), acpi_method_name }; +acpi_status status; + +/* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only +* systems, ATIF is in the dGPU's namespace. +*/ + status =acpi_get_handle (dhandle,"ATIF" , &handle); +if (ACPI_SUCCESS (status)) + goto out; + +if (amdgpu_has_atpx ()) { + status =acpi_get_handle (amdgpu_atpx_get_dhandle (),"ATIF" , + &handle); +if (ACPI_SUCCESS (status)) + goto out; + } + +DRM_DEBUG_DRIVER ("No ATIF handle found\n" ); +return NULL ; +out: +acpi_get_name (handle,ACPI_FULL_PATHNAME , &buffer); +DRM_DEBUG_DRIVER ("Found ATIF handle %s\n" , acpi_method_name); +return handle; +} +/** * amdgpu_atif_get_notification_params - determine notify configuration *
@@ -225,15 +257,16 @@ out:* where n is specified in the result if a notifier is used. * Returns 0 on success, error on failure. */ -static int amdgpu_atif_get_notification_params (acpi_handle handle, -struct amdgpu_atif_notification_cfg *n) +static int amdgpu_atif_get_notification_params (struct amdgpu_atif *atif) {union acpi_object *info; +struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;struct atif_system_params params;size_t size;int err =0 ; - info =amdgpu_atif_call (handle,ATIF_FUNCTION_GET_SYSTEM_PARAMETERS ,NULL ); + info =amdgpu_atif_call (atif,ATIF_FUNCTION_GET_SYSTEM_PARAMETERS , +NULL );if (!info) { err = -EIO ; goto out;
@@ -287,14 +320,15 @@ out:* (all asics). * Returns 0 on success, error on failure. */ -static int amdgpu_atif_get_sbios_requests (acpi_handle handle, -struct atif_sbios_requests *req) +static int amdgpu_atif_get_sbios_requests (struct amdgpu_atif *atif, +struct atif_sbios_requests *req) {union acpi_object *info;size_t size;int count =0 ; - info =amdgpu_atif_call (handle,ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS ,NULL ); + info =amdgpu_atif_call (atif,ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS , +NULL );if (!info)return -EIO ;
@@ -327,11 +361,10 @@ out:* Returns NOTIFY code */ static int amdgpu_atif_handler (struct amdgpu_device *adev, -struct acpi_bus_event *event) +struct acpi_bus_event *event) {struct amdgpu_atif *atif = adev->atif;struct atif_sbios_requests req; -acpi_handle handle;int count; DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
@@ -347,8 +380,7 @@ static int amdgpu_atif_handler(struct amreturn NOTIFY_DONE ;/* Check pending SBIOS requests */ - handle =ACPI_HANDLE (&adev->pdev->dev); - count =amdgpu_atif_get_sbios_requests (handle, &req); + count =amdgpu_atif_get_sbios_requests (atif, &req);if (count <=0 )return NOTIFY_DONE ;
@@ -679,7 +711,7 @@ static int amdgpu_acpi_event(struct noti*/ int amdgpu_acpi_init (struct amdgpu_device *adev) { -acpi_handle handle; +acpi_handle handle, atif_handle;struct amdgpu_atif *atif;struct amdgpu_atcs *atcs = &adev->atcs;int ret;
@@ -696,14 +728,20 @@ int amdgpu_acpi_init(struct amdgpu_devicDRM_DEBUG_DRIVER ("Call to ATCS verify_interface failed: %d\n" , ret); } -/* Call the ATIF method */ +/* Probe for ATIF, and initialize it if found */ + atif_handle =amdgpu_atif_probe_handle (handle); +if (!atif_handle) + goto out; + atif =kzalloc (sizeof (*atif),GFP_KERNEL );if (!atif) {DRM_WARN ("Not enough memory to initialize ATIF\n" ); goto out; } + atif->handle = atif_handle; - ret =amdgpu_atif_verify_interface (handle, atif); +/* Call the ATIF method */ + ret =amdgpu_atif_verify_interface (atif);if (ret) {DRM_DEBUG_DRIVER ("Call to ATIF verify_interface failed: %d\n" , ret);kfree (atif);
@@ -739,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_devic }if (atif->functions.system_params) { - ret =amdgpu_atif_get_notification_params (handle, - &atif->notification_cfg); + ret =amdgpu_atif_get_notification_params (atif);if (ret) {DRM_DEBUG_DRIVER ("Call to GET_SYSTEM_PARAMS failed: %d\n" , ret);
Greg Kroah-Hartman
maintainerPATCH 27/56 jbd2: dont mark block as modified if the handle is out of credits
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit e09463f220ca9a1a1ecfda84fcda658f99a1f12a upstream.
Do not set the b_modified flag in block's journal head should not until after we're sure that jbd2_journal_dirty_metadat() will not abort with an error due to there not being enough space reserved in the jbd2 handle.
Otherwise, future attempts to modify the buffer may lead a large number of spurious errors and warnings.
This addresses CVE-2018-10883.
https://bugzilla.kernel.org/show_bug.cgi?id=200071
--- fs/jbd2/transaction.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
fs/jbd2/transaction.c +8 -1
@@ -1363,6 +1363,13 @@ int jbd2_journal_dirty_metadata(handle_tif (jh->b_transaction == transaction && jh->b_jlist != BJ_Metadata) {jbd_lock_bh_state (bh); +if (jh->b_transaction == transaction && + jh->b_jlist != BJ_Metadata) +pr_err ("JBD2: assertion failure: h_type=%u " +"h_line_no=%u block_no=%llu jlist=%u\n" , + handle->h_type, handle->h_line_no, + (unsigned long long ) bh->b_blocknr, + jh->b_jlist);J_ASSERT_JH (jh, jh->b_transaction != transaction || jh->b_jlist == BJ_Metadata);jbd_unlock_bh_state (bh);
@@ -1382,11 +1389,11 @@ int jbd2_journal_dirty_metadata(handle_t* of the transaction. This needs to be done * once a transaction -bzzz */ - jh->b_modified =1 ;if (handle->h_buffer_credits <=0 ) { ret = -ENOSPC ; goto out_unlock_bh; } + jh->b_modified =1 ; handle->h_buffer_credits--; }
Greg Kroah-Hartman
maintainerPATCH 28/56 ext4: add corruption check in ext4_xattr_set_entry()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 5369a762c882c0b6e9599e4ebbb3a9ba9eee7e2d upstream.
In theory this should have been caught earlier when the xattr list was verified, but in case it got missed, it's simple enough to add check to make sure we don't overrun the xattr buffer.
This addresses CVE-2018-10879.
https://bugzilla.kernel.org/show_bug.cgi?id=200001
--- fs/ext4/xattr.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
fs/ext4/xattr.c +8 -2
@@ -1560,7 +1560,7 @@ static int ext4_xattr_set_entry(struct e handle_t *handle, struct inode *inode, bool is_block) { - struct ext4_xattr_entry *last; + struct ext4_xattr_entry *last, *next;struct ext4_xattr_entry *here = s->here;size_t min_offs = s->end - s->base, name_len =strlen (i->name);int in_inode = i->in_inode;
@@ -1595,7 +1595,13 @@ static int ext4_xattr_set_entry(struct e/* Compute min_offs and last. */ last = s->first; -for (; !IS_LAST_ENTRY (last); last =EXT4_XATTR_NEXT (last)) { +for (; !IS_LAST_ENTRY (last); last = next) { + next =EXT4_XATTR_NEXT (last); +if ((void *)next >= s->end) { +EXT4_ERROR_INODE (inode,"corrupted xattr entries" ); + ret = -EFSCORRUPTED ; + goto out; + }if (!last->e_value_inum && last->e_value_size) {size_t offs =le16_to_cpu (last->e_value_offs);if (offs < min_offs)
Greg Kroah-Hartman
maintainerPATCH 29/56 ext4: always verify the magic number in xattr blocks
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 513f86d73855ce556ea9522b6bfd79f87356dc3a upstream.
If there an inode points to a block which is also some other type of metadata block (such as a block allocation bitmap), the buffer_verified flag can be set when it was validated as that other metadata block type; however, it would make a really terrible external attribute block. The reason why we use the verified flag is to avoid constantly reverifying the block. However, it doesn't take much overhead to make sure the magic number of the xattr block is correct, and this will avoid potential crashes.
This addresses CVE-2018-10879.
https://bugzilla.kernel.org/show_bug.cgi?id=200001
--- fs/ext4/xattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/ext4/xattr.c +3 -3
@@ -230,12 +230,12 @@ __ext4_xattr_check_block(struct inode *i {int error = -EFSCORRUPTED ; -if (buffer_verified (bh)) -return 0 ; -if (BHDR (bh)->h_magic !=cpu_to_le32 (EXT4_XATTR_MAGIC ) ||BHDR (bh)->h_blocks !=cpu_to_le32 (1 )) goto errout; +if (buffer_verified (bh)) +return 0 ; + error = -EFSBADCRC ;if (!ext4_xattr_block_csum_verify (inode, bh)) goto errout;
Greg Kroah-Hartman
maintainerPATCH 30/56 ext4: make sure bitmaps and the inode table dont overlap with bg descriptors
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 77260807d1170a8cf35dbb06e07461a655f67eee upstream.
It's really bad when the allocation bitmaps and the inode table overlap with the block group descriptors, since it causes random corruption of the bg descriptors. So we really want to head those off at the pass.
https://bugzilla.kernel.org/show_bug.cgi?id=199865
--- fs/ext4/super.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
fs/ext4/super.c +25 -0
@@ -2307,6 +2307,7 @@ static int ext4_check_descriptors(structstruct ext4_sb_info *sbi =EXT4_SB (sb);ext4_fsblk_t first_block =le32_to_cpu (sbi->s_es->s_first_data_block);ext4_fsblk_t last_block; +ext4_fsblk_t last_bg_block = sb_block +ext4_bg_num_gdb (sb,0 ) +1 ;ext4_fsblk_t block_bitmap;ext4_fsblk_t inode_bitmap;ext4_fsblk_t inode_table;
@@ -2339,6 +2340,14 @@ static int ext4_check_descriptors(structif (!sb_rdonly (sb))return 0 ; } +if (block_bitmap >= sb_block +1 && + block_bitmap <= last_bg_block) { +ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " +"Block bitmap for group %u overlaps " +"block group descriptors" , i); +if (!sb_rdonly (sb)) +return 0 ; + }if (block_bitmap < first_block || block_bitmap > last_block) {ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " "Block bitmap for group %u not in group "
@@ -2353,6 +2362,14 @@ static int ext4_check_descriptors(structif (!sb_rdonly (sb))return 0 ; } +if (inode_bitmap >= sb_block +1 && + inode_bitmap <= last_bg_block) { +ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " +"Inode bitmap for group %u overlaps " +"block group descriptors" , i); +if (!sb_rdonly (sb)) +return 0 ; + }if (inode_bitmap < first_block || inode_bitmap > last_block) {ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " "Inode bitmap for group %u not in group "
@@ -2367,6 +2384,14 @@ static int ext4_check_descriptors(structif (!sb_rdonly (sb))return 0 ; } +if (inode_table >= sb_block +1 && + inode_table <= last_bg_block) { +ext4_msg (sb,KERN_ERR ,"ext4_check_descriptors: " +"Inode table for group %u overlaps " +"block group descriptors" , i); +if (!sb_rdonly (sb)) +return 0 ; + }if (inode_table < first_block || inode_table + sbi->s_itb_per_group -1 > last_block) { ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
Greg Kroah-Hartman
maintainerPATCH 31/56 ext4: always check block group bounds in ext4_init_block_bitmap()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 819b23f1c501b17b9694325471789e6b5cc2d0d2 upstream.
Regardless of whether the flex_bg feature is set, we should always check to make sure the bits we are setting in the block bitmap are within the block group bounds.
https://bugzilla.kernel.org/show_bug.cgi?id=199865
--- fs/ext4/balloc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
fs/ext4/balloc.c +3 -7
@@ -184,7 +184,6 @@ static int ext4_init_block_bitmap(structunsigned int bit, bit_max;struct ext4_sb_info *sbi =EXT4_SB (sb);ext4_fsblk_t start, tmp; -int flex_bg =0 ;struct ext4_group_info *grp;J_ASSERT_BH (bh,buffer_locked (bh));
@@ -217,22 +216,19 @@ static int ext4_init_block_bitmap(struct start =ext4_group_first_block_no (sb, block_group); -if (ext4_has_feature_flex_bg (sb)) - flex_bg =1 ; -/* Set bits for block and inode bitmaps, and inode table */ tmp =ext4_block_bitmap (sb, gdp); -if (!flex_bg ||ext4_block_in_group (sb, tmp, block_group)) +if (ext4_block_in_group (sb, tmp, block_group))ext4_set_bit (EXT4_B2C (sbi, tmp - start), bh->b_data); tmp =ext4_inode_bitmap (sb, gdp); -if (!flex_bg ||ext4_block_in_group (sb, tmp, block_group)) +if (ext4_block_in_group (sb, tmp, block_group))ext4_set_bit (EXT4_B2C (sbi, tmp - start), bh->b_data); tmp =ext4_inode_table (sb, gdp);for (; tmp <ext4_inode_table (sb, gdp) + sbi->s_itb_per_group; tmp++) { -if (!flex_bg ||ext4_block_in_group (sb, tmp, block_group)) +if (ext4_block_in_group (sb, tmp, block_group))ext4_set_bit (EXT4_B2C (sbi, tmp - start), bh->b_data); }
Greg Kroah-Hartman
maintainerPATCH 32/56 ext4: only look at the bg_flags field if it is valid
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 8844618d8aa7a9973e7b527d038a2a589665002c upstream.
The bg_flags field in the block group descripts is only valid if the uninit_bg or metadata_csum feature is enabled. We were not consistently looking at this field; fix this.
Also block group #0 must never have uninitialized allocation bitmaps, or need to be zeroed, since that's where the root inode, and other special inodes are set up. Check for these conditions and mark the file system as corrupted if they are detected.
This addresses CVE-2018-10876.
https://bugzilla.kernel.org/show_bug.cgi?id=199403
--- fs/ext4/balloc.c | 11 ++++++++++- fs/ext4/ialloc.c | 14 ++++++++++++-- fs/ext4/mballoc.c | 6 ++++-- fs/ext4/super.c | 11 ++++++++++- 4 files changed, 36 insertions(+), 6 deletions(-)
fs/ext4/balloc.c +10 -1
@@ -451,7 +451,16 @@ ext4_read_block_bitmap_nowait(struct sup goto verify; }ext4_lock_group (sb, block_group); -if (desc->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT )) { +if (ext4_has_group_desc_csum (sb) && + (desc->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT ))) { +if (block_group ==0 ) { +ext4_unlock_group (sb, block_group); +unlock_buffer (bh); +ext4_error (sb,"Block bitmap for bg 0 marked " +"uninitialized" ); + err = -EFSCORRUPTED ; + goto out; + } err =ext4_init_block_bitmap (sb, bh, block_group, desc);set_bitmap_uptodate (bh);set_buffer_uptodate (bh);
fs/ext4/ialloc.c +12 -2
@@ -155,7 +155,16 @@ ext4_read_inode_bitmap(struct super_bloc }ext4_lock_group (sb, block_group); -if (desc->bg_flags &cpu_to_le16 (EXT4_BG_INODE_UNINIT )) { +if (ext4_has_group_desc_csum (sb) && + (desc->bg_flags &cpu_to_le16 (EXT4_BG_INODE_UNINIT ))) { +if (block_group ==0 ) { +ext4_unlock_group (sb, block_group); +unlock_buffer (bh); +ext4_error (sb,"Inode bitmap for bg 0 marked " +"uninitialized" ); + err = -EFSCORRUPTED ; + goto out; + }memset (bh->b_data,0 , (EXT4_INODES_PER_GROUP (sb) +7 ) /8 );ext4_mark_bitmap_end (EXT4_INODES_PER_GROUP (sb), sb->s_blocksize *8 , bh->b_data);
@@ -1000,7 +1009,8 @@ got:/* recheck and clear flag under lock if we still need to */ ext4_lock_group (sb, group); -if (gdp->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT )) { +if (ext4_has_group_desc_csum (sb) && + (gdp->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT ))) { gdp->bg_flags &=cpu_to_le16 (~EXT4_BG_BLOCK_UNINIT );ext4_free_group_clusters_set (sb, gdp,ext4_free_clusters_after_init (sb, group, gdp));
fs/ext4/mballoc.c +4 -2
@@ -2444,7 +2444,8 @@ int ext4_mb_add_groupinfo(struct super_b* initialize bb_free to be able to skip * empty groups without initialization */ -if (desc->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT )) { +if (ext4_has_group_desc_csum (sb) && + (desc->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT ))) { meta_group_info[i]->bb_free =ext4_free_clusters_after_init (sb, group, desc); }else {
@@ -3011,7 +3012,8 @@ ext4_mb_mark_diskspace_used(struct ext4_#endif ext4_set_bits (bitmap_bh->b_data, ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); -if (gdp->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT )) { +if (ext4_has_group_desc_csum (sb) && + (gdp->bg_flags &cpu_to_le16 (EXT4_BG_BLOCK_UNINIT ))) { gdp->bg_flags &=cpu_to_le16 (~EXT4_BG_BLOCK_UNINIT ); ext4_free_group_clusters_set(sb, gdp, ext4_free_clusters_after_init(sb,
fs/ext4/super.c +10 -1
@@ -3098,13 +3098,22 @@ static ext4_group_t ext4_has_uninit_itabext4_group_t group, ngroups =EXT4_SB (sb)->s_groups_count;struct ext4_group_desc *gdp =NULL ; +if (!ext4_has_group_desc_csum (sb)) +return ngroups; +for (group =0 ; group < ngroups; group++) { gdp =ext4_get_group_desc (sb, group,NULL );if (!gdp)continue ; -if (!(gdp->bg_flags &cpu_to_le16 (EXT4_BG_INODE_ZEROED ))) +if (gdp->bg_flags &cpu_to_le16 (EXT4_BG_INODE_ZEROED )) +continue ; +if (group !=0 )break ; +ext4_error (sb,"Inode table for bg 0 marked as " +"needing zeroing" ); +if (sb_rdonly (sb)) +return ngroups; }return group;
Greg Kroah-Hartman
maintainerPATCH 33/56 ext4: verify the depth of extent tree in ext4_find_extent()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit bc890a60247171294acc0bd67d211fa4b88d40ba upstream.
If there is a corupted file system where the claimed depth of the extent tree is -1, this can cause a massive buffer overrun leading to sadness.
This addresses CVE-2018-10877.
https://bugzilla.kernel.org/show_bug.cgi?id=199417
--- fs/ext4/ext4_extents.h | 1 + fs/ext4/extents.c | 6 ++++++ 2 files changed, 7 insertions(+)
fs/ext4/ext4_extents.h +1 -0
@@ -91,6 +91,7 @@ struct ext4_extent_header { };#define EXT4_EXT_MAGIC cpu_to_le16(0xf30a) +#define EXT4_MAX_EXTENT_DEPTH 5#define EXT4_EXTENT_TAIL_OFFSET (hdr) \ (sizeof(struct ext4_extent_header) + \
fs/ext4/extents.c +6 -0
@@ -869,6 +869,12 @@ ext4_find_extent(struct inode *inode, ex eh =ext_inode_hdr (inode); depth =ext_depth (inode); +if (depth <0 || depth >EXT4_MAX_EXTENT_DEPTH ) { +EXT4_ERROR_INODE (inode,"inode has invalid extent depth: %d" , + depth); + ret = -EFSCORRUPTED ; + goto err; + }if (path) {ext4_ext_drop_refs (path);
Greg Kroah-Hartman
maintainerPATCH 34/56 ext4: include the illegal physical block in the bad map ext4_error msg
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit bdbd6ce01a70f02e9373a584d0ae9538dcf0a121 upstream.
--- fs/ext4/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ext4/inode.c +2 -2
@@ -402,9 +402,9 @@ static int __check_block_validity(structif (!ext4_data_block_valid (EXT4_SB (inode->i_sb), map->m_pblk, map->m_len)) {ext4_error_inode (inode, func, line, map->m_pblk, -"lblock %lu mapped to illegal pblock " +"lblock %lu mapped to illegal pblock %llu " "(length %d)" , (unsigned long ) map->m_lblk, - map->m_len); + map->m_pblk, map->m_len);return -EFSCORRUPTED ; }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 35/56 ext4: clear i_data in ext4_inode_info when removing inline data
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 6e8ab72a812396996035a37e5ca4b3b99b5d214b upstream.
When converting from an inode from storing the data in-line to a data block, ext4_destroy_inline_data_nolock() was only clearing the on-disk copy of the i_blocks[] array. It was not clearing copy of the i_blocks[] in ext4_inode_info, in i_data[], which is the copy actually used by ext4_map_blocks().
This didn't matter much if we are using extents, since the extents header would be invalid and thus the extents could would re-initialize the extents tree. But if we are using indirect blocks, the previous contents of the i_blocks array will be treated as block numbers, with potentially catastrophic results to the file system integrity and/or user data.
This gets worse if the file system is using a 1k block size and s_first_data is zero, but even without this, the file system can get quite badly corrupted.
This addresses CVE-2018-10881.
https://bugzilla.kernel.org/show_bug.cgi?id=200015
--- fs/ext4/inline.c | 1 + 1 file changed, 1 insertion(+)
fs/ext4/inline.c +1 -0
@@ -437,6 +437,7 @@ static int ext4_destroy_inline_data_nolomemset ((void *)ext4_raw_inode (&is.iloc)->i_block,0 ,EXT4_MIN_INLINE_DATA_SIZE ); +memset (ei->i_data,0 ,EXT4_MIN_INLINE_DATA_SIZE );if (ext4_has_feature_extents (inode->i_sb)) { if (S_ISDIR(inode->i_mode) ||
Greg Kroah-Hartman
maintainerPATCH 36/56 ext4: never move the system.data xattr out of the inode body
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 8cdb5240ec5928b20490a2bb34cb87e9a5f40226 upstream.
When expanding the extra isize space, we must never move the system.data xattr out of the inode body. For performance reasons, it doesn't make any sense, and the inline data implementation assumes that system.data xattr is never in the external xattr block.
This addresses CVE-2018-10880
https://bugzilla.kernel.org/show_bug.cgi?id=200005
--- fs/ext4/xattr.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/ext4/xattr.c +5 -0
@@ -2657,6 +2657,11 @@ static int ext4_xattr_make_inode_space(h last =IFIRST (header);/* Find the entry best suited to be pushed into EA block */ for (; !IS_LAST_ENTRY (last); last =EXT4_XATTR_NEXT (last)) { +/* never move system.data out of the inode */ +if ((last->e_name_len ==4 ) && + (last->e_name_index ==EXT4_XATTR_INDEX_SYSTEM ) && + !memcmp (last->e_name,"data" ,4 )) +continue ; total_size =EXT4_XATTR_LEN (last->e_name_len);if (!last->e_value_inum) total_size += EXT4_XATTR_SIZE(
Greg Kroah-Hartman
maintainerPATCH 37/56 ext4: avoid running out of journal credits when appending to an inline file
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit 8bc1379b82b8e809eef77a9fedbb75c6c297be19 upstream.
Use a separate journal transaction if it turns out that we need to convert an inline file to use an data block. Otherwise we could end up failing due to not having journal credits.
This addresses CVE-2018-10883.
https://bugzilla.kernel.org/show_bug.cgi?id=200071
--- fs/ext4/ext4.h | 3 --- fs/ext4/inline.c | 38 +------------------------------------- fs/ext4/xattr.c | 19 ++----------------- 3 files changed, 3 insertions(+), 57 deletions(-)
fs/ext4/ext4.h +0 -3
@@ -3005,9 +3005,6 @@ extern int ext4_inline_data_fiemap(strucstruct iomap ;extern int ext4_inline_data_iomap (struct inode *inode,struct iomap *iomap); -extern int ext4_try_to_evict_inline_data (handle_t *handle, -struct inode *inode, -int needed);extern int ext4_inline_data_truncate (struct inode *inode,int *has_inline);extern int ext4_convert_inline_data (struct inode *inode);
fs/ext4/inline.c +1 -37
@@ -887,11 +887,11 @@ retry_journal: flags |=AOP_FLAG_NOFS ;if (ret == -ENOSPC ) { +ext4_journal_stop (handle); ret =ext4_da_convert_inline_data_to_extent (mapping, inode, flags, fsdata); -ext4_journal_stop (handle);if (ret == -ENOSPC &&ext4_should_retry_alloc (inode->i_sb, &retries)) goto retry_journal;
@@ -1891,42 +1891,6 @@ out:return (error <0 ? error :0 ); } -/* -* Called during xattr set, and if we can sparse space 'needed', -* just create the extent tree evict the data to the outer block. -* -* We use jbd2 instead of page cache to move data to the 1st block -* so that the whole transaction can be committed as a whole and -* the data isn't lost because of the delayed page cache write. -*/ -int ext4_try_to_evict_inline_data (handle_t *handle, -struct inode *inode, -int needed) -{ -int error; -struct ext4_xattr_entry *entry; -struct ext4_inode *raw_inode; -struct ext4_iloc iloc; - - error =ext4_get_inode_loc (inode, &iloc); -if (error) -return error; - - raw_inode =ext4_raw_inode (&iloc); - entry = (struct ext4_xattr_entry *)((void *)raw_inode + -EXT4_I (inode)->i_inline_off); -if (EXT4_XATTR_LEN (entry->e_name_len) + -EXT4_XATTR_SIZE (le32_to_cpu (entry->e_value_size)) < needed) { - error = -ENOSPC ; - goto out; - } - - error =ext4_convert_inline_data_nolock (handle, inode, &iloc); -out: -brelse (iloc.bh); -return error; -} -int ext4_inline_data_truncate (struct inode *inode,int *has_inline) {handle_t *handle;
fs/ext4/xattr.c +2 -17
@@ -2212,23 +2212,8 @@ int ext4_xattr_ibody_inline_set(handle_tif (EXT4_I (inode)->i_extra_isize ==0 )return -ENOSPC ; error =ext4_xattr_set_entry (i, s, handle, inode, false/* is_block */ ); -if (error) { -if (error == -ENOSPC && -ext4_has_inline_data (inode)) { - error =ext4_try_to_evict_inline_data (handle, inode, -EXT4_XATTR_LEN (strlen (i->name) + -EXT4_XATTR_SIZE (i->value_len))); -if (error) -return error; - error =ext4_xattr_ibody_find (inode, i, is); -if (error) -return error; - error =ext4_xattr_set_entry (i, s, handle, inode, - false/* is_block */ ); - } -if (error) -return error; - } +if (error) +return error; header =IHDR (inode,ext4_raw_inode (&is->iloc));if (!IS_LAST_ENTRY (s->first)) { header->h_magic =cpu_to_le32 (EXT4_XATTR_MAGIC );
Greg Kroah-Hartman
maintainerPATCH 38/56 ext4: add more inode number paranoia checks
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit c37e9e013469521d9adb932d17a1795c139b36db upstream.
If there is a directory entry pointing to a system inode (such as a journal inode), complain and declare the file system to be corrupted.
Also, if the superblock's first inode number field is too small, refuse to mount the file system.
This addresses CVE-2018-10882.
https://bugzilla.kernel.org/show_bug.cgi?id=200069
--- fs/ext4/ext4.h | 5 ----- fs/ext4/inode.c | 3 ++- fs/ext4/super.c | 5 +++++ 3 files changed, 7 insertions(+), 6 deletions(-)
fs/ext4/ext4.h +0 -5
@@ -1501,11 +1501,6 @@ static inline struct ext4_inode_info *EXstatic inline int ext4_valid_inum (struct super_block *sb,unsigned long ino) {return ino ==EXT4_ROOT_INO || - ino ==EXT4_USR_QUOTA_INO || - ino ==EXT4_GRP_QUOTA_INO || - ino ==EXT4_BOOT_LOADER_INO || - ino ==EXT4_JOURNAL_INO || - ino ==EXT4_RESIZE_INO || (ino >=EXT4_FIRST_INO (sb) && ino <=le32_to_cpu (EXT4_SB (sb)->s_es->s_inodes_count)); }
fs/ext4/inode.c +2 -1
@@ -4506,7 +4506,8 @@ static int __ext4_get_inode_loc(struct iint inodes_per_block, inode_offset; iloc->bh =NULL ; -if (!ext4_valid_inum (sb, inode->i_ino)) +if (inode->i_ino <EXT4_ROOT_INO || + inode->i_ino >le32_to_cpu (EXT4_SB (sb)->s_es->s_inodes_count))return -EFSCORRUPTED ; iloc->block_group = (inode->i_ino -1 ) /EXT4_INODES_PER_GROUP (sb);
fs/ext4/super.c +5 -0
@@ -3817,6 +3817,11 @@ static int ext4_fill_super(struct super_ }else { sbi->s_inode_size =le16_to_cpu (es->s_inode_size); sbi->s_first_ino =le32_to_cpu (es->s_first_ino); +if (sbi->s_first_ino <EXT4_GOOD_OLD_FIRST_INO ) { +ext4_msg (sb,KERN_ERR ,"invalid first ino: %u" , + sbi->s_first_ino); + goto failed_mount; + }if ((sbi->s_inode_size <EXT4_GOOD_OLD_INODE_SIZE ) || (!is_power_of_2 (sbi->s_inode_size)) || (sbi->s_inode_size > blocksize)) {
Greg Kroah-Hartman
maintainerPATCH 39/56 ext4: add more mount time checks of the superblock
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Theodore Ts'o <[email protected]>
commit bfe0a5f47ada40d7984de67e59a7d3390b9b9ecc upstream.
The kernel's ext4 mount-time checks were more permissive than e2fsprogs's libext2fs checks when opening a file system. The superblock is considered too insane for debugfs or e2fsck to operate on it, the kernel has no business trying to mount it.
This will make file system fuzzing tools work harder, but the failure cases that they find will be more useful and be easier to evaluate.
--- fs/ext4/super.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
fs/ext4/super.c +26 -11
@@ -3752,6 +3752,13 @@ static int ext4_fill_super(struct super_ le32_to_cpu(es->s_log_block_size)); goto failed_mount; } +if (le32_to_cpu (es->s_log_cluster_size) > + (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { +ext4_msg (sb,KERN_ERR , +"Invalid log cluster size: %u" , +le32_to_cpu (es->s_log_cluster_size)); + goto failed_mount; + }if (le16_to_cpu (sbi->s_es->s_reserved_gdt_blocks) > (blocksize /4 )) { ext4_msg(sb, KERN_ERR,
@@ -3898,13 +3905,6 @@ static int ext4_fill_super(struct super_ "block size (%d)", clustersize, blocksize); goto failed_mount; } -if (le32_to_cpu (es->s_log_cluster_size) > - (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { -ext4_msg (sb,KERN_ERR , -"Invalid log cluster size: %u" , -le32_to_cpu (es->s_log_cluster_size)); - goto failed_mount; - } sbi->s_cluster_bits =le32_to_cpu (es->s_log_cluster_size) -le32_to_cpu (es->s_log_block_size); sbi->s_clusters_per_group =
@@ -3925,10 +3925,10 @@ static int ext4_fill_super(struct super_ } }else {if (clustersize != blocksize) { -ext4_warning (sb,"fragment/cluster size (%d) != " -"block size (%d)" , clustersize, - blocksize); - clustersize = blocksize; +ext4_msg (sb,KERN_ERR , +"fragment/cluster size (%d) != " +"block size (%d)" , clustersize, blocksize); + goto failed_mount; }if (sbi->s_blocks_per_group > blocksize *8 ) { ext4_msg(sb, KERN_ERR,
@@ -3982,6 +3982,13 @@ static int ext4_fill_super(struct super_ ext4_blocks_count(es)); goto failed_mount; } +if ((es->s_first_data_block ==0 ) && (es->s_log_block_size ==0 ) && + (sbi->s_cluster_ratio ==1 )) { +ext4_msg (sb,KERN_WARNING ,"bad geometry: first data " +"block is 0 with a 1k block and cluster size" ); + goto failed_mount; + } + blocks_count = (ext4_blocks_count (es) -le32_to_cpu (es->s_first_data_block) +EXT4_BLOCKS_PER_GROUP (sb) -1 );
@@ -4017,6 +4024,14 @@ static int ext4_fill_super(struct super_ ret = -ENOMEM ; goto failed_mount; } +if (((u64 )sbi->s_groups_count * sbi->s_inodes_per_group) != +le32_to_cpu (es->s_inodes_count)) { +ext4_msg (sb,KERN_ERR ,"inodes count not valid: %u vs %llu" , +le32_to_cpu (es->s_inodes_count), + ((u64 )sbi->s_groups_count * sbi->s_inodes_per_group)); + ret = -EINVAL ; + goto failed_mount; + }bgl_lock_init (sbi->s_blockgroup_lock);
Greg Kroah-Hartman
maintainerPATCH 40/56 ext4: check superblock mapped prior to committing
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jon Derrick <[email protected]>
commit a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 upstream.
This patch attempts to close a hole leading to a BUG seen with hot removals during writes [1].
A block device (NVME namespace in this test case) is formatted to EXT4 without partitions. It's mounted and write I/O is run to a file, then the device is hot removed from the slot. The superblock attempts to be written to the drive which is no longer present.
The typical chain of events leading to the BUG:ext4_commit_super()
__sync_dirty_buffer()
submit_bh()
submit_bh_wbc()
BUG_ON(!buffer_mapped(bh));This fix checks for the superblock's buffer head being mapped prior to syncing.
[1] https://www.spinics.net/lists/linux-ext4/msg56527.html
--- fs/ext4/super.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/ext4/super.c +8 -0
@@ -4763,6 +4763,14 @@ static int ext4_commit_super(struct supeif (!sbh ||block_device_ejected (sb))return error; + +/* +* The superblock bh should be mapped, but it might not be if the +* device was hot-removed. Not much we can do but fail the I/O. +*/ +if (!buffer_mapped (sbh)) +return error; +/* * If the file system is mounted read-only, don't update the * superblock write time. This avoids updating the superblock
Greg Kroah-Hartman
maintainerPATCH 41/56 HID: i2c-hid: Fix "incomplete report" noise
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <[email protected]>
commit ef6eaf27274c0351f7059163918f3795da13199c upstream.
Commit ac75a041048b ("HID: i2c-hid: fix size check and type usage") started writing messages when the ret_size is <= 2 from i2c_master_recv. However, my device i2c-DLL07D1 returns 2 for a short period of time (~0.5s) after I stop moving the pointing stick or touchpad. It varies, but you get ~50 messages each time which spams the log hard.
[ 95.925055] i2c_hid i2c-DLL07D1:01: i2c_hid_get_input: incomplete report (83/2)
This has also been observed with a i2c-ALP0017.
[ 1781.266353] i2c_hid i2c-ALP0017:00: i2c_hid_get_input: incomplete report (30/2)
Only print the message when ret_size is totally invalid and less than 2 to cut down on the log spam.
--- drivers/hid/i2c-hid/i2c-hid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/i2c-hid/i2c-hid.c +1 -1
@@ -486,7 +486,7 @@ static void i2c_hid_get_input(struct i2creturn ; } -if ((ret_size > size) || (ret_size <=2 )) { +if ((ret_size > size) || (ret_size <2 )) {dev_err (&ihid->client->dev,"%s: incomplete report (%d/%d)\n" , __func__, size, ret_size);return ;
Greg Kroah-Hartman
maintainerPATCH 42/56 HID: hiddev: fix potential Spectre v1
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gustavo A. R. Silva <[email protected]>
commit 4f65245f2d178b9cba48350620d76faa4a098841 upstream.
uref->field_index, uref->usage_index, finfo.field_index and cinfo.index can be indirectly controlled by user-space, hence leading to a potential exploitation of the Spectre variant 1 vulnerability.
This issue was detected with the help of Smatch:
drivers/hid/usbhid/hiddev.c:473 hiddev_ioctl_usage() warn: potential spectre issue 'report->field' (local cap) drivers/hid/usbhid/hiddev.c:477 hiddev_ioctl_usage() warn: potential spectre issue 'field->usage' (local cap) drivers/hid/usbhid/hiddev.c:757 hiddev_ioctl() warn: potential spectre issue 'report->field' (local cap) drivers/hid/usbhid/hiddev.c:801 hiddev_ioctl() warn: potential spectre issue 'hid->collection' (local cap)
Fix this by sanitizing such structure fields before using them to index report->field, field->usage and hid->collection
Notice that given that speculation windows are large, the policy is to kill the speculation on the first load and not worry if it can be completed with a dependent load/store [1].
[1] https://marc.info/?l=linux-kernel&m=152449131114778&w=2
--- drivers/hid/usbhid/hiddev.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/hid/usbhid/hiddev.c +11 -0
@@ -36,6 +36,7 @@#include <linux/hiddev.h> #include <linux/compat.h> #include <linux/vmalloc.h> +#include <linux/nospec.h> #include "usbhid.h" #ifdef CONFIG_USB_DYNAMIC_MINORS
@@ -469,10 +470,14 @@ static noinline int hiddev_ioctl_usage(sif (uref->field_index >= report->maxfield) goto inval; + uref->field_index =array_index_nospec (uref->field_index, + report->maxfield); field = report->field[uref->field_index];if (uref->usage_index >= field->maxusage) goto inval; + uref->usage_index =array_index_nospec (uref->usage_index, + field->maxusage); uref->usage_code = field->usage[uref->usage_index].hid;
@@ -499,6 +504,8 @@ static noinline int hiddev_ioctl_usage(sif (uref->field_index >= report->maxfield) goto inval; + uref->field_index =array_index_nospec (uref->field_index, + report->maxfield); field = report->field[uref->field_index];
@@ -753,6 +760,8 @@ static long hiddev_ioctl(struct file *fiif (finfo.field_index >= report->maxfield)break ; + finfo.field_index =array_index_nospec (finfo.field_index, + report->maxfield); field = report->field[finfo.field_index];memset (&finfo,0 ,sizeof (finfo));
@@ -797,6 +806,8 @@ static long hiddev_ioctl(struct file *fiif (cinfo.index >= hid->maxcollection)break ; + cinfo.index =array_index_nospec (cinfo.index, + hid->maxcollection); cinfo.type = hid->collection[cinfo.index].type; cinfo.usage = hid->collection[cinfo.index].usage;
Greg Kroah-Hartman
maintainerPATCH 43/56 HID: debug: check length before copy_to_user()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Rosenberg <[email protected]>
commit 717adfdaf14704fd3ec7fa2c04520c0723247eac upstream.
If our length is greater than the size of the buffer, we overflow the buffer
--- drivers/hid/hid-debug.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/hid/hid-debug.c +7 -1
@@ -1154,6 +1154,8 @@ copy_rest: goto out;if (list->tail > list->head) { len = list->tail - list->head; +if (len > count) + len = count;if (copy_to_user (buffer + ret, &list->hid_debug_buf[list->head], len)) { ret = -EFAULT ;
@@ -1163,6 +1165,8 @@ copy_rest: list->head += len; }else { len =HID_DEBUG_BUFSIZE - list->head; +if (len > count) + len = count;if (copy_to_user (buffer, &list->hid_debug_buf[list->head], len)) { ret = -EFAULT ;
@@ -1170,7 +1174,9 @@ copy_rest: } list->head =0 ; ret += len; - goto copy_rest; + count -= len; +if (count >0 ) + goto copy_rest; } }
Greg Kroah-Hartman
maintainerPATCH 44/56 HID: core: allow concurrent registration of drivers
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Tissoires <[email protected]>
commit 8f732850df1b2b4d8d719f7e606dfb3050e7ea11 upstream.
Detected on the Dell XPS 9365.
The laptop has 2 devices that benefit from the hid-generic auto-unbinding. When those 2 devices are presented to the userspace, udev loads both wacom and hid-multitouch. When this happens, the code in __hid_bus_reprobe_drivers() is called concurrently and the second device gets reprobed twice.
An other bug in the power_supply subsystem prevent to remove the wacom driver if it just finished its initialization, which basically kills the wacom node.
[[email protected]: reformat changelog a bit]
Fixes c17a7476e4c4 ("HID: core: rewrite the hid-generic automatic unbind")
--- drivers/hid/hid-core.c | 5 ++++- include/linux/hid.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-)
drivers/hid/hid-core.c +4 -1
@@ -1942,6 +1942,8 @@ static int hid_device_probe(struct devic } hdev->io_started = false; +clear_bit (ffs (HID_STAT_REPROBED ), &hdev->status); +if (!hdev->driver) { id =hid_match_device (hdev, hdrv);if (id ==NULL ) {
@@ -2205,7 +2207,8 @@ static int __hid_bus_reprobe_drivers(strstruct hid_device *hdev =to_hid_device (dev);if (hdev->driver == hdrv && - !hdrv->match (hdev, hid_ignore_special_drivers)) + !hdrv->match (hdev, hid_ignore_special_drivers) && + !test_and_set_bit (ffs (HID_STAT_REPROBED ), &hdev->status))return device_reprobe (dev);return 0 ;
include/linux/hid.h +2 -1
@@ -502,6 +502,7 @@ struct hid_output_fifo {#define HID_STAT_ADDED BIT(0)#define HID_STAT_PARSED BIT(1) +#define HID_STAT_REPROBED BIT(3)struct hid_input {struct list_head list;
@@ -568,7 +569,7 @@ struct hid_device { /* device repobool battery_avoid_query;#endif -unsigned int status;/* see STAT flags above */ +unsigned long status;/* see STAT flags above */ unsigned claimed;/* Claimed by hidinput, hiddev? */ unsigned quirks;/* Various quirks the device can pull on us */ bool io_started;/* If IO has started */
Greg Kroah-Hartman
maintainerPATCH 45/56 i2c: core: smbus: fix a potential missing-check bug
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenwen Wang <[email protected]>
commit 8e03477cb709b73a2c1e1f4349ee3b7b33c50416 upstream.
In i2c_smbus_xfer_emulated(), the function i2c_transfer() is invoked to transfer i2c messages. The number of actual transferred messages is returned and saved to 'status'. If 'status' is negative, that means an error occurred during the transfer process. In that case, the value of 'status' is an error code to indicate the reason of the transfer failure. In most cases, i2c_transfer() can transfer 'num' messages with no error. And so 'status' == 'num'. However, due to unexpected errors, it is probable that only partial messages are transferred by i2c_transfer(). As a result, 'status' != 'num'. This special case is not checked after the invocation of i2c_transfer() and can potentially lead to unexpected issues in the following execution since it is expected that 'status' == 'num'.
This patch checks the return value of i2c_transfer() and returns an error code -EIO if the number of actual transferred messages 'status' is not equal to 'num'.
--- drivers/i2c/i2c-core-smbus.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/i2c/i2c-core-smbus.c +2 -0
@@ -466,6 +466,8 @@ static s32 i2c_smbus_xfer_emulated(struc status =i2c_transfer (adapter, msg, num);if (status <0 )return status; +if (status != num) +return -EIO ;/* Check PEC if last message is a read */ if (i && (msg[num-1 ].flags &I2C_M_RD )) {
Greg Kroah-Hartman
maintainerPATCH 46/56 i2c: smbus: kill memory leak on emulated and failed DMA SMBus xfers
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Rosin <[email protected]>
commit 9aa613674f89d01248ae2e4afe691b515ff8fbb6 upstream.
If DMA safe memory was allocated, but the subsequent I2C transfer fails the memory is leaked. Plug this leak.
--- drivers/i2c/i2c-core-smbus.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/i2c/i2c-core-smbus.c +9 -5
@@ -465,15 +465,18 @@ static s32 i2c_smbus_xfer_emulated(struc status =i2c_transfer (adapter, msg, num);if (status <0 ) -return status; -if (status != num) -return -EIO ; + goto cleanup; +if (status != num) { + status = -EIO ; + goto cleanup; + } + status =0 ;/* Check PEC if last message is a read */ if (i && (msg[num-1 ].flags &I2C_M_RD )) { status =i2c_smbus_check_pec (partial_pec, &msg[num-1 ]);if (status <0 ) -return status; + goto cleanup; }if (read_write ==I2C_SMBUS_READ )
@@ -499,12 +502,13 @@ static s32 i2c_smbus_xfer_emulated(strucbreak ; } +cleanup:if (msg[0 ].flags &I2C_M_DMA_SAFE )kfree (msg[0 ].buf);if (msg[1 ].flags &I2C_M_DMA_SAFE )kfree (msg[1 ].buf); -return 0 ; +return status; }/**
Greg Kroah-Hartman
maintainerPATCH 47/56 fs: allow per-device dax status checking for filesystems
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <[email protected]>
commit ba23cba9b3bdc967aabdc6ff1e3e9b11ce05bb4f upstream.
Change bdev_dax_supported so it takes a bdev parameter. This enables multi-device filesystems like xfs to check that a dax device can work for the particular filesystem. Once that's in place, actually fix all the parts of XFS where we need to be able to distinguish between datadev and rtdev.
This patch fixes the problem where we screw up the dax support checking in xfs if the datadev and rtdev have different dax capabilities.
--- drivers/dax/super.c | 26 +++++++++++++------------- fs/ext2/super.c | 2 +- fs/ext4/super.c | 2 +- fs/xfs/xfs_ioctl.c | 3 ++- fs/xfs/xfs_iops.c | 30 +++++++++++++++++++++++++----- fs/xfs/xfs_super.c | 10 ++++++++-- include/linux/dax.h | 9 +++++---- 7 files changed, 55 insertions(+), 27 deletions(-)
drivers/dax/super.c +13 -13
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);/** * __bdev_dax_supported() - Check if the device supports dax for filesystem -* @sb: The superblock of the device +* @bdev: block device to check * @blocksize: The block size of the device * * This is a library function for filesystems to check if the block device
@@ -82,33 +82,33 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);* * Return: negative errno if unsupported, 0 if supported. */ -int __bdev_dax_supported (struct super_block *sb,int blocksize) +int __bdev_dax_supported (struct block_device *bdev,int blocksize) { -struct block_device *bdev = sb->s_bdev;struct dax_device *dax_dev;pgoff_t pgoff;int err, id;void *kaddr;pfn_t pfn;long len; +char buf[BDEVNAME_SIZE ];if (blocksize !=PAGE_SIZE ) { -pr_debug ("VFS (%s): error: unsupported blocksize for dax\n" , - sb->s_id); +pr_debug ("%s: error: unsupported blocksize for dax\n" , +bdevname (bdev, buf));return -EINVAL ; } err =bdev_dax_pgoff (bdev,0 ,PAGE_SIZE , &pgoff);if (err) { -pr_debug ("VFS (%s): error: unaligned partition for dax\n" , - sb->s_id); +pr_debug ("%s: error: unaligned partition for dax\n" , +bdevname (bdev, buf));return err; } dax_dev =dax_get_by_host (bdev->bd_disk->disk_name);if (!dax_dev) { -pr_debug ("VFS (%s): error: device does not support dax\n" , - sb->s_id); +pr_debug ("%s: error: device does not support dax\n" , +bdevname (bdev, buf));return -EOPNOTSUPP ; }
@@ -119,8 +119,8 @@ int __bdev_dax_supported(struct super_blput_dax (dax_dev);if (len <1 ) { -pr_debug ("VFS (%s): error: dax access failed (%ld)\n" , - sb->s_id, len); +pr_debug ("%s: error: dax access failed (%ld)\n" , +bdevname (bdev, buf), len);return len <0 ? len : -EIO ; }
@@ -137,8 +137,8 @@ int __bdev_dax_supported(struct super_bl }else if (pfn_t_devmap (pfn)) {/* pass */ ; }else { -pr_debug ("VFS (%s): error: dax support not enabled\n" , - sb->s_id); +pr_debug ("%s: error: dax support not enabled\n" , +bdevname (bdev, buf));return -EOPNOTSUPP ; }
fs/ext2/super.c +1 -1
@@ -961,7 +961,7 @@ static int ext2_fill_super(struct super_ blocksize =BLOCK_SIZE <<le32_to_cpu (sbi->s_es->s_log_block_size);if (sbi->s_mount_opt &EXT2_MOUNT_DAX ) { - err =bdev_dax_supported (sb, blocksize); + err =bdev_dax_supported (sb->s_bdev, blocksize);if (err) {ext2_msg (sb,KERN_ERR ,"DAX unsupported by block device. Turning off DAX." );
fs/ext4/super.c +1 -1
@@ -3773,7 +3773,7 @@ static int ext4_fill_super(struct super_ " that may contain inline data"); sbi->s_mount_opt &= ~EXT4_MOUNT_DAX ; } - err =bdev_dax_supported (sb, blocksize); + err =bdev_dax_supported (sb->s_bdev, blocksize);if (err) {ext4_msg (sb,KERN_ERR ,"DAX unsupported by block device. Turning off DAX." );
fs/xfs/xfs_ioctl.c +2 -1
@@ -1103,7 +1103,8 @@ xfs_ioctl_setattr_dax_invalidate(if (fa->fsx_xflags &FS_XFLAG_DAX ) {if (!(S_ISREG (inode->i_mode) ||S_ISDIR (inode->i_mode)))return -EINVAL ; -if (bdev_dax_supported (sb, sb->s_blocksize) <0 ) +if (bdev_dax_supported (xfs_find_bdev_for_inode (VFS_I (ip)), + sb->s_blocksize) <0 )return -EINVAL ; }
fs/xfs/xfs_iops.c +25 -5
@@ -1195,6 +1195,30 @@ static const struct inode_operations xfs .update_time = xfs_vn_update_time, }; +/* Figure out if this file actually supports DAX. */ +static bool +xfs_inode_supports_dax ( +struct xfs_inode *ip) +{ +struct xfs_mount *mp = ip->i_mount; + +/* Only supported on non-reflinked files. */ +if (!S_ISREG (VFS_I (ip)->i_mode) ||xfs_is_reflink_inode (ip)) +return false; + +/* DAX mount option or DAX iflag must be set. */ +if (!(mp->m_flags &XFS_MOUNT_DAX ) && + !(ip->i_d.di_flags2 &XFS_DIFLAG2_DAX )) +return false; + +/* Block size must match page size */ +if (mp->m_sb.sb_blocksize !=PAGE_SIZE ) +return false; + +/* Device has to support DAX too. */ +return xfs_find_daxdev_for_inode (VFS_I (ip)) !=NULL ; +} + STATIC void xfs_diflags_to_iflags( struct inode *inode,
@@ -1213,11 +1237,7 @@ xfs_diflags_to_iflags( inode->i_flags |=S_SYNC ;if (flags &XFS_DIFLAG_NOATIME ) inode->i_flags |=S_NOATIME ; -if (S_ISREG (inode->i_mode) && - ip->i_mount->m_sb.sb_blocksize ==PAGE_SIZE && - !xfs_is_reflink_inode (ip) && - (ip->i_mount->m_flags &XFS_MOUNT_DAX || - ip->i_d.di_flags2 &XFS_DIFLAG2_DAX )) +if (xfs_inode_supports_dax (ip)) inode->i_flags |=S_DAX ; }
fs/xfs/xfs_super.c +8 -2
@@ -1690,11 +1690,17 @@ xfs_fs_fill_super( sb->s_flags |=SB_I_VERSION ;if (mp->m_flags &XFS_MOUNT_DAX ) { +int error2 =0 ; +xfs_warn (mp,"DAX enabled. Warning: EXPERIMENTAL, use at your own risk" ); - error =bdev_dax_supported (sb, sb->s_blocksize); -if (error) { + error =bdev_dax_supported (mp->m_ddev_targp->bt_bdev, + sb->s_blocksize); +if (mp->m_rtdev_targp) + error2 =bdev_dax_supported (mp->m_rtdev_targp->bt_bdev, + sb->s_blocksize); +if (error && error2) {xfs_alert (mp,"DAX unsupported by block device. Turning off DAX." ); mp->m_flags &= ~XFS_MOUNT_DAX ;
include/linux/dax.h +5 -4
@@ -64,10 +64,10 @@ static inline bool dax_write_cache_enablstruct writeback_control ;int bdev_dax_pgoff (struct block_device *,sector_t ,size_t ,pgoff_t *pgoff);#if IS_ENABLED (CONFIG_FS_DAX ) -int __bdev_dax_supported (struct super_block *sb,int blocksize); -static inline int bdev_dax_supported (struct super_block *sb,int blocksize) +int __bdev_dax_supported (struct block_device *bdev,int blocksize); +static inline int bdev_dax_supported (struct block_device *bdev,int blocksize) { -return __bdev_dax_supported (sb, blocksize); +return __bdev_dax_supported (bdev, blocksize); }static inline struct dax_device *fs_dax_get_by_host (const char *host)
@@ -84,7 +84,8 @@ struct dax_device *fs_dax_get_by_bdev(stint dax_writeback_mapping_range (struct address_space *mapping,struct block_device *bdev,struct writeback_control *wbc);#else -static inline int bdev_dax_supported (struct super_block *sb,int blocksize) +static inline int bdev_dax_supported (struct block_device *bdev, +int blocksize) {return -EOPNOTSUPP ; }
Greg Kroah-Hartman
maintainerPATCH 48/56 dax: change bdev_dax_supported() to support boolean returns
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jiang <[email protected]>
commit 80660f20252d6f76c9f203874ad7c7a4a8508cf8 upstream.
The function return values are confusing with the way the function is named. We expect a true or false return value but it actually returns 0/-errno. This makes the code very confusing. Changing the return values to return a bool where if DAX is supported then return true and no DAX support returns false.
--- drivers/dax/super.c | 16 ++++++++-------- fs/ext2/super.c | 3 +-- fs/ext4/super.c | 3 +-- fs/xfs/xfs_ioctl.c | 4 ++-- fs/xfs/xfs_super.c | 12 ++++++------ include/linux/dax.h | 8 ++++---- 6 files changed, 22 insertions(+), 24 deletions(-)
drivers/dax/super.c +8 -8
@@ -80,9 +80,9 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);* This is a library function for filesystems to check if the block device * can be mounted with dax option. * -* Return: negative errno if unsupported, 0 if supported. +* Return: true if supported, false if unsupported */ -int __bdev_dax_supported (struct block_device *bdev,int blocksize) +bool __bdev_dax_supported (struct block_device *bdev,int blocksize) {struct dax_device *dax_dev;pgoff_t pgoff;
@@ -95,21 +95,21 @@ int __bdev_dax_supported(struct block_deif (blocksize !=PAGE_SIZE ) {pr_debug ("%s: error: unsupported blocksize for dax\n" ,bdevname (bdev, buf)); -return -EINVAL ; +return false; } err =bdev_dax_pgoff (bdev,0 ,PAGE_SIZE , &pgoff);if (err) {pr_debug ("%s: error: unaligned partition for dax\n" ,bdevname (bdev, buf)); -return err; +return false; } dax_dev =dax_get_by_host (bdev->bd_disk->disk_name);if (!dax_dev) {pr_debug ("%s: error: device does not support dax\n" ,bdevname (bdev, buf)); -return -EOPNOTSUPP ; +return false; } id =dax_read_lock ();
@@ -121,7 +121,7 @@ int __bdev_dax_supported(struct block_deif (len <1 ) {pr_debug ("%s: error: dax access failed (%ld)\n" ,bdevname (bdev, buf), len); -return len <0 ? len : -EIO ; +return false; }if (IS_ENABLED (CONFIG_FS_DAX_LIMITED ) &&pfn_t_special (pfn)) {
@@ -139,10 +139,10 @@ int __bdev_dax_supported(struct block_de } else {pr_debug ("%s: error: dax support not enabled\n" ,bdevname (bdev, buf)); -return -EOPNOTSUPP ; +return false; } -return 0 ; +return true; }EXPORT_SYMBOL_GPL (__bdev_dax_supported);#endif
fs/ext2/super.c +1 -2
@@ -961,8 +961,7 @@ static int ext2_fill_super(struct super_ blocksize =BLOCK_SIZE <<le32_to_cpu (sbi->s_es->s_log_block_size);if (sbi->s_mount_opt &EXT2_MOUNT_DAX ) { - err =bdev_dax_supported (sb->s_bdev, blocksize); -if (err) { +if (!bdev_dax_supported (sb->s_bdev, blocksize)) {ext2_msg (sb,KERN_ERR ,"DAX unsupported by block device. Turning off DAX." ); sbi->s_mount_opt &= ~EXT2_MOUNT_DAX ;
fs/ext4/super.c +1 -2
@@ -3773,8 +3773,7 @@ static int ext4_fill_super(struct super_ " that may contain inline data"); sbi->s_mount_opt &= ~EXT4_MOUNT_DAX ; } - err =bdev_dax_supported (sb->s_bdev, blocksize); -if (err) { +if (!bdev_dax_supported (sb->s_bdev, blocksize)) {ext4_msg (sb,KERN_ERR ,"DAX unsupported by block device. Turning off DAX." ); sbi->s_mount_opt &= ~EXT4_MOUNT_DAX ;
fs/xfs/xfs_ioctl.c +2 -2
@@ -1103,8 +1103,8 @@ xfs_ioctl_setattr_dax_invalidate(if (fa->fsx_xflags &FS_XFLAG_DAX ) {if (!(S_ISREG (inode->i_mode) ||S_ISDIR (inode->i_mode)))return -EINVAL ; -if (bdev_dax_supported (xfs_find_bdev_for_inode (VFS_I (ip)), - sb->s_blocksize) <0 ) +if (!bdev_dax_supported (xfs_find_bdev_for_inode (VFS_I (ip)), + sb->s_blocksize))return -EINVAL ; }
fs/xfs/xfs_super.c +6 -6
@@ -1690,17 +1690,17 @@ xfs_fs_fill_super( sb->s_flags |=SB_I_VERSION ;if (mp->m_flags &XFS_MOUNT_DAX ) { -int error2 =0 ; +bool rtdev_is_dax = false, datadev_is_dax;xfs_warn (mp,"DAX enabled. Warning: EXPERIMENTAL, use at your own risk" ); - error =bdev_dax_supported (mp->m_ddev_targp->bt_bdev, - sb->s_blocksize); + datadev_is_dax =bdev_dax_supported (mp->m_ddev_targp->bt_bdev, + sb->s_blocksize);if (mp->m_rtdev_targp) - error2 =bdev_dax_supported (mp->m_rtdev_targp->bt_bdev, - sb->s_blocksize); -if (error && error2) { + rtdev_is_dax =bdev_dax_supported ( + mp->m_rtdev_targp->bt_bdev, sb->s_blocksize); +if (!rtdev_is_dax && !datadev_is_dax) {xfs_alert (mp,"DAX unsupported by block device. Turning off DAX." ); mp->m_flags &= ~XFS_MOUNT_DAX ;
include/linux/dax.h +4 -4
@@ -64,8 +64,8 @@ static inline bool dax_write_cache_enablstruct writeback_control ;int bdev_dax_pgoff (struct block_device *,sector_t ,size_t ,pgoff_t *pgoff);#if IS_ENABLED (CONFIG_FS_DAX ) -int __bdev_dax_supported (struct block_device *bdev,int blocksize); -static inline int bdev_dax_supported (struct block_device *bdev,int blocksize) +bool __bdev_dax_supported (struct block_device *bdev,int blocksize); +static inline bool bdev_dax_supported (struct block_device *bdev,int blocksize) {return __bdev_dax_supported (bdev, blocksize); }
@@ -84,10 +84,10 @@ struct dax_device *fs_dax_get_by_bdev(stint dax_writeback_mapping_range (struct address_space *mapping,struct block_device *bdev,struct writeback_control *wbc);#else -static inline int bdev_dax_supported (struct block_device *bdev, +static inline bool bdev_dax_supported (struct block_device *bdev,int blocksize) { -return -EOPNOTSUPP ; +return false; }static inline struct dax_device *fs_dax_get_by_host (const char *host)
Greg Kroah-Hartman
maintainerPATCH 49/56 dax: check for QUEUE_FLAG_DAX in bdev_dax_supported()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ross Zwisler <[email protected]>
commit 15256f6cc4b44f2e70503758150267fd2a53c0d6 upstream.
Add an explicit check for QUEUE_FLAG_DAX to __bdev_dax_supported(). This is needed for DM configurations where the first element in the dm-linear or dm-stripe target supports DAX, but other elements do not. Without this check __bdev_dax_supported() will pass for such devices, letting a filesystem on that device mount with the DAX option.
--- drivers/dax/super.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/dax/super.c +8 -0
@@ -85,6 +85,7 @@ EXPORT_SYMBOL_GPL(fs_dax_get_by_bdev);bool __bdev_dax_supported (struct block_device *bdev,int blocksize) {struct dax_device *dax_dev; +struct request_queue *q;pgoff_t pgoff;int err, id;void *kaddr;
@@ -97,6 +98,13 @@ bool __bdev_dax_supported(struct block_d bdevname(bdev, buf));return false; } + + q =bdev_get_queue (bdev); +if (!q || !blk_queue_dax (q)) { +pr_debug ("%s: error: request queue doesn't support dax\n" , +bdevname (bdev, buf)); +return false; + } err =bdev_dax_pgoff (bdev,0 ,PAGE_SIZE , &pgoff);if (err) {
Greg Kroah-Hartman
maintainerPATCH 50/56 dm: prevent DAX mounts if not supported
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ross Zwisler <[email protected]>
commit dbc626597c39b24cefce09fbd8e9dea85869a801 upstream.
Currently device_supports_dax() just checks to see if the QUEUE_FLAG_DAX flag is set on the device's request queue to decide whether or not the device supports filesystem DAX. Really we should be using bdev_dax_supported() like filesystems do at mount time. This performs other tests like checking to make sure the dax_direct_access() path works.
We also explicitly clear QUEUE_FLAG_DAX on the DM device's request queue if any of the underlying devices do not support DAX. This makes the handling of QUEUE_FLAG_DAX consistent with the setting/clearing of most other flags in dm_table_set_restrictions().
Now that bdev_dax_supported() explicitly checks for QUEUE_FLAG_DAX, this will ensure that filesystems built upon DM devices will only be able to mount with DAX if all underlying devices also support DAX.
--- drivers/md/dm-table.c | 7 ++++--- drivers/md/dm.c | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/md/dm-table.c +4 -3
@@ -885,9 +885,7 @@ EXPORT_SYMBOL_GPL(dm_table_set_type);static int device_supports_dax (struct dm_target *ti,struct dm_dev *dev,sector_t start,sector_t len,void *data) { -struct request_queue *q =bdev_get_queue (dev->bdev); - -return q &&blk_queue_dax (q); +return bdev_dax_supported (dev->bdev,PAGE_SIZE ); }static bool dm_table_supports_dax (struct dm_table *t)
@@ -1907,6 +1905,9 @@ void dm_table_set_restrictions(struct dmif (dm_table_supports_dax (t))blk_queue_flag_set (QUEUE_FLAG_DAX , q); +else +blk_queue_flag_clear (QUEUE_FLAG_DAX , q); +if (dm_table_supports_dax_write_cache (t))dax_write_cache (t->md->dax_dev, true);
drivers/md/dm.c +1 -2
@@ -1056,8 +1056,7 @@ static long dm_dax_direct_access(structif (len <1 ) goto out; nr_pages =min (len, nr_pages); -if (ti->type->direct_access) - ret = ti->type->direct_access (ti, pgoff, nr_pages, kaddr, pfn); + ret = ti->type->direct_access (ti, pgoff, nr_pages, kaddr, pfn); out:dm_put_live_table (md, srcu_idx);
Greg Kroah-Hartman
maintainerPATCH 51/56 mtd: cfi_cmdset_0002: Change definition naming to retry write operation
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tokunori Ikegami <[email protected]>
commit 85a82e28b023de9b259a86824afbd6ba07bd6475 upstream.
The definition can be used for other program and erase operations also. So change the naming to MAX_RETRIES from MAX_WORD_RETRIES.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +3 -3
@@ -42,7 +42,7 @@#define AMD_BOOTLOC_BUG #define FORCE_WORD_WRITE 0 -#define MAX_WORD_RETRIES 3 +#define MAX_RETRIES 3#define SST49LF004B 0x0060#define SST49LF040B 0x0050
@@ -1647,7 +1647,7 @@ static int __xipram do_write_oneword(strmap_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_WORD_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) goto retry; ret = -EIO ;
@@ -2106,7 +2106,7 @@ retry:map_write (map,CMD (0xF0 ), chip->start);/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_WORD_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) goto retry; ret = -EIO ;
Greg Kroah-Hartman
maintainerPATCH 52/56 mtd: cfi_cmdset_0002: Change erase functions to retry for error
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tokunori Ikegami <[email protected]>
commit 45f75b8a919a4255f52df454f1ffdee0e42443b2 upstream.
For the word write functions it is retried for error. But it is not implemented to retry for the erase functions. To make sure for the erase functions change to retry as same.
This is needed to prevent the flash erase error caused only once. It was caused by the error case of chip_good() in the do_erase_oneblock(). Also it was confirmed on the MACRONIX flash device MX29GL512FHT2I-11G. But the error issue behavior is not able to reproduce at this moment. The flash controller is parallel Flash interface integrated on BCM53003.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/mtd/chips/cfi_cmdset_0002.c +10 -0
@@ -2241,6 +2241,7 @@ static int __xipram do_erase_chip(structunsigned long int adr;DECLARE_WAITQUEUE (wait, current);int ret =0 ; +int retry_cnt =0 ; adr = cfi->addr_unlock1;
@@ -2258,6 +2259,7 @@ static int __xipram do_erase_chip(structENABLE_VPP (map);xip_disable (map, chip, adr); + retry:cfi_send_gen_cmd (0xAA , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x55 , cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x80 , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );
@@ -2312,6 +2314,9 @@ static int __xipram do_erase_chip(structmap_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ +if (++retry_cnt <=MAX_RETRIES ) + goto retry; + ret = -EIO ; }
@@ -2331,6 +2336,7 @@ static int __xipram do_erase_oneblock(stunsigned long timeo = jiffies +HZ ;DECLARE_WAITQUEUE (wait, current);int ret =0 ; +int retry_cnt =0 ; adr += chip->start;
@@ -2348,6 +2354,7 @@ static int __xipram do_erase_oneblock(stENABLE_VPP (map);xip_disable (map, chip, adr); + retry:cfi_send_gen_cmd (0xAA , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x55 , cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type,NULL );cfi_send_gen_cmd (0x80 , cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type,NULL );
@@ -2405,6 +2412,9 @@ static int __xipram do_erase_oneblock(stmap_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ +if (++retry_cnt <=MAX_RETRIES ) + goto retry; + ret = -EIO ; }
Greg Kroah-Hartman
maintainerPATCH 53/56 mtd: cfi_cmdset_0002: Change erase functions to check chip good only
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tokunori Ikegami <[email protected]>
commit 79ca484b613041ca223f74b34608bb6f5221724b upstream.
Currently the functions use to check both chip ready and good. But the chip ready is not enough to check the operation status. So change this to check the chip good instead of this. About the retry functions to make sure the error handling remain it.
--- drivers/mtd/chips/cfi_cmdset_0002.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/mtd/chips/cfi_cmdset_0002.c +12 -10
@@ -2296,12 +2296,13 @@ static int __xipram do_erase_chip(struct chip->erase_suspended =0 ; } -if (chip_ready (map, adr)) +if (chip_good (map, adr,map_word_ff (map)))break ;if (time_after (jiffies, timeo)) {printk (KERN_WARNING "MTD %s(): software timeout\n" , __func__ ); + ret = -EIO ;break ; }
@@ -2309,15 +2310,15 @@ static int __xipram do_erase_chip(structUDELAY (map, chip, adr,1000000 /HZ ); }/* Did we succeed? */ -if (!chip_good (map, adr,map_word_ff (map))) { +if (ret) {/* reset on all failures. */ map_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) { + ret =0 ; goto retry; - - ret = -EIO ; + } } chip->state =FL_READY ;
@@ -2391,7 +2392,7 @@ static int __xipram do_erase_oneblock(st chip->erase_suspended =0 ; } -if (chip_ready (map, adr)) { +if (chip_good (map, adr,map_word_ff (map))) {xip_enable (map, chip, adr);break ; }
@@ -2400,6 +2401,7 @@ static int __xipram do_erase_oneblock(stxip_enable (map, chip, adr);printk (KERN_WARNING "MTD %s(): software timeout\n" , __func__ ); + ret = -EIO ;break ; }
@@ -2407,15 +2409,15 @@ static int __xipram do_erase_oneblock(stUDELAY (map, chip, adr,1000000 /HZ ); }/* Did we succeed? */ -if (!chip_good (map, adr,map_word_ff (map))) { +if (ret) {/* reset on all failures. */ map_write ( map,CMD (0xF0 ), chip->start );/* FIXME - should have reset delay before continuing */ -if (++retry_cnt <=MAX_RETRIES ) +if (++retry_cnt <=MAX_RETRIES ) { + ret =0 ; goto retry; - - ret = -EIO ; + } } chip->state =FL_READY ;
Greg Kroah-Hartman
maintainerPATCH 54/56 netfilter: nf_log: dont hold nf_log_mutex during user access
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit ce00bf07cc95a57cd20b208e02b3c2604e532ae8 upstream.
The old code would indefinitely block other users of nf_log_mutex if a userspace access in proc_dostring() blocked e.g. due to a userfaultfd region. Fix it by moving proc_dostring() out of the locked region.
This is a followup to commit 266d07cb1c9a ("netfilter: nf_log: fix sleeping function called from invalid context"), which changed this code from using rcu_read_lock() to taking nf_log_mutex.
--- net/netfilter/nf_log.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
net/netfilter/nf_log.c +6 -3
@@ -457,14 +457,17 @@ static int nf_log_proc_dostring(struct crcu_assign_pointer (net->nf.nf_loggers[tindex], logger);mutex_unlock (&nf_log_mutex); }else { +struct ctl_table tmp = *table; + + tmp.data = buf;mutex_lock (&nf_log_mutex); logger =nft_log_dereference (net->nf.nf_loggers[tindex]);if (!logger) - table->data ="NONE" ; +strlcpy (buf,"NONE" ,sizeof (buf));else - table->data = logger->name; - r =proc_dostring (table, write, buffer, lenp, ppos); +strlcpy (buf, logger->name,sizeof (buf));mutex_unlock (&nf_log_mutex); + r =proc_dostring (&tmp, write, buffer, lenp, ppos); }return r;
Greg Kroah-Hartman
maintainerPATCH 55/56 staging: comedi: quatech_daqp_cs: fix no-op loop daqp_ao_insn_write()
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 1376b0a2160319125c3a2822e8c09bd283cd8141 upstream.
There is a '>' vs '<' typo so this loop is a no-op.
--- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/comedi/drivers/quatech_daqp_cs.c +1 -1
@@ -642,7 +642,7 @@ static int daqp_ao_insn_write(struct com/* Make sure D/A update mode is direct update */ outb (0 , dev->iobase +DAQP_AUX_REG ); -for (i =0 ; i > insn->n; i++) { +for (i =0 ; i < insn->n; i++) {unsigned int val = data[i];int ret;
Greg Kroah-Hartman
maintainerPATCH 56/56 Revert mm/vmstat.c: fix vmstat_update() preemption BUG
In reply to Greg Kroah-Hartman4.17-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit 28557cc106e6d2aa8b8c5c7687ea9f8055ff3911 upstream.
Revert commit c7f26ccfb2c3 ("mm/vmstat.c: fix vmstat_update() preemption BUG"). Steven saw a "using smp_processor_id() in preemptible" message and added a preempt_disable() section around it to keep it quiet. This is not the right thing to do it does not fix the real problem.
vmstat_update() is invoked by a kworker on a specific CPU. This worker it bound to this CPU. The name of the worker was "kworker/1:1" so it should have been a worker which was bound to CPU1. A worker which can run on any CPU would have a `u' before the first digit.
smp_processor_id() can be used in a preempt-enabled region as long as the task is bound to a single CPU which is the case here. If it could run on an arbitrary CPU then this is the problem we have an should seek to resolve.
Not only this smp_processor_id() must not be migrated to another CPU but also refresh_cpu_vm_stats() which might access wrong per-CPU variables. Not to mention that other code relies on the fact that such a worker runs on one specific CPU only.
Therefore revert that commit and we should look instead what broke the affinity mask of the kworker.
--- mm/vmstat.c | 2 -- 1 file changed, 2 deletions(-)
mm/vmstat.c +0 -2
@@ -1844,11 +1844,9 @@ static void vmstat_update(struct work_st* to occur in the future. Keep on running the * update worker thread. */ -preempt_disable ();queue_delayed_work_on (smp_processor_id (), mm_percpu_wq,this_cpu_ptr (&vmstat_work),round_jiffies_relative (sysctl_stat_interval)); -preempt_enable (); } }
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.17.6-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.17.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm and x86_64.
Summary
------------------------------------------------------------------------
kernel: 4.17.6-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.17.y
git commit: f2ecef5f51032daf857ba27e7dbdb7d63917b025
git describe: v4.17.5-57-gf2ecef5f5103
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.17-oe/build/v4.17.5-57-gf2ecef5f5103
No regressions (compared to build v4.17.5-55-g20c391f52e00)
Ran 16496 total tests in the following environments and test suites.
Environments
--------------
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- juno-r2 - arm64
- qemu_arm
- qemu_arm64
- qemu_x86_64
- x15 - arm
- x86_64
Test Suites
-----------
* boot
* kselftest
* libhugetlbfs
* ltp-cap_bounds-tests
* ltp-containers-tests
* ltp-cve-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-timers-tests
* ltp-open-posix-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Greg Kroah-Hartman
maintainerQuoted 15 lines · Naresh Kamboju
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.17.6-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.17.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 3 lines
thanks,
greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm andx86_64.
Thanks for testing 4 of these and letting me know.
greg k-h
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
Build results:
total: 134 pass: 134 fail: 0 Qemu test results: total: 158 pass: 158 fail: 0
Details are available at http://kerneltests.org/builders/.
Guenter
Greg Kroah-Hartman
maintainerQuoted 10 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
Quoted 6 lines
Build results:
total: 134 pass: 134 fail: 0 Qemu test results: total: 158 pass: 158 fail: 0Details are available at http://kerneltests.org/builders/.
Wonderful, thanks for testing all of these and letting me know.
greg k-h
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.17.6-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.17.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Greg Kroah-Hartman
maintainerQuoted 15 lines · Shuah Khan
Quoted 14 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.17.6 release. There are 56 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 Thu Jul 12 18:24:40 UTC 2018. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.17.6-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-4.17.y
and the diffstat can be found below.
Quoted 6 lines
Quoted 4 lines
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Thanks for testing all of these and letting me know.
greg k-h