4.14.54-stable review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 4.14.54-stable review
This is the start of the stable review cycle for the 4.14.54 release. There are 61 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun Jul 8 05:46:58 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.14.54-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.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.14.54-rc1
Damien Thébault <[email protected]>
net: dsa: b53: Add BCM5389 support
Finn Thain <[email protected]>
net/sonic: Use dma_mapping_error()
João Paulo Rechi Vita <[email protected]>
platform/x86: asus-wmi: Fix NULL pointer dereference
Paul Burton <[email protected]>
sched/core: Require cpu_active() in select_task_rq(), for user tasks
Peter Zijlstra <[email protected]>
sched/core: Fix rules for running on online && !active CPUs
Darrick J. Wong <[email protected]>
fs: clear writeback errors in inode_init_always
YueHaibing <[email protected]>
perf bpf: Fix NULL return handling in bpf__prepare_load()
Thomas Richter <[email protected]>
perf test: "Session topology" dumps core on s390
Josh Hill <[email protected]>
net: qmi_wwan: Add Netgear Aircard 779S
Ivan Bornyakov <[email protected]>
atm: zatm: fix memcmp casting
Hao Wei Tee <[email protected]>
iwlwifi: pcie: compare with number of IRQs requested for, not number of CPUs
Julian Anastasov <[email protected]>
ipvs: fix buffer overflow with sync daemon and service
Pablo Neira Ayuso <[email protected]>
netfilter: nft_limit: fix packet ratelimiting
Sebastian Ott <[email protected]>
s390/dasd: use blk_mq_rq_from_pdu for per request data
Paolo Abeni <[email protected]>
netfilter: ebtables: handle string from userspace with care
David Howells <[email protected]>
afs: Fix directory permissions check
Eric Dumazet <[email protected]>
xfrm6: avoid potential infinite loop in _decode_session6()
Abhishek Sahu <[email protected]>
mtd: rawnand: fix return value check for bad block status
Sean Nyekjaer <[email protected]>
ARM: dts: imx6q: Use correct SDMA script for SPI5 core
Taehee Yoo <[email protected]>
netfilter: nf_tables: use WARN_ON_ONCE instead of BUG_ON in nft_do_chain()
Vincent Bernat <[email protected]>
netfilter: ip6t_rpfilter: provide input interface for route lookup
Florian Westphal <[email protected]>
netfilter: don't set F_IFACE on ipv6 fib lookups
NeilBrown <[email protected]>
md: remove special meaning of ->quiesce(.., 2)
NeilBrown <[email protected]>
md: allow metadata update while suspending.
NeilBrown <[email protected]>
md: use mddev_suspend/resume instead of ->quiesce()
NeilBrown <[email protected]>
md: move suspend_hi/lo handling into core md code
NeilBrown <[email protected]>
md: don't call bitmap_create() while array is quiesced.
NeilBrown <[email protected]>
md: always hold reconfig_mutex when calling mddev_suspend()
Taehee Yoo <[email protected]>
netfilter: nf_tables: fix NULL-ptr in nf_tables_dump_obj()
Florian Westphal <[email protected]>
netfilter: nf_tables: add missing netlink attrs to policies
Colin Ian King <[email protected]>
netfilter: nf_tables: fix memory leak on error exit return
Taehee Yoo <[email protected]>
netfilter: nf_tables: increase nft_counters_enabled in nft_chain_stats_replace()
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: disable preemption in nft_update_chain_stats()
Taehee Yoo <[email protected]>
netfilter: nft_meta: fix wrong value dereference in nft_meta_set_eval
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: bogus EBUSY in chain deletions
Florian Westphal <[email protected]>
netfilter: nf_tables: don't assume chain stats are set when jumplabel is set
Florian Westphal <[email protected]>
netfilter: nft_compat: fix handling of large matchinfo size
Florian Westphal <[email protected]>
netfilter: nft_compat: prepare for indirect info storage
Florian Westphal <[email protected]>
netfilter: nf_tables: nft_compat: fix refcount leak on xt module
Kenneth Graunke <[email protected]>
drm/i915: Enable provoking vertex fix on Gen9 systems.
Michel Dänzer <[email protected]>
drm/amdgpu: Refactor amdgpu_vram_mgr_bo_invisible_size helper
Michel Dänzer <[email protected]>
drm/amdgpu: Use kvmalloc_array for allocating VRAM manager nodes array
Stefan Agner <[email protected]>
drm/atmel-hlcdc: check stride values in the first plane
Jeremy Cline <[email protected]>
drm/qxl: Call qxl_bo_unref outside atomic context
Huang Rui <[email protected]>
drm/amdgpu: fix the missed vcn fw version report
Rex Zhu <[email protected]>
drm/amdgpu: Add APU support in vi_set_vce_clocks
Rex Zhu <[email protected]>
drm/amdgpu: Add APU support in vi_set_uvd_clocks
Alexander Potapenko <[email protected]>
vt: prevent leaking uninitialized data to userspace via /dev/vcs*
Johan Hovold <[email protected]>
serdev: fix memleak on module unload
Andy Shevchenko <[email protected]>
serial: 8250_pci: Remove stalled entries in blacklist
Laura Abbott <[email protected]>
staging: android: ion: Return an ERR_PTR in ion_map_kernel
Tetsuo Handa <[email protected]>
n_tty: Access echo_* variables carefully.
Tetsuo Handa <[email protected]>
n_tty: Fix stall at n_tty_receive_char_special().
Zhengjun Xing <[email protected]>
xhci: Fix kernel oops in trace_xhci_free_virt_device
Heikki Krogerus <[email protected]>
usb: typec: ucsi: Fix for incorrect status data issue
Heikki Krogerus <[email protected]>
usb: typec: ucsi: acpi: Workaround for cache mode issue
Heikki Krogerus <[email protected]>
acpi: Add helper for deactivating memory region
William Wu <[email protected]>
usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub
Karoly Pados <[email protected]>
USB: serial: cp210x: add Silicon Labs IDs for Windows Update
Johan Hovold <[email protected]>
USB: serial: cp210x: add CESINEL device ids
Houston Yaroschoff <[email protected]>
usb: cdc_acm: Add quirk for Uniden UBC125 scanner
-------------
Diffstat:
Documentation/devicetree/bindings/net/dsa/b53.txt | 1 + Makefile | 4 +- arch/arm/boot/dts/imx6q.dtsi | 2 +- drivers/acpi/osl.c | 72 ++++++++ drivers/atm/zatm.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 23 ++- drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/vi.c | 77 +++++++-- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +- drivers/gpu/drm/i915/i915_reg.h | 5 + drivers/gpu/drm/i915/intel_lrc.c | 12 +- drivers/gpu/drm/qxl/qxl_display.c | 7 +- drivers/md/dm-raid.c | 10 +- drivers/md/md-cluster.c | 6 +- drivers/md/md.c | 90 ++++++---- drivers/md/md.h | 15 +- drivers/md/raid0.c | 2 +- drivers/md/raid1.c | 27 +-- drivers/md/raid10.c | 10 +- drivers/md/raid5-cache.c | 30 ++-- drivers/md/raid5-log.h | 2 +- drivers/md/raid5.c | 40 +---- drivers/mtd/nand/nand_base.c | 2 +- drivers/net/dsa/b53/b53_common.c | 13 ++ drivers/net/dsa/b53/b53_mdio.c | 5 +- drivers/net/dsa/b53/b53_priv.h | 1 + drivers/net/ethernet/natsemi/sonic.c | 2 +- drivers/net/usb/qmi_wwan.c | 1 + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 10 +- drivers/platform/x86/asus-wmi.c | 23 +-- drivers/s390/block/dasd.c | 7 +- drivers/staging/android/ion/ion_heap.c | 2 +- drivers/tty/n_tty.c | 55 +++--- drivers/tty/serdev/core.c | 1 + drivers/tty/serial/8250/8250_pci.c | 2 - drivers/tty/vt/vt.c | 4 +- drivers/usb/class/cdc-acm.c | 3 + drivers/usb/dwc2/hcd_queue.c | 2 +- drivers/usb/host/xhci-mem.c | 4 +- drivers/usb/host/xhci-trace.h | 36 +++- drivers/usb/serial/cp210x.c | 14 ++ drivers/usb/typec/ucsi/ucsi.c | 13 ++ drivers/usb/typec/ucsi/ucsi_acpi.c | 5 + fs/afs/security.c | 10 +- fs/inode.c | 1 + include/linux/acpi.h | 3 + include/net/netfilter/nf_tables.h | 5 + kernel/sched/core.c | 45 +++-- net/bridge/netfilter/ebtables.c | 3 +- net/ipv6/netfilter/ip6t_rpfilter.c | 4 +- net/ipv6/netfilter/nft_fib_ipv6.c | 12 +- net/ipv6/xfrm6_policy.c | 2 +- net/netfilter/ipvs/ip_vs_ctl.c | 21 ++- net/netfilter/nf_tables_api.c | 61 ++++++- net/netfilter/nf_tables_core.c | 20 ++- net/netfilter/nft_compat.c | 201 +++++++++++++++++----- net/netfilter/nft_immediate.c | 15 +- net/netfilter/nft_limit.c | 38 ++-- net/netfilter/nft_meta.c | 14 +- tools/perf/tests/topology.c | 30 +++- tools/perf/util/bpf-loader.c | 6 +- 64 files changed, 809 insertions(+), 340 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/61 usb: cdc_acm: Add quirk for Uniden UBC125 scanner
4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Houston Yaroschoff <[email protected]>
commit 4a762569a2722b8a48066c7bacf0e1dc67d17fa1 upstream.
Uniden UBC125 radio scanner has USB interface which fails to work with cdc_acm driver:
usb 1-1.5: new full-speed USB device number 4 using xhci_hcd cdc_acm 1-1.5:1.0: Zero length descriptor references
cdc_acm: probe of 1-1.5:1.0 failed with error -22
Adding the NO_UNION_NORMAL quirk for the device fixes the issue:
usb 1-4: new full-speed USB device number 15 using xhci_hcd usb 1-4: New USB device found, idVendor=1965, idProduct=0018 usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-4: Product: UBC125XLT
usb 1-4: Manufacturer: Uniden Corp.
usb 1-4: SerialNumber: 0001
cdc_acm 1-4:1.0: ttyACM0: USB ACM device
lsusb -v of the device:
Bus 001 Device 015: ID 1965:0018 Uniden Corporation Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x1965 Uniden Corporation
idProduct 0x0018
bcdDevice 0.01
iManufacturer 1 Uniden Corp.
iProduct 2 UBC125XLT
iSerial 3 0001
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 48
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 0 None
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x87 EP 7 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)
--- drivers/usb/class/cdc-acm.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/class/cdc-acm.c +3 -0
@@ -1771,6 +1771,9 @@ static const struct usb_device_id acm_id { USB_DEVICE(0x11ca, 0x0201), /* VeriFone Mx870 Gadget Serial */ .driver_info =SINGLE_RX_URB , }, + { USB_DEVICE(0x1965, 0x0018), /* Uniden UBC125XLT */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ },
Greg Kroah-Hartman
maintainerPATCH 2/61 USB: serial: cp210x: add CESINEL device ids
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 24160628a34af962ac99f2f58e547ac3c4cbd26f upstream.
Add device ids for CESINEL products.
--- drivers/usb/serial/cp210x.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/usb/serial/cp210x.c +11 -0
@@ -98,6 +98,9 @@ static const struct usb_device_id id_tab { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ + { USB_DEVICE(0x10C4, 0x817C) }, /* CESINEL MEDCAL N Power Quality Monitor */ + { USB_DEVICE(0x10C4, 0x817D) }, /* CESINEL MEDCAL NT Power Quality Monitor */ + { USB_DEVICE(0x10C4, 0x817E) }, /* CESINEL MEDCAL S Power Quality Monitor */ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
@@ -115,6 +118,9 @@ static const struct usb_device_id id_tab { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */ + { USB_DEVICE(0x10C4, 0x82EF) }, /* CESINEL FALCO 6105 AC Power Supply */ + { USB_DEVICE(0x10C4, 0x82F1) }, /* CESINEL MEDCAL EFD Earth Fault Detector */ + { USB_DEVICE(0x10C4, 0x82F2) }, /* CESINEL MEDCAL ST Network Analyzer */ { USB_DEVICE(0x10C4, 0x82F4) }, /* Starizona MicroTouch */ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
@@ -127,7 +133,9 @@ static const struct usb_device_id id_tab { USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */ { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ { USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */ + { USB_DEVICE(0x10C4, 0x851E) }, /* CESINEL MEDCAL PT Network Analyzer */ { USB_DEVICE(0x10C4, 0x85A7) }, /* LifeScan OneTouch Verio IQ */ + { USB_DEVICE(0x10C4, 0x85B8) }, /* CESINEL ReCon T Energy Logger */ { USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */ { USB_DEVICE(0x10C4, 0x85EB) }, /* AC-Services CIS-IBUS */ { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */
@@ -137,10 +145,13 @@ static const struct usb_device_id id_tab { USB_DEVICE(0x10C4, 0x8857) }, /* CEL EM357 ZigBee USB Stick */ { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x88FB) }, /* CESINEL MEDCAL STII Network Analyzer */ + { USB_DEVICE(0x10C4, 0x8938) }, /* CESINEL MEDCAL S II Network Analyzer */ { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */ { USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */ { USB_DEVICE(0x10C4, 0x8977) }, /* CEL MeshWorks DevKit Device */ { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ + { USB_DEVICE(0x10C4, 0x89A4) }, /* CESINEL FTBC Flexible Thyristor Bridge Controller */ { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
Greg Kroah-Hartman
maintainerPATCH 3/61 USB: serial: cp210x: add Silicon Labs IDs for Windows Update
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karoly Pados <[email protected]>
commit 2f839823382748664b643daa73f41ee0cc01ced6 upstream.
Silicon Labs defines alternative VID/PID pairs for some chips that when used will automatically install drivers for Windows users without manual intervention. Unfortunately, these IDs are not recognized by the Linux module, so using these IDs improves user experience on one platform but degrades it on Linux. This patch addresses this problem.
--- drivers/usb/serial/cp210x.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/cp210x.c +3 -0
@@ -157,8 +157,11 @@ static const struct usb_device_id id_tab { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0xEA63) }, /* Silicon Labs Windows Update (CP2101-4/CP2102N) */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */ + { USB_DEVICE(0x10C4, 0xEA7A) }, /* Silicon Labs Windows Update (CP2105) */ + { USB_DEVICE(0x10C4, 0xEA7B) }, /* Silicon Labs Windows Update (CP2108) */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */ { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
Greg Kroah-Hartman
maintainerPATCH 4/61 usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Wu <[email protected]>
commit 8760675932ddb614e83702117d36ea644050c609 upstream.
The dwc2_get_ls_map() use ttport to reference into the bitmap if we're on a multi_tt hub. But the bitmaps index from 0 to (hub->maxchild - 1), while the ttport index from 1 to hub->maxchild. This will cause invalid memory access when the number of ttport is hub->maxchild.
Without this patch, I can easily meet a Kernel panic issue if connect a low-speed USB mouse with the max port of FE2.1 multi-tt hub (1a40:0201) on rk3288 platform.
--- drivers/usb/dwc2/hcd_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/dwc2/hcd_queue.c +1 -1
@@ -379,7 +379,7 @@ static unsigned long *dwc2_get_ls_map(st/* Get the map and adjust if this is a multi_tt hub */ map = qh->dwc_tt->periodic_bitmaps;if (qh->dwc_tt->usb_tt->multi) - map +=DWC2_ELEMENTS_PER_LS_BITMAP * qh->ttport; + map +=DWC2_ELEMENTS_PER_LS_BITMAP * (qh->ttport -1 );return map; }
Greg Kroah-Hartman
maintainerPATCH 5/61 acpi: Add helper for deactivating memory region
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <[email protected]>
commit d2d2e3c46be5d6dd8001d0eebdf7cafb9bc7006b upstream.
Sometimes memory resource may be overlapping with SystemMemory Operation Region by design, for example if the memory region is used as a mailbox for communication with a firmware in the system. One occasion of such mailboxes is USB Type-C Connector System Software Interface (UCSI).
With regions like that, it is important that the driver is able to map the memory with the requirements it has. For example, the driver should be allowed to map the memory as non-cached memory. However, if the operation region has been accessed before the driver has mapped the memory, the memory has been marked as write-back by the time the driver is loaded. That means the driver will fail to map the memory if it expects non-cached memory.
To work around the problem, introducing helper that the drivers can use to temporarily deactivate (unmap) SystemMemory Operation Regions that overlap with their IO memory.
--- drivers/acpi/osl.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 3 ++ 2 files changed, 75 insertions(+)
drivers/acpi/osl.c +72 -0
@@ -45,6 +45,8 @@#include <linux/uaccess.h> #include <linux/io-64-nonatomic-lo-hi.h> +#include "acpica/accommon.h" +#include "acpica/acnamesp.h" #include "internal.h" #define _COMPONENT ACPI_OS_SERVICES
@@ -1477,6 +1479,76 @@ int acpi_check_region(resource_size_t st }EXPORT_SYMBOL (acpi_check_region); +static acpi_status acpi_deactivate_mem_region (acpi_handle handle,u32 level, +void *_res,void **return_value) +{ +struct acpi_mem_space_context **mem_ctx; +union acpi_operand_object *handler_obj; +union acpi_operand_object *region_obj2; +union acpi_operand_object *region_obj; +struct resource *res = _res; +acpi_status status; + + region_obj =acpi_ns_get_attached_object (handle); +if (!region_obj) +return AE_OK ; + + handler_obj = region_obj->region.handler; +if (!handler_obj) +return AE_OK ; + +if (region_obj->region.space_id !=ACPI_ADR_SPACE_SYSTEM_MEMORY ) +return AE_OK ; + +if (!(region_obj->region.flags &AOPOBJ_SETUP_COMPLETE )) +return AE_OK ; + + region_obj2 =acpi_ns_get_secondary_object (region_obj); +if (!region_obj2) +return AE_OK ; + + mem_ctx = (void *)®ion_obj2->extra.region_context; + +if (!(mem_ctx[0 ]->address >= res->start && + mem_ctx[0 ]->address < res->end)) +return AE_OK ; + + status = handler_obj->address_space.setup (region_obj, +ACPI_REGION_DEACTIVATE , +NULL , (void **)mem_ctx); +if (ACPI_SUCCESS (status)) + region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE ); + +return status; +} + +/** +* acpi_release_memory - Release any mappings done to a memory region +* @handle: Handle to namespace node +* @res: Memory resource +* @level: A level that terminates the search +* +* Walks through @handle and unmaps all SystemMemory Operation Regions that +* overlap with @res and that have already been activated (mapped). +* +* This is a helper that allows drivers to place special requirements on memory +* region that may overlap with operation regions, primarily allowing them to +* safely map the region as non-cached memory. +* +* The unmapped Operation Regions will be automatically remapped next time they +* are called, so the drivers do not need to do anything else. +*/ +acpi_status acpi_release_memory (acpi_handle handle,struct resource *res, +u32 level) +{ +if (!(res->flags &IORESOURCE_MEM )) +return AE_TYPE ; + +return acpi_walk_namespace (ACPI_TYPE_REGION , handle, level, + acpi_deactivate_mem_region,NULL , res,NULL ); +} +EXPORT_SYMBOL_GPL (acpi_release_memory); +/* * Let drivers know whether the resource checks are effective */
include/linux/acpi.h +3 -0
@@ -441,6 +441,9 @@ int acpi_check_resource_conflict(const sint acpi_check_region (resource_size_t start,resource_size_t n,const char *name); +acpi_status acpi_release_memory (acpi_handle handle,struct resource *res, +u32 level); +int acpi_resources_are_enforced (void );#ifdef CONFIG_HIBERNATION
Greg Kroah-Hartman
maintainerPATCH 6/61 usb: typec: ucsi: acpi: Workaround for cache mode issue
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <[email protected]>
commit 1f9f9d168ce619608572b01771c47a41b15429e6 upstream.
This fixes an issue where the driver fails with an error:
ioremap error for 0x3f799000-0x3f79a000, requested 0x2, got 0x0
On some platforms the UCSI ACPI mailbox SystemMemory Operation Region may be setup before the driver has been loaded. That will lead into the driver failing to map the mailbox region, as it has been already marked as write-back memory. acpi_os_ioremap() for x86 uses ioremap_cache() unconditionally.
When the issue happens, the embedded controller has a pending query event for the UCSI notification right after boot-up which causes the operation region to be setup before UCSI driver has been loaded.
The fix is to notify acpi core that the driver is about to access memory region which potentially overlaps with an operation region right before mapping it. acpi_release_memory() will check if the memory has already been setup (mapped) by acpi core, and deactivate it (unmap) if it has. The driver is then able to map the memory with ioremap_nocache() and set the memtype to uncached for the region.
--- drivers/usb/typec/ucsi/ucsi_acpi.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/usb/typec/ucsi/ucsi_acpi.c +5 -0
@@ -82,6 +82,11 @@ static int ucsi_acpi_probe(struct platforeturn -ENODEV ; } +/* This will make sure we can use ioremap_nocache() */ + status =acpi_release_memory (ACPI_HANDLE (&pdev->dev), res,1 ); +if (ACPI_FAILURE (status)) +return -ENOMEM ; +/* * NOTE: The memory region for the data structures is used also in an * operation region, which means ACPI has already reserved it. Therefore
Greg Kroah-Hartman
maintainerPATCH 7/61 usb: typec: ucsi: Fix for incorrect status data issue
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <[email protected]>
commit 68816e16b4789f2d05e77b6dcb77564cf5d6a8d8 upstream.
According to UCSI Specification, Connector Change Event only means a change in the Connector Status and Operation Mode fields of the STATUS data structure. So any other change should create another event.
Unfortunately on some platforms the firmware acting as PPM (platform policy manager - usually embedded controller firmware) still does not report any other status changes if there is a connector change event. So if the connector power or data role was changed when a device was plugged to the connector, the driver does not get any indication about that. The port will show wrong roles if that happens.
To fix the issue, always checking the data and power role together with a connector change event.
--- drivers/usb/typec/ucsi/ucsi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/usb/typec/ucsi/ucsi.c +13 -0
@@ -346,6 +346,19 @@ static void ucsi_connector_change(struct }if (con->status.change &UCSI_CONSTAT_CONNECT_CHANGE ) { +typec_set_pwr_role (con->port, con->status.pwr_dir); + +switch (con->status.partner_type) { +case UCSI_CONSTAT_PARTNER_TYPE_UFP : +typec_set_data_role (con->port,TYPEC_HOST ); +break ; +case UCSI_CONSTAT_PARTNER_TYPE_DFP : +typec_set_data_role (con->port,TYPEC_DEVICE ); +break ; +default : +break ; + } +if (con->status.connected)ucsi_register_partner (con);else
Greg Kroah-Hartman
maintainerPATCH 8/61 xhci: Fix kernel oops in trace_xhci_free_virt_device
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhengjun Xing <[email protected]>
commit d850c1658328e757635a46763783c6fd56390dcb upstream.
commit 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device") set dev->udev pointer to NULL in xhci_free_dev(), it will cause kernel panic in trace_xhci_free_virt_device. This patch reimplement the trace function trace_xhci_free_virt_device, remove dev->udev dereference and added more useful parameters to show in the trace function,it also makes sure dev->udev is not NULL before calling trace_xhci_free_virt_device. This issue happened when xhci-hcd trace is enabled and USB devices hot plug test. Original use-after-free patch went to stable so this needs so be applied there as well.
[ 1092.022457] usb 2-4: USB disconnect, device number 6 [ 1092.092772] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 [ 1092.101694] PGD 0 P4D 0 [ 1092.104601] Oops: 0000 [#1] SMP [ 1092.207734] Workqueue: usb_hub_wq hub_event [ 1092.212507] RIP: 0010:trace_event_raw_event_xhci_log_virt_dev+0x6c/0xf0 [ 1092.220050] RSP: 0018:ffff8c252e883d28 EFLAGS: 00010086 [ 1092.226024] RAX: ffff8c24af86fa84 RBX: 0000000000000003 RCX: ffff8c25255c2a01 [ 1092.234130] RDX: 0000000000000000 RSI: 00000000aef55009 RDI: ffff8c252e883d28 [ 1092.242242] RBP: ffff8c252550e2c0 R08: ffff8c24af86fa84 R09: 0000000000000a70 [ 1092.250364] R10: 0000000000000a70 R11: 0000000000000000 R12: ffff8c251f21a000 [ 1092.258468] R13: 000000000000000c R14: ffff8c251f21a000 R15: ffff8c251f432f60 [ 1092.266572] FS: 0000000000000000(0000) GS:ffff8c252e880000(0000) knlGS:0000000000000000 [ 1092.275757] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1092.282281] CR2: 0000000000000000 CR3: 0000000154209001 CR4: 00000000003606e0 [ 1092.290384] Call Trace: [ 1092.293156] <IRQ> [ 1092.295439] xhci_free_virt_device.part.34+0x182/0x1a0 [ 1092.301288] handle_cmd_completion+0x7ac/0xfa0 [ 1092.306336] ? trace_event_raw_event_xhci_log_trb+0x6e/0xa0 [ 1092.312661] xhci_irq+0x3e8/0x1f60 [ 1092.316524] __handle_irq_event_percpu+0x75/0x180 [ 1092.321876] handle_irq_event_percpu+0x20/0x50 [ 1092.326922] handle_irq_event+0x36/0x60 [ 1092.331273] handle_edge_irq+0x6d/0x180 [ 1092.335644] handle_irq+0x16/0x20 [ 1092.339417] do_IRQ+0x41/0xc0 [ 1092.342782] common_interrupt+0xf/0xf [ 1092.346955] </IRQ>
--- drivers/usb/host/xhci-mem.c | 4 ++-- drivers/usb/host/xhci-trace.h | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-)
drivers/usb/host/xhci-mem.c +2 -2
@@ -891,12 +891,12 @@ void xhci_free_virt_device(struct xhci_h dev = xhci->devs[slot_id]; -trace_xhci_free_virt_device (dev); - xhci->dcbaa->dev_context_ptrs[slot_id] =0 ;if (!dev)return ; +trace_xhci_free_virt_device (dev); +if (dev->tt_info) old_active_eps = dev->tt_info->active_eps;
drivers/usb/host/xhci-trace.h +31 -5
@@ -158,6 +158,37 @@ DEFINE_EVENT(xhci_log_trb, xhci_queue_trTP_ARGS (ring, trb) ); +DECLARE_EVENT_CLASS (xhci_log_free_virt_dev, + TP_PROTO(struct xhci_virt_device *vdev), +TP_ARGS (vdev), +TP_STRUCT__entry ( + __field(void *, vdev) + __field(unsigned long long, out_ctx) + __field(unsigned long long, in_ctx) + __field(u8, fake_port) + __field(u8, real_port) +__field (u16, current_mel) + + ), +TP_fast_assign ( + __entry->vdev = vdev; + __entry->in_ctx = (unsigned long long) vdev->in_ctx->dma; + __entry->out_ctx = (unsigned long long) vdev->out_ctx->dma; + __entry->fake_port = (u8) vdev->fake_port; + __entry->real_port = (u8) vdev->real_port; + __entry->current_mel = (u16) vdev->current_mel; + ), +TP_printk ("vdev %p ctx %llx | %llx fake_port %d real_port %d current_mel %d" , + __entry->vdev, __entry->in_ctx, __entry->out_ctx, + __entry->fake_port, __entry->real_port, __entry->current_mel + ) +); + +DEFINE_EVENT (xhci_log_free_virt_dev, xhci_free_virt_device, + TP_PROTO(struct xhci_virt_device *vdev), +TP_ARGS (vdev) +); + DECLARE_EVENT_CLASS(xhci_log_virt_dev, TP_PROTO(struct xhci_virt_device *vdev), TP_ARGS(vdev),
@@ -194,11 +225,6 @@ DEFINE_EVENT(xhci_log_virt_dev, xhci_all TP_PROTO(struct xhci_virt_device *vdev), TP_ARGS(vdev) ); - -DEFINE_EVENT (xhci_log_virt_dev, xhci_free_virt_device, - TP_PROTO(struct xhci_virt_device *vdev), -TP_ARGS (vdev) -); DEFINE_EVENT(xhci_log_virt_dev, xhci_setup_device, TP_PROTO(struct xhci_virt_device *vdev),
Greg Kroah-Hartman
maintainerPATCH 9/61 n_tty: Fix stall at n_tty_receive_char_special().
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
commit 3d63b7e4ae0dc5e02d28ddd2fa1f945defc68d81 upstream.
syzbot is reporting stalls at n_tty_receive_char_special() [1]. This is because comparison is not working as expected since ldata->read_head can change at any moment. Mitigate this by explicitly masking with buffer size when checking condition for "while" loops.
[1] https://syzkaller.appspot.com/bug?id=3d7481a346958d9469bebbeb0537d5f056bdd6e8
--- drivers/tty/n_tty.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/tty/n_tty.c +8 -5
@@ -126,6 +126,8 @@ struct n_tty_data {struct mutex output_lock; }; +#define MASK (x) ((x) & (N_TTY_BUF_SIZE - 1)) +static inline size_t read_cnt (struct n_tty_data *ldata) {return ldata->read_head - ldata->read_tail;
@@ -980,14 +982,15 @@ static void eraser(unsigned char c, stru } seen_alnums =0 ; -while (ldata->read_head != ldata->canon_head) { +while (MASK (ldata->read_head) !=MASK (ldata->canon_head)) { head = ldata->read_head;/* erase a single possibly multibyte character */ do { head--; c =read_buf (ldata, head); - }while (is_continuation (c, tty) && head != ldata->canon_head); + }while (is_continuation (c, tty) && +MASK (head) !=MASK (ldata->canon_head));/* do not partially erase */ if (is_continuation (c, tty))
@@ -1029,7 +1032,7 @@ static void eraser(unsigned char c, stru* This info is used to go back the correct * number of columns. */ -while (tail != ldata->canon_head) { +while (MASK (tail) !=MASK (ldata->canon_head)) { tail--; c =read_buf (ldata, tail);if (c =='\t' ) {
@@ -1304,7 +1307,7 @@ n_tty_receive_char_special(struct tty_stfinish_erasing (ldata);echo_char (c, tty);echo_char_raw ('\n' , ldata); -while (tail != ldata->read_head) { +while (MASK (tail) !=MASK (ldata->read_head)) {echo_char (read_buf (ldata, tail), tty); tail++; }
@@ -2413,7 +2416,7 @@ static unsigned long inq_canon(struct n_ tail = ldata->read_tail; nr = head - tail;/* Skip EOF-chars.. */ -while (head != tail) { +while (MASK (head) !=MASK (tail)) {if (test_bit (tail & (N_TTY_BUF_SIZE -1 ), ldata->read_flags) &&read_buf (ldata, tail) == __DISABLED_CHAR) nr--;
Greg Kroah-Hartman
maintainerPATCH 10/61 n_tty: Access echo_* variables carefully.
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <[email protected]>
commit ebec3f8f5271139df618ebdf8427e24ba102ba94 upstream.
syzbot is reporting stalls at __process_echoes() [1]. This is because since ldata->echo_commit < ldata->echo_tail becomes true for some reason, the discard loop is serving as almost infinite loop. This patch tries to avoid falling into ldata->echo_commit < ldata->echo_tail situation by making access to echo_* variables more carefully.
Since reset_buffer_flags() is called without output_lock held, it should not touch echo_* variables. And omit a call to reset_buffer_flags() from n_tty_open() by using vzalloc().
Since add_echo_byte() is called without output_lock held, it needs memory barrier between storing into echo_buf[] and incrementing echo_head counter. echo_buf() needs corresponding memory barrier before reading echo_buf[]. Lack of handling the possibility of not-yet-stored multi-byte operation might be the reason of falling into ldata->echo_commit < ldata->echo_tail situation, for if I do WARN_ON(ldata->echo_commit == tail + 1) prior to echo_buf(ldata, tail + 1), the WARN_ON() fires.
Also, explicitly masking with buffer for the former "while" loop, and use ldata->echo_commit > tail for the latter "while" loop.
[1] https://syzkaller.appspot.com/bug?id=17f23b094cd80df750e5b0f8982c521ee6bcbf40
--- drivers/tty/n_tty.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-)
drivers/tty/n_tty.c +24 -18
@@ -145,6 +145,7 @@ static inline unsigned char *read_buf_adstatic inline unsigned char echo_buf (struct n_tty_data *ldata,size_t i) { +smp_rmb ();/* Matches smp_wmb() in add_echo_byte(). */ return ldata->echo_buf[i & (N_TTY_BUF_SIZE -1 )]; }
@@ -320,9 +321,7 @@ static inline void put_tty_queue(unsignestatic void reset_buffer_flags (struct n_tty_data *ldata) { ldata->read_head = ldata->canon_head = ldata->read_tail =0 ; - ldata->echo_head = ldata->echo_tail = ldata->echo_commit =0 ; ldata->commit_head =0 ; - ldata->echo_mark =0 ; ldata->line_start =0 ; ldata->erasing =0 ;
@@ -621,13 +620,20 @@ static size_t __process_echoes(struct tt old_space = space =tty_write_room (tty); tail = ldata->echo_tail; -while (ldata->echo_commit != tail) { +while (MASK (ldata->echo_commit) !=MASK (tail)) { c =echo_buf (ldata, tail);if (c ==ECHO_OP_START ) {unsigned char op;int no_space_left =0 ;/* +* Since add_echo_byte() is called without holding +* output_lock, we might see only portion of multi-byte +* operation. +*/ +if (MASK (ldata->echo_commit) ==MASK (tail +1 )) + goto not_yet_stored; +/* * If the buffer byte is the start of a multi-byte * operation, get the next byte, which is either the * op code or a control character value.
@@ -638,6 +644,8 @@ static size_t __process_echoes(struct ttunsigned int num_chars, num_bs;case ECHO_OP_ERASE_TAB : +if (MASK (ldata->echo_commit) ==MASK (tail +2 )) + goto not_yet_stored; num_chars =echo_buf (ldata, tail +2 );/*
@@ -732,7 +740,8 @@ static size_t __process_echoes(struct tt/* If the echo buffer is nearly full (so that the possibility exists * of echo overrun before the next commit), then discard enough * data at the tail to prevent a subsequent overrun */ -while (ldata->echo_commit - tail >=ECHO_DISCARD_WATERMARK ) { +while (ldata->echo_commit > tail && + ldata->echo_commit - tail >=ECHO_DISCARD_WATERMARK ) {if (echo_buf (ldata, tail) ==ECHO_OP_START ) {if (echo_buf (ldata, tail +1 ) ==ECHO_OP_ERASE_TAB ) tail +=3 ;
@@ -742,6 +751,7 @@ static size_t __process_echoes(struct tt tail++; } + not_yet_stored: ldata->echo_tail = tail;return old_space - space; }
@@ -752,6 +762,7 @@ static void commit_echoes(struct tty_strsize_t nr, old, echoed;size_t head; +mutex_lock (&ldata->output_lock); head = ldata->echo_head; ldata->echo_mark = head; old = ldata->echo_commit - ldata->echo_tail;
@@ -760,10 +771,12 @@ static void commit_echoes(struct tty_str* is over the threshold (and try again each time another * block is accumulated) */ nr = head - ldata->echo_tail; -if (nr <ECHO_COMMIT_WATERMARK || (nr %ECHO_BLOCK > old %ECHO_BLOCK )) +if (nr <ECHO_COMMIT_WATERMARK || + (nr %ECHO_BLOCK > old %ECHO_BLOCK )) { +mutex_unlock (&ldata->output_lock);return ; + } -mutex_lock (&ldata->output_lock); ldata->echo_commit = head; echoed =__process_echoes (tty);mutex_unlock (&ldata->output_lock);
@@ -814,7 +827,9 @@ static void flush_echoes(struct tty_strustatic inline void add_echo_byte (unsigned char c,struct n_tty_data *ldata) { - *echo_buf_addr (ldata, ldata->echo_head++) = c; + *echo_buf_addr (ldata, ldata->echo_head) = c; +smp_wmb ();/* Matches smp_rmb() in echo_buf(). */ + ldata->echo_head++; }/**
@@ -1883,30 +1898,21 @@ static int n_tty_open(struct tty_structstruct n_tty_data *ldata;/* Currently a malloc failure here can panic */ - ldata =vmalloc (sizeof (*ldata)); + ldata =vzalloc (sizeof (*ldata));if (!ldata) - goto err; +return -ENOMEM ; ldata->overrun_time = jiffies;mutex_init (&ldata->atomic_read_lock);mutex_init (&ldata->output_lock); tty->disc_data = ldata; -reset_buffer_flags (tty->disc_data); - ldata->column =0 ; - ldata->canon_column =0 ; - ldata->num_overrun =0 ; - ldata->no_room =0 ; - ldata->lnext =0 ; tty->closing =0 ;/* indicate buffer work may resume */ clear_bit (TTY_LDISC_HALTED , &tty->flags);n_tty_set_termios (tty,NULL );tty_unthrottle (tty); -return 0 ; -err: -return -ENOMEM ; }static inline int input_available_p (struct tty_struct *tty,int poll)
Greg Kroah-Hartman
maintainerPATCH 11/61 staging: android: ion: Return an ERR_PTR in ion_map_kernel
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laura Abbott <[email protected]>
commit 0a2bc00341dcfcc793c0dbf4f8d43adf60458b05 upstream.
The expected return value from ion_map_kernel is an ERR_PTR. The error path for a vmalloc failure currently just returns NULL, triggering a warning in ion_buffer_kmap_get. Encode the vmalloc failure as an ERR_PTR.
--- drivers/staging/android/ion/ion_heap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/android/ion/ion_heap.c +1 -1
@@ -38,7 +38,7 @@ void *ion_heap_map_kernel(struct ion_heastruct page **tmp = pages;if (!pages) -return NULL ; +return ERR_PTR (-ENOMEM );if (buffer->flags &ION_FLAG_CACHED ) pgprot =PAGE_KERNEL ;
Greg Kroah-Hartman
maintainerPATCH 12/61 serial: 8250_pci: Remove stalled entries in blacklist
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
commit 20dcff436e9fcd2e106b0ccc48a52206bc176d70 upstream.
After the commit
7d8905d06405 ("serial: 8250_pci: Enable device after we check black list")
pure serial multi-port cards, such as CH355, got blacklisted and thus not being enumerated anymore. Previously, it seems, blacklisting them was on purpose to shut up pciserial_init_one() about record duplication.
So, remove the entries from blacklist in order to get cards enumerated.
--- drivers/tty/serial/8250/8250_pci.c | 2 -- 1 file changed, 2 deletions(-)
drivers/tty/serial/8250/8250_pci.c +0 -2
@@ -3345,9 +3345,7 @@ static const struct pci_device_id blackl/* multi-io cards handled by parport_serial */ { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */ - { PCI_DEVICE(0x4348, 0x7173), }, /* WCH CH355 4S */ { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */ - { PCI_DEVICE(0x1c00, 0x3470), }, /* WCH CH384 4S */ /* Moxa Smartio MUE boards handled by 8250_moxa */ { PCI_VDEVICE(MOXA, 0x1024), },
Greg Kroah-Hartman
maintainerPATCH 13/61 serdev: fix memleak on module unload
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit bc6cf3669d22371f573ab0305b3abf13887c0786 upstream.
Make sure to free all resources associated with the ida on module exit.
--- drivers/tty/serdev/core.c | 1 + 1 file changed, 1 insertion(+)
drivers/tty/serdev/core.c +1 -0
@@ -482,6 +482,7 @@ EXPORT_SYMBOL_GPL(__serdev_device_driver static void __exit serdev_exit(void) {bus_unregister (&serdev_bus_type); +ida_destroy (&ctrl_ida); }module_exit (serdev_exit);
Greg Kroah-Hartman
maintainerPATCH 14/61 vt: prevent leaking uninitialized data to userspace via /dev/vcs*
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Potapenko <[email protected]>
commit 21eff69aaaa0e766ca0ce445b477698dc6a9f55a upstream.
KMSAN reported an infoleak when reading from /dev/vcs*:
BUG: KMSAN: kernel-infoleak in vcs_read+0x18ba/0x1cc0 Call Trace: ... kmsan_copy_to_user+0x7a/0x160 mm/kmsan/kmsan.c:1253 copy_to_user ./include/linux/uaccess.h:184 vcs_read+0x18ba/0x1cc0 drivers/tty/vt/vc_screen.c:352 __vfs_read+0x1b2/0x9d0 fs/read_write.c:416 vfs_read+0x36c/0x6b0 fs/read_write.c:452 ... Uninit was created at: kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:189 kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:315 __kmalloc+0x13a/0x350 mm/slub.c:3818 kmalloc ./include/linux/slab.h:517 vc_allocate+0x438/0x800 drivers/tty/vt/vt.c:787 con_install+0x8c/0x640 drivers/tty/vt/vt.c:2880 tty_driver_install_tty drivers/tty/tty_io.c:1224 tty_init_dev+0x1b5/0x1020 drivers/tty/tty_io.c:1324 tty_open_by_driver drivers/tty/tty_io.c:1959 tty_open+0x17b4/0x2ed0 drivers/tty/tty_io.c:2007 chrdev_open+0xc25/0xd90 fs/char_dev.c:417 do_dentry_open+0xccc/0x1440 fs/open.c:794 vfs_open+0x1b6/0x2f0 fs/open.c:908 ... Bytes 0-79 of 240 are uninitialized
Consistently allocating |vc_screenbuf| with kzalloc() fixes the problem
--- drivers/tty/vt/vt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/vt/vt.c +2 -2
@@ -782,7 +782,7 @@ int vc_allocate(unsigned int currcons) /if (!*vc->vc_uni_pagedir_loc)con_set_default_unimap (vc); - vc->vc_screenbuf =kmalloc (vc->vc_screenbuf_size,GFP_KERNEL ); + vc->vc_screenbuf =kzalloc (vc->vc_screenbuf_size,GFP_KERNEL );if (!vc->vc_screenbuf) goto err_free;
@@ -869,7 +869,7 @@ static int vc_do_resize(struct tty_strucif (new_screen_size > (4 <<20 ))return -EINVAL ; - newscreen =kmalloc (new_screen_size,GFP_USER ); + newscreen =kzalloc (new_screen_size,GFP_USER );if (!newscreen)return -ENOMEM ;
syzbot
syzbotRe: [PATCH 4.14 14/61] vt: prevent leaking uninitialized data to userspace via /dev/vcs*
Can't find the corresponding bug.
Quoted 60 lines
4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Potapenko <[email protected]>
commit
21eff69aaaa0e766ca0ce445b477698dc6a9f55aupstream.KMSAN reported an infoleak when reading from
/dev/vcs*:BUG: KMSAN: kernel-infoleak in vcs_read+0x18ba/0x1cc0 Call Trace: ... kmsan_copy_to_user+0x7a/0x160 mm/kmsan/kmsan.c:1253 copy_to_user ./include/linux/uaccess.h:184 vcs_read+0x18ba/0x1cc0 drivers/tty/vt/vc_screen.c:352 __vfs_read+0x1b2/0x9d0 fs/read_write.c:416 vfs_read+0x36c/0x6b0 fs/read_write.c:452 ... Uninit was created at: kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:189 kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:315 __kmalloc+0x13a/0x350 mm/slub.c:3818 kmalloc ./include/linux/slab.h:517 vc_allocate+0x438/0x800 drivers/tty/vt/vt.c:787 con_install+0x8c/0x640 drivers/tty/vt/vt.c:2880 tty_driver_install_tty drivers/tty/tty_io.c:1224 tty_init_dev+0x1b5/0x1020 drivers/tty/tty_io.c:1324 tty_open_by_driver drivers/tty/tty_io.c:1959 tty_open+0x17b4/0x2ed0 drivers/tty/tty_io.c:2007 chrdev_open+0xc25/0xd90 fs/char_dev.c:417 do_dentry_open+0xccc/0x1440 fs/open.c:794 vfs_open+0x1b6/0x2f0 fs/open.c:908 ... Bytes 0-79 of 240 are uninitializedConsistently allocating |vc_screenbuf| with
kzalloc()fixes the problemReported-by [email protected]Signed-off-by Alexander Potapenko <[email protected]>Cc stable <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/tty/vt/vt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/tty/vt/vt.c +1
-1@@ -782,7 +782,7 @@ int vc_allocate(unsigned int currcons) /if (!*vc->vc_uni_pagedir_loc)con_set_default_unimap (vc); - vc->vc_screenbuf =kmalloc (vc->vc_screenbuf_size,GFP_KERNEL ); + vc->vc_screenbuf =kzalloc (vc->vc_screenbuf_size,GFP_KERNEL );if (!vc->vc_screenbuf) goto err_free;
drivers/tty/vt/vt.c static int vc_do_resize(struct tty_struc · line 874
Quoted 7 lines
drivers/tty/vt/vt.c +1
-1@@ -869,7 +869,7 @@ static int vc_do_resize(struct tty_strucif (new_screen_size > (4 <<20 ))return -EINVAL ; - newscreen =kmalloc (new_screen_size,GFP_USER ); + newscreen =kzalloc (new_screen_size,GFP_USER );if (!newscreen)return -ENOMEM ;
Can't find the corresponding bug.
Greg Kroah-Hartman
maintainerPATCH 18/61 drm/qxl: Call qxl_bo_unref outside atomic context
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeremy Cline <[email protected]>
commit 889ad63d41eea20184b0483e7e585e5b20fb6cfe upstream.
"qxl_bo_unref" may sleep, but calling "qxl_release_map" causes "preempt_disable()" to be called and "preempt_enable()" isn't called until "qxl_release_unmap" is used. Move the call to "qxl_bo_unref" out from in between the two to avoid sleeping from an atomic context.
This issue can be demonstrated on a kernel with CONFIG_LOCKDEP=y by creating a VM using QXL, using a desktop environment using Xorg, then moving the cursor on or off a window.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1571128
--- drivers/gpu/drm/qxl/qxl_display.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/gpu/drm/qxl/qxl_display.c +5 -2
@@ -630,7 +630,7 @@ static void qxl_cursor_atomic_update(strstruct qxl_cursor_cmd *cmd;struct qxl_cursor *cursor;struct drm_gem_object *obj; -struct qxl_bo *cursor_bo =NULL , *user_bo =NULL ; +struct qxl_bo *cursor_bo =NULL , *user_bo =NULL , *old_cursor_bo =NULL ;int ret;void *user_ptr;int size =64 *64 *4 ;
@@ -684,7 +684,7 @@ static void qxl_cursor_atomic_update(str cursor_bo, 0); cmd->type =QXL_CURSOR_SET ; -qxl_bo_unref (&qcrtc->cursor_bo); + old_cursor_bo = qcrtc->cursor_bo; qcrtc->cursor_bo = cursor_bo; cursor_bo =NULL ; }else {
@@ -704,6 +704,9 @@ static void qxl_cursor_atomic_update(strqxl_push_cursor_ring_release (qdev, release,QXL_CMD_CURSOR , false);qxl_release_fence_buffer_objects (release); +if (old_cursor_bo) +qxl_bo_unref (&old_cursor_bo); +qxl_bo_unref (&cursor_bo);return ;
Greg Kroah-Hartman
maintainerPATCH 19/61 drm/atmel-hlcdc: check stride values in the first plane
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Agner <[email protected]>
commit 9fcf2b3c1c0276650fea537c71b513d27d929b05 upstream.
The statement always evaluates to true since the struct fields are arrays. This has shown up as a warning when compiling with clang:
warning: address of array 'desc->layout.xstride' will always
evaluate to 'true' [-Wpointer-bool-conversion]
Check for values in the first plane instead.
--- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +1 -1
@@ -889,7 +889,7 @@ static int atmel_hlcdc_plane_init_properdrm_object_attach_property (&plane->base.base, props->alpha,255 ); -if (desc->layout.xstride && desc->layout.pstride) { +if (desc->layout.xstride[0 ] && desc->layout.pstride[0 ]) {int ret; ret = drm_plane_create_rotation_property(&plane->base,
Greg Kroah-Hartman
maintainerPATCH 22/61 drm/i915: Enable provoking vertex fix on Gen9 systems.
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kenneth Graunke <[email protected]>
commit 7a3727f385dc64773db1c144f6b15c1e9d4735bb upstream.
The SF and clipper units mishandle the provoking vertex in some cases, which can cause misrendering with shaders that use flat shaded inputs.
There are chicken bits in 3D_CHICKEN3 (for SF) and FF_SLICE_CHICKEN (for the clipper) that work around the issue. These registers are unfortunately not part of the logical context (even the power context), and so we must reload them every time we start executing in a context.
Bugzilla: https://bugs.freedesktop.org/103047
--- drivers/gpu/drm/i915/i915_reg.h | 5 +++++ drivers/gpu/drm/i915/intel_lrc.c | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/i915_reg.h +5 -0
@@ -2484,12 +2484,17 @@ enum i915_power_well_id {#define _3D_CHICKEN _MMIO(0x2084)#define _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB (1 << 10)#define _3D_CHICKEN2 _MMIO(0x208c) + +#define FF_SLICE_CHICKEN _MMIO(0x2088) +#define FF_SLICE_CHICKEN_CL_PROVOKING_VERTEX_FIX (1 << 1) +/* Disables pipelining of read flushes past the SF-WIZ interface. * Required on all Ironlake steppings according to the B-Spec, but the * particular danger of not doing so is not specified. */ # define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14)#define _3D_CHICKEN3 _MMIO(0x2090) +#define _3D_CHICKEN_SF_PROVOKING_VERTEX_FIX (1 << 12)#define _3D_CHICKEN_SF_DISABLE_OBJEND_CULL (1 << 10)#define _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL (1 << 5)#define _3D_CHICKEN_SDE_LIMIT_FIFO_POLY_DEPTH (x) ((x)<<1)/* gen8+ */
drivers/gpu/drm/i915/intel_lrc.c +11 -1
@@ -1067,11 +1067,21 @@ static u32 *gen9_init_indirectctx_bb(str/* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */ batch =gen8_emit_flush_coherentl3_wa (engine, batch); + *batch++ =MI_LOAD_REGISTER_IMM (3 ); +/* WaDisableGatherAtSetShaderCommonSlice:skl,bxt,kbl,glk */ - *batch++ =MI_LOAD_REGISTER_IMM (1 ); *batch++ =i915_mmio_reg_offset (COMMON_SLICE_CHICKEN2 ); *batch++ =_MASKED_BIT_DISABLE (GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE ); + +/* BSpec: 11391 */ + *batch++ =i915_mmio_reg_offset (FF_SLICE_CHICKEN ); + *batch++ =_MASKED_BIT_ENABLE (FF_SLICE_CHICKEN_CL_PROVOKING_VERTEX_FIX ); + +/* BSpec: 11299 */ + *batch++ =i915_mmio_reg_offset (_3D_CHICKEN3); + *batch++ =_MASKED_BIT_ENABLE (_3D_CHICKEN_SF_PROVOKING_VERTEX_FIX); + *batch++ =MI_NOOP ;/* WaClearSlmSpaceAtContextSwitch:kbl */
Greg Kroah-Hartman
maintainerPATCH 23/61 netfilter: nf_tables: nft_compat: fix refcount leak on xt module
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit b8e9dc1c75714ceb53615743e1036f76e00f5a17 upstream.
Taehee Yoo reported following bug:
iptables-compat -I OUTPUT -m cpu --cpu 0
iptables-compat -F
lsmod |grep xt_cpu
xt_cpu 16384 1
Quote:
"When above command is given, a netlink message has two expressions that are the cpu compat and the nft_counter.
The nft_expr_type_get() in the nf_tables_expr_parse() successes first expression then, calls select_ops callback.
(allocates memory and holds module)
But, second nft_expr_type_get() in the nf_tables_expr_parse() returns -EAGAIN because of request_module().
In that point, by the 'goto err1',
the 'module_put(info[i].ops->type->owner)' is called.
There is no release routine."
The core problem is that unlike all other expression, nft_compat select_ops has side effects.
1. it allocates dynamic memory which holds an nft ops struct. In all other expressions, ops has static storage duration.
2. It grabs references to the xt module that it is supposed to invoke.
Depending on where things go wrong, error unwinding doesn't always do the right thing.
In the above scenario, a new nft_compat_expr is created and xt_cpu module gets loaded with a refcount of 1.
Due to to -EAGAIN, the netlink messages get re-parsed. When that happens, nft_compat finds that xt_cpu is already present and increments module refcount again.
This fixes the problem by making select_ops to have no visible side effects and removes all extra module_get/put.
When select_ops creates a new nft_compat expression, the new expression has a refcount of 0, and the xt module gets its refcount incremented.
When error happens, the next call finds existing entry, but will no longer increase the reference count -- the presence of existing nft_xt means we already hold a module reference.
Because nft_xt_put is only called from nft_compat destroy hook, it will never see the initial zero reference count. ->destroy can only be called after ->init(), and that will increase the refcount.
Lastly, we now free nft_xt struct with kfree_rcu. Else, we get use-after free in nf_tables_rule_destroy:
while (expr != nft_expr_last(rule) && expr->ops) {
nf_tables_expr_destroy(ctx, expr);
expr = nft_expr_next(expr); // herenft_expr_next() dereferences expr->ops. This is safe for all users, as ops have static storage duration. In nft_compat case however, its ->destroy callback can free the memory that hold the ops structure.
--- net/netfilter/nft_compat.c | 92 ++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 34 deletions(-)
net/netfilter/nft_compat.c +58 -34
@@ -27,14 +27,24 @@ struct nft_xt {struct list_head head;struct nft_expr_ops ops;unsigned int refcnt; + +/* Unlike other expressions, ops doesn't have static storage duration. +* nft core assumes they do. We use kfree_rcu so that nft core can +* can check expr->ops->size even after nft_compat->destroy() frees +* the nft_xt struct that holds the ops structure. +*/ +struct rcu_head rcu_head; }; -static void nft_xt_put (struct nft_xt *xt) +static bool nft_xt_put (struct nft_xt *xt) {if (--xt->refcnt ==0 ) {list_del (&xt->head); -kfree (xt); +kfree_rcu (xt, rcu_head); +return true; } + +return false; } static int nft_compat_chain_validate_dependency(const char *tablename,
@@ -226,6 +236,7 @@ nft_target_init(const struct nft_ctx *ctstruct xt_target *target = expr->ops->data;struct xt_tgchk_param par;size_t size =XT_ALIGN (nla_len (tb[NFTA_TARGET_INFO ])); +struct nft_xt *nft_xt;u16 proto =0 ;bool inv = false;union nft_entry e = {};
@@ -236,25 +247,22 @@ nft_target_init(const struct nft_ctx *ctif (ctx->nla[NFTA_RULE_COMPAT ]) { ret =nft_parse_compat (ctx->nla[NFTA_RULE_COMPAT ], &proto, &inv);if (ret <0 ) - goto err; +return ret; }nft_target_set_tgchk_param (&par, ctx, target, info, &e, proto, inv); ret =xt_check_target (&par, size, proto, inv);if (ret <0 ) - goto err; +return ret;/* The standard target cannot be used */ -if (target->target ==NULL ) { - ret = -EINVAL ; - goto err; - } +if (!target->target) +return -EINVAL ; + nft_xt = container_of(expr->ops, struct nft_xt, ops); + nft_xt->refcnt++;return 0 ; -err: -module_put (target->me); -return ret; } static void
@@ -271,8 +279,8 @@ nft_target_destroy(const struct nft_ctxif (par.target->destroy !=NULL ) par.target->destroy (&par); - nft_xt_put(container_of(expr->ops, struct nft_xt, ops)); -module_put (target->me); + if (nft_xt_put(container_of(expr->ops, struct nft_xt, ops))) +module_put (target->me); }static int nft_target_dump (struct sk_buff *skb,const struct nft_expr *expr)
@@ -411,6 +419,7 @@ nft_match_init(const struct nft_ctx *ctxstruct xt_match *match = expr->ops->data;struct xt_mtchk_param par;size_t size =XT_ALIGN (nla_len (tb[NFTA_MATCH_INFO ])); +struct nft_xt *nft_xt;u16 proto =0 ;bool inv = false;union nft_entry e = {};
@@ -421,19 +430,18 @@ nft_match_init(const struct nft_ctx *ctxif (ctx->nla[NFTA_RULE_COMPAT ]) { ret =nft_parse_compat (ctx->nla[NFTA_RULE_COMPAT ], &proto, &inv);if (ret <0 ) - goto err; +return ret; }nft_match_set_mtchk_param (&par, ctx, match, info, &e, proto, inv); ret =xt_check_match (&par, size, proto, inv);if (ret <0 ) - goto err; +return ret; + nft_xt = container_of(expr->ops, struct nft_xt, ops); + nft_xt->refcnt++;return 0 ; -err: -module_put (match->me); -return ret; } static void
@@ -450,8 +458,8 @@ nft_match_destroy(const struct nft_ctx *if (par.match->destroy !=NULL ) par.match->destroy (&par); - nft_xt_put(container_of(expr->ops, struct nft_xt, ops)); -module_put (match->me); + if (nft_xt_put(container_of(expr->ops, struct nft_xt, ops))) +module_put (match->me); }static int nft_match_dump (struct sk_buff *skb,const struct nft_expr *expr)
@@ -654,13 +662,8 @@ nft_match_select_ops(const struct nft_ctlist_for_each_entry (nft_match, &nft_match_list, head) {struct xt_match *match = nft_match->ops.data; -if (nft_match_cmp (match, mt_name, rev, family)) { -if (!try_module_get (match->me)) -return ERR_PTR (-ENOENT ); - - nft_match->refcnt++; +if (nft_match_cmp (match, mt_name, rev, family))return &nft_match->ops; - } } match =xt_request_find_match (family, mt_name, rev);
@@ -679,7 +682,7 @@ nft_match_select_ops(const struct nft_ct goto err; } - nft_match->refcnt =1 ; + nft_match->refcnt =0 ; nft_match->ops.type = &nft_match_type; nft_match->ops.size =NFT_EXPR_SIZE (XT_ALIGN (match->matchsize)); nft_match->ops.eval = nft_match_eval;
@@ -739,13 +742,8 @@ nft_target_select_ops(const struct nft_clist_for_each_entry (nft_target, &nft_target_list, head) {struct xt_target *target = nft_target->ops.data; -if (nft_target_cmp (target, tg_name, rev, family)) { -if (!try_module_get (target->me)) -return ERR_PTR (-ENOENT ); - - nft_target->refcnt++; +if (nft_target_cmp (target, tg_name, rev, family))return &nft_target->ops; - } } target =xt_request_find_target (family, tg_name, rev);
@@ -764,7 +762,7 @@ nft_target_select_ops(const struct nft_c goto err; } - nft_target->refcnt =1 ; + nft_target->refcnt =0 ; nft_target->ops.type = &nft_target_type; nft_target->ops.size =NFT_EXPR_SIZE (XT_ALIGN (target->targetsize)); nft_target->ops.init = nft_target_init;
@@ -825,6 +823,32 @@ err_match: static void __exit nft_compat_module_exit(void) { +struct nft_xt *xt, *next; + +/* list should be empty here, it can be non-empty only in case there +* was an error that caused nft_xt expr to not be initialized fully +* and noone else requested the same expression later. +* +* In this case, the lists contain 0-refcount entries that still +* hold module reference. +*/ +list_for_each_entry_safe (xt, next, &nft_target_list, head) { +struct xt_target *target = xt->ops.data; + +if (WARN_ON_ONCE (xt->refcnt)) +continue ; +module_put (target->me); +kfree (xt); + } + +list_for_each_entry_safe (xt, next, &nft_match_list, head) { +struct xt_match *match = xt->ops.data; + +if (WARN_ON_ONCE (xt->refcnt)) +continue ; +module_put (match->me); +kfree (xt); + }nfnetlink_subsys_unregister (&nfnl_compat_subsys);nft_unregister_expr (&nft_target_type);nft_unregister_expr (&nft_match_type);
Greg Kroah-Hartman
maintainerPATCH 24/61 netfilter: nft_compat: prepare for indirect info storage
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 8bdf164744b2c7f63561846c01cff3db597f282d upstream.
Next patch will make it possible for *info to be stored in a separate allocation instead of the expr private area.
This removes the 'expr priv area is info blob' assumption from the match init/destroy/eval functions.
--- net/netfilter/nft_compat.c | 47 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-)
net/netfilter/nft_compat.c +36 -11
@@ -324,11 +324,11 @@ static int nft_target_validate(const strreturn 0 ; } -static void nft_match_eval (const struct nft_expr *expr, -struct nft_regs *regs, -const struct nft_pktinfo *pkt) +static void __nft_match_eval (const struct nft_expr *expr, +struct nft_regs *regs, +const struct nft_pktinfo *pkt, +void *info) { -void *info =nft_expr_priv (expr);struct xt_match *match = expr->ops->data;struct sk_buff *skb = pkt->skb;bool ret;
@@ -352,6 +352,13 @@ static void nft_match_eval(const struct } } +static void nft_match_eval (const struct nft_expr *expr, +struct nft_regs *regs, +const struct nft_pktinfo *pkt) +{ +__nft_match_eval (expr, regs, pkt,nft_expr_priv (expr)); +} +static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX +1 ] = { [NFTA_MATCH_NAME ] = { .type =NLA_NUL_STRING }, [NFTA_MATCH_REV ] = { .type =NLA_U32 },
@@ -412,10 +419,10 @@ static void match_compat_from_user(struc }static int -nft_match_init (const struct nft_ctx *ctx,const struct nft_expr *expr, -const struct nlattr *const tb[]) +__nft_match_init (const struct nft_ctx *ctx,const struct nft_expr *expr, +const struct nlattr *const tb[], +void *info) { -void *info =nft_expr_priv (expr);struct xt_match *match = expr->ops->data;struct xt_mtchk_param par;size_t size =XT_ALIGN (nla_len (tb[NFTA_MATCH_INFO ]));
@@ -444,11 +451,18 @@ nft_match_init(const struct nft_ctx *ctxreturn 0 ; } +static int +nft_match_init (const struct nft_ctx *ctx,const struct nft_expr *expr, +const struct nlattr *const tb[]) +{ +return __nft_match_init (ctx, expr, tb,nft_expr_priv (expr)); +} +static void -nft_match_destroy (const struct nft_ctx *ctx,const struct nft_expr *expr) +__nft_match_destroy (const struct nft_ctx *ctx,const struct nft_expr *expr, +void *info) {struct xt_match *match = expr->ops->data; -void *info =nft_expr_priv (expr);struct xt_mtdtor_param par; par.net = ctx->net;
@@ -462,9 +476,15 @@ nft_match_destroy(const struct nft_ctx *module_put (match->me); } -static int nft_match_dump (struct sk_buff *skb,const struct nft_expr *expr) +static void +nft_match_destroy (const struct nft_ctx *ctx,const struct nft_expr *expr) +{ +__nft_match_destroy (ctx, expr,nft_expr_priv (expr)); +} + +static int __nft_match_dump (struct sk_buff *skb,const struct nft_expr *expr, +void *info) { -void *info =nft_expr_priv (expr);struct xt_match *match = expr->ops->data; if (nla_put_string(skb, NFTA_MATCH_NAME, match->name) ||
@@ -478,6 +498,11 @@ nla_put_failure:return -1 ; } +static int nft_match_dump (struct sk_buff *skb,const struct nft_expr *expr) +{ +return __nft_match_dump (skb, expr,nft_expr_priv (expr)); +} +static int nft_match_validate (const struct nft_ctx *ctx,const struct nft_expr *expr,const struct nft_data **data)
PATCH 25/61 netfilter: nft_compat: fix handling of large matchinfo size
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 732a8049f365f514d0607e03938491bf6cb0d620 upstream.
currently matchinfo gets stored in the expression, but some xt matches are very large.
To handle those we either need to switch nft core to kvmalloc and increase size limit, or allocate the info blob of large matches separately.
This does the latter, this limits the scope of the changes to nft_compat.
I picked a threshold of 192, this allows most matches to work as before and handle only few ones via separate alloation (cgroup, u32, sctp, rt).
--- net/netfilter/nft_compat.c | 64 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-)
net/netfilter/nft_compat.c +63 -1
@@ -36,6 +36,13 @@ struct nft_xt {struct rcu_head rcu_head; }; +/* Used for matches where *info is larger than X byte */ +#define NFT_MATCH_LARGE_THRESH 192 + +struct nft_xt_match_priv { +void *info; +}; +static bool nft_xt_put (struct nft_xt *xt) {if (--xt->refcnt ==0 ) {
@@ -352,6 +359,15 @@ static void __nft_match_eval(const struc } } +static void nft_match_large_eval (const struct nft_expr *expr, +struct nft_regs *regs, +const struct nft_pktinfo *pkt) +{ +struct nft_xt_match_priv *priv =nft_expr_priv (expr); + +__nft_match_eval (expr, regs, pkt, priv->info); +} +static void nft_match_eval (const struct nft_expr *expr,struct nft_regs *regs,const struct nft_pktinfo *pkt)
@@ -458,6 +474,24 @@ nft_match_init(const struct nft_ctx *ctxreturn __nft_match_init (ctx, expr, tb,nft_expr_priv (expr)); } +static int +nft_match_large_init (const struct nft_ctx *ctx,const struct nft_expr *expr, +const struct nlattr *const tb[]) +{ +struct nft_xt_match_priv *priv =nft_expr_priv (expr); +struct xt_match *m = expr->ops->data; +int ret; + + priv->info =kmalloc (XT_ALIGN (m->matchsize),GFP_KERNEL ); +if (!priv->info) +return -ENOMEM ; + + ret =__nft_match_init (ctx, expr, tb, priv->info); +if (ret) +kfree (priv->info); +return ret; +} +static void __nft_match_destroy (const struct nft_ctx *ctx,const struct nft_expr *expr,void *info)
@@ -482,6 +516,15 @@ nft_match_destroy(const struct nft_ctx *__nft_match_destroy (ctx, expr,nft_expr_priv (expr)); } +static void +nft_match_large_destroy (const struct nft_ctx *ctx,const struct nft_expr *expr) +{ +struct nft_xt_match_priv *priv =nft_expr_priv (expr); + +__nft_match_destroy (ctx, expr, priv->info); +kfree (priv->info); +} +static int __nft_match_dump (struct sk_buff *skb,const struct nft_expr *expr,void *info) {
@@ -503,6 +546,13 @@ static int nft_match_dump(struct sk_buffreturn __nft_match_dump (skb, expr,nft_expr_priv (expr)); } +static int nft_match_large_dump (struct sk_buff *skb,const struct nft_expr *e) +{ +struct nft_xt_match_priv *priv =nft_expr_priv (e); + +return __nft_match_dump (skb, e, priv->info); +} +static int nft_match_validate (const struct nft_ctx *ctx,const struct nft_expr *expr,const struct nft_data **data)
@@ -670,6 +720,7 @@ nft_match_select_ops(const struct nft_ct {struct nft_xt *nft_match;struct xt_match *match; +unsigned int matchsize;char *mt_name;u32 rev, family;int err;
@@ -709,7 +760,6 @@ nft_match_select_ops(const struct nft_ct nft_match->refcnt =0 ; nft_match->ops.type = &nft_match_type; - nft_match->ops.size =NFT_EXPR_SIZE (XT_ALIGN (match->matchsize)); nft_match->ops.eval = nft_match_eval; nft_match->ops.init = nft_match_init; nft_match->ops.destroy = nft_match_destroy;
@@ -717,6 +767,18 @@ nft_match_select_ops(const struct nft_ct nft_match->ops.validate = nft_match_validate; nft_match->ops.data = match; + matchsize =NFT_EXPR_SIZE (XT_ALIGN (match->matchsize)); +if (matchsize >NFT_MATCH_LARGE_THRESH ) { + matchsize =NFT_EXPR_SIZE (sizeof (struct nft_xt_match_priv )); + + nft_match->ops.eval = nft_match_large_eval; + nft_match->ops.init = nft_match_large_init; + nft_match->ops.destroy = nft_match_large_destroy; + nft_match->ops.dump = nft_match_large_dump; + } + + nft_match->ops.size = matchsize; +list_add (&nft_match->head, &nft_match_list);return &nft_match->ops;
Greg Kroah-Hartman
maintainerPATCH 26/61 netfilter: nf_tables: dont assume chain stats are set when jumplabel is set
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 009240940e84c1c089af88b454f7e804a4c5bd1b upstream.
nft_chain_stats_replace() and all other spots assume ->stats can be NULL, but nft_update_chain_stats does not. It must do this check, just because the jump label is set doesn't mean all basechains have stats assigned.
--- net/netfilter/nf_tables_core.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
net/netfilter/nf_tables_core.c +14 -7
@@ -119,15 +119,22 @@ DEFINE_STATIC_KEY_FALSE(nft_counters_ena static noinline void nft_update_chain_stats(const struct nft_chain *chain,const struct nft_pktinfo *pkt) { +struct nft_base_chain *base_chain;struct nft_stats *stats; -local_bh_disable (); - stats =this_cpu_ptr (rcu_dereference (nft_base_chain (chain)->stats)); -u64_stats_update_begin (&stats->syncp); - stats->pkts++; - stats->bytes += pkt->skb->len; -u64_stats_update_end (&stats->syncp); -local_bh_enable (); + base_chain =nft_base_chain (chain); +if (!base_chain->stats) +return ; + + stats =this_cpu_ptr (rcu_dereference (base_chain->stats)); +if (stats) { +local_bh_disable (); +u64_stats_update_begin (&stats->syncp); + stats->pkts++; + stats->bytes += pkt->skb->len; +u64_stats_update_end (&stats->syncp); +local_bh_enable (); + } }struct nft_jumpstack {
Greg Kroah-Hartman
maintainerPATCH 27/61 netfilter: nf_tables: bogus EBUSY in chain deletions
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit bb7b40aecbf778c0c83a5bd62b0f03ca9f49a618 upstream.
When removing a rule that jumps to chain and such chain in the same batch, this bogusly hits EBUSY. Add activate and deactivate operations to expression that can be called from the preparation and the commit/abort phases.
--- include/net/netfilter/nf_tables.h | 5 ++++ net/netfilter/nf_tables_api.c | 46 ++++++++++++++++++++++++++++++++++---- net/netfilter/nft_immediate.c | 15 +++++++++--- 3 files changed, 59 insertions(+), 7 deletions(-)
include/net/netfilter/nf_tables.h +5 -0
@@ -177,6 +177,7 @@ struct nft_data_desc {int nft_data_init (const struct nft_ctx *ctx,struct nft_data *data,unsigned int size,struct nft_data_desc *desc,const struct nlattr *nla); +void nft_data_hold (const struct nft_data *data,enum nft_data_types type);void nft_data_release (const struct nft_data *data,enum nft_data_types type);int nft_data_dump (struct sk_buff *skb,int attr,const struct nft_data *data,enum nft_data_types type,unsigned int len);
@@ -731,6 +732,10 @@ struct nft_expr_ops {int (*init)(const struct nft_ctx *ctx,const struct nft_expr *expr,const struct nlattr *const tb[]); +void (*activate)(const struct nft_ctx *ctx, +const struct nft_expr *expr); +void (*deactivate)(const struct nft_ctx *ctx, +const struct nft_expr *expr);void (*destroy)(const struct nft_ctx *ctx,const struct nft_expr *expr); int (*dump)(struct sk_buff *skb,
net/netfilter/nf_tables_api.c +42 -4
98 lines not on this page · raw message
net/netfilter/nft_immediate.c +12 -3
@@ -69,8 +69,16 @@ err1:return err; } -static void nft_immediate_destroy (const struct nft_ctx *ctx, -const struct nft_expr *expr) +static void nft_immediate_activate (const struct nft_ctx *ctx, +const struct nft_expr *expr) +{ +const struct nft_immediate_expr *priv =nft_expr_priv (expr); + +return nft_data_hold (&priv->data,nft_dreg_to_type (priv->dreg)); +} + +static void nft_immediate_deactivate (const struct nft_ctx *ctx, +const struct nft_expr *expr) {const struct nft_immediate_expr *priv =nft_expr_priv (expr);
@@ -108,7 +116,8 @@ static const struct nft_expr_ops nft_imm .size = NFT_EXPR_SIZE(sizeof(struct nft_immediate_expr)), .eval = nft_immediate_eval, .init = nft_immediate_init, - .destroy = nft_immediate_destroy, + .activate = nft_immediate_activate, + .deactivate = nft_immediate_deactivate, .dump = nft_immediate_dump, .validate = nft_immediate_validate, };
Greg Kroah-Hartman
maintainerPATCH 28/61 netfilter: nft_meta: fix wrong value dereference in nft_meta_set_eval
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taehee Yoo <[email protected]>
commit 97a0549b15a0b466c47f6a0143a490a082c64b4e upstream.
In the nft_meta_set_eval, nftrace value is dereferenced as u32 from sreg. But correct type is u8. so that sometimes incorrect value is dereferenced.
Steps to reproduce:
%nft add table ip filter
%nft add chain ip filter input { type filter hook input priority 4\; } %nft add rule ip filter input nftrace set 0
%nft monitor
Sometimes, we can see trace messages.
trace id 16767227 ip filter input packet: iif "enp2s0" ether saddr xx:xx:xx:xx:xx:xx ether daddr xx:xx:xx:xx:xx:xx ip saddr 192.168.0.1 ip daddr 255.255.255.255 ip dscp cs0 ip ecn not-ect ip
trace id 16767227 ip filter input rule nftrace set 0 (verdict continue) trace id 16767227 ip filter input verdict continue
trace id 16767227 ip filter input
--- net/netfilter/nft_meta.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
net/netfilter/nft_meta.c +8 -6
@@ -229,7 +229,7 @@ void nft_meta_set_eval(const struct nft_struct sk_buff *skb = pkt->skb;u32 *sreg = ®s->data[meta->sreg];u32 value = *sreg; -u8 pkt_type; +u8 value8;switch (meta->key) {case NFT_META_MARK :
@@ -239,15 +239,17 @@ void nft_meta_set_eval(const struct nft_ skb->priority = value;break ;case NFT_META_PKTTYPE : - pkt_type =nft_reg_load8 (sreg); + value8 =nft_reg_load8 (sreg); -if (skb->pkt_type != pkt_type && -skb_pkt_type_ok (pkt_type) && +if (skb->pkt_type != value8 && +skb_pkt_type_ok (value8) &&skb_pkt_type_ok (skb->pkt_type)) - skb->pkt_type = pkt_type; + skb->pkt_type = value8;break ;case NFT_META_NFTRACE : - skb->nf_trace = !!value; + value8 =nft_reg_load8 (sreg); + + skb->nf_trace = !!value8;break ;default :WARN_ON (1 );
Greg Kroah-Hartman
maintainerPATCH 29/61 netfilter: nf_tables: disable preemption in nft_update_chain_stats()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
commit ad9d9e85072b668731f356be0a3750a3ba22a607 upstream.
This patch fixes the following splat.
[118709.054937] BUG: using smp_processor_id() in preemptible [00000000] code: test/1571 [118709.054970] caller is nft_update_chain_stats.isra.4+0x53/0x97 [nf_tables] [118709.054980] CPU: 2 PID: 1571 Comm: test Not tainted 4.17.0-rc6+ #335 [...] [118709.054992] Call Trace: [118709.055011] dump_stack+0x5f/0x86 [118709.055026] check_preemption_disabled+0xd4/0xe4
--- net/netfilter/nf_tables_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netfilter/nf_tables_core.c +2 -2
@@ -126,15 +126,15 @@ static noinline void nft_update_chain_stif (!base_chain->stats)return ; +local_bh_disable (); stats =this_cpu_ptr (rcu_dereference (base_chain->stats));if (stats) { -local_bh_disable ();u64_stats_update_begin (&stats->syncp); stats->pkts++; stats->bytes += pkt->skb->len;u64_stats_update_end (&stats->syncp); -local_bh_enable (); } +local_bh_enable (); }struct nft_jumpstack {
Greg Kroah-Hartman
maintainerPATCH 30/61 netfilter: nf_tables: increase nft_counters_enabled in nft_chain_stats_replace()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taehee Yoo <[email protected]>
commit bbb8c61f97e3a2dd91b30d3e57b7964a67569d11 upstream.
When a chain is updated, a counter can be attached. if so, the nft_counters_enabled should be increased.
test commands:
%nft add table ip filter
%nft add chain ip filter input { type filter hook input priority 4\; } %iptables-compat -Z input
%nft delete chain ip filter input
we can see below messages.
[ 286.443720] jump label: negative count! [ 286.448278] WARNING: CPU: 0 PID: 1459 at kernel/jump_label.c:197 __static_key_slow_dec_cpuslocked+0x6f/0xf0 [ 286.449144] Modules linked in: nf_tables nfnetlink ip_tables x_tables [ 286.449144] CPU: 0 PID: 1459 Comm: nft Tainted: G W 4.17.0-rc2+ #12 [ 286.449144] RIP: 0010:__static_key_slow_dec_cpuslocked+0x6f/0xf0 [ 286.449144] RSP: 0018:ffff88010e5176f0 EFLAGS: 00010286 [ 286.449144] RAX: 000000000000001b RBX: ffffffffc0179500 RCX: ffffffffb8a82522 [ 286.449144] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffff88011b7e5eac [ 286.449144] RBP: 0000000000000000 R08: ffffed00236fce5c R09: ffffed00236fce5b [ 286.449144] R10: ffffffffc0179503 R11: ffffed00236fce5c R12: 0000000000000000 [ 286.449144] R13: ffff88011a28e448 R14: ffff88011a28e470 R15: dffffc0000000000 [ 286.449144] FS: 00007f0384328700(0000) GS:ffff88011b600000(0000) knlGS:0000000000000000 [ 286.449144] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 286.449144] CR2: 00007f038394bf10 CR3: 0000000104a86000 CR4: 00000000001006f0 [ 286.449144] Call Trace: [ 286.449144] static_key_slow_dec+0x6a/0x70 [ 286.449144] nf_tables_chain_destroy+0x19d/0x210 [nf_tables] [ 286.449144] nf_tables_commit+0x1891/0x1c50 [nf_tables] [ 286.449144] nfnetlink_rcv+0x1148/0x13d0 [nfnetlink]
[ ... ]
--- net/netfilter/nf_tables_api.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +3 -1
@@ -1266,8 +1266,10 @@ static void nft_chain_stats_replace(strurcu_assign_pointer (chain->stats, newstats);synchronize_rcu ();free_percpu (oldstats); - }else + }else {rcu_assign_pointer (chain->stats, newstats); +static_branch_inc (&nft_counters_enabled); + } }static void nf_tables_chain_destroy (struct nft_chain *chain)
Greg Kroah-Hartman
maintainerPATCH 31/61 netfilter: nf_tables: fix memory leak on error exit return
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <[email protected]>
commit f0dfd7a2b35b02030949100247d851b793cb275f upstream.
Currently the -EBUSY error return path is not free'ing resources allocated earlier, leaving a memory leak. Fix this by exiting via the error exit label err5 that performs the necessary resource clean up.
Detected by CoverityScan, CID#1432975 ("Resource leak")
--- net/netfilter/nf_tables_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/netfilter/nf_tables_api.c +4 -2
@@ -3999,8 +3999,10 @@ static int nft_add_set_elem(struct nft_cif (nft_set_ext_exists (ext,NFT_SET_EXT_DATA ) ^nft_set_ext_exists (ext2,NFT_SET_EXT_DATA ) ||nft_set_ext_exists (ext,NFT_SET_EXT_OBJREF ) ^ -nft_set_ext_exists (ext2,NFT_SET_EXT_OBJREF )) -return -EBUSY ; +nft_set_ext_exists (ext2,NFT_SET_EXT_OBJREF )) { + err = -EBUSY ; + goto err5; + } if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) && nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) && memcmp(nft_set_ext_data(ext),
Greg Kroah-Hartman
maintainerPATCH 32/61 netfilter: nf_tables: add missing netlink attrs to policies
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 467697d289e7e6e1b15910d99096c0da08c56d5b upstream.
--- net/netfilter/nf_tables_api.c | 3 +++ 1 file changed, 3 insertions(+)
net/netfilter/nf_tables_api.c +3 -0
@@ -1978,6 +1978,7 @@ static const struct nla_policy nft_rule_ [NFTA_RULE_POSITION] = { .type = NLA_U64 }, [NFTA_RULE_USERDATA ] = { .type =NLA_BINARY , .len = NFT_USERDATA_MAXLEN }, + [NFTA_RULE_ID] = { .type = NLA_U32 }, }; static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
@@ -3412,6 +3413,8 @@ static const struct nla_policy nft_set_e [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 }, [NFTA_SET_ELEM_USERDATA ] = { .type =NLA_BINARY , .len = NFT_USERDATA_MAXLEN }, + [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED }, + [NFTA_SET_ELEM_OBJREF] = { .type = NLA_STRING }, };static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +1 ] = {
Greg Kroah-Hartman
maintainerPATCH 33/61 netfilter: nf_tables: fix NULL-ptr in nf_tables_dump_obj()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taehee Yoo <[email protected]>
commit 360cc79d9d299ce297b205508276285ceffc5fa8 upstream.
The table field in nft_obj_filter is not an array. In order to check tablename, we should check if the pointer is set.
Test commands:
%nft add table ip filter
%nft add counter ip filter ct1
%nft reset counters
Splat looks like:
[ 306.510504] kasan: CONFIG_KASAN_INLINE enabled [ 306.516184] kasan: GPF could be caused by NULL-ptr deref or user memory access [ 306.524775] general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI [ 306.528284] Modules linked in: nft_objref nft_counter nf_tables nfnetlink ip_tables x_tables [ 306.528284] CPU: 0 PID: 1488 Comm: nft Not tainted 4.17.0-rc4+ #17 [ 306.528284] Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 07/08/2015 [ 306.528284] RIP: 0010:nf_tables_dump_obj+0x52c/0xa70 [nf_tables] [ 306.528284] RSP: 0018:ffff8800b6cb7520 EFLAGS: 00010246 [ 306.528284] RAX: 0000000000000000 RBX: ffff8800b6c49820 RCX: 0000000000000000 [ 306.528284] RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffffed0016d96e9a [ 306.528284] RBP: ffff8800b6cb75c0 R08: ffffed00236fce7c R09: ffffed00236fce7b [ 306.528284] R10: ffffffff9f6241e8 R11: ffffed00236fce7c R12: ffff880111365108 [ 306.528284] R13: 0000000000000000 R14: ffff8800b6c49860 R15: ffff8800b6c49860 [ 306.528284] FS: 00007f838b007700(0000) GS:ffff88011b600000(0000) knlGS:0000000000000000 [ 306.528284] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 306.528284] CR2: 00007ffeafabcf78 CR3: 00000000b6cbe000 CR4: 00000000001006f0 [ 306.528284] Call Trace: [ 306.528284] netlink_dump+0x470/0xa20 [ 306.528284] __netlink_dump_start+0x5ae/0x690 [ 306.528284] ? nf_tables_getobj+0x1b3/0x740 [nf_tables] [ 306.528284] nf_tables_getobj+0x2f5/0x740 [nf_tables] [ 306.528284] ? nft_obj_notify+0x100/0x100 [nf_tables] [ 306.528284] ? nf_tables_getobj+0x740/0x740 [nf_tables] [ 306.528284] ? nf_tables_dump_flowtable_done+0x70/0x70 [nf_tables] [ 306.528284] ? nft_obj_notify+0x100/0x100 [nf_tables] [ 306.528284] nfnetlink_rcv_msg+0x8ff/0x932 [nfnetlink] [ 306.528284] ? nfnetlink_rcv_msg+0x216/0x932 [nfnetlink] [ 306.528284] netlink_rcv_skb+0x1c9/0x2f0 [ 306.528284] ? nfnetlink_bind+0x1d0/0x1d0 [nfnetlink] [ 306.528284] ? debug_check_no_locks_freed+0x270/0x270 [ 306.528284] ? netlink_ack+0x7a0/0x7a0 [ 306.528284] ? ns_capable_common+0x6e/0x110
[ ... ]
--- net/netfilter/nf_tables_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +1 -1
@@ -4614,7 +4614,7 @@ static int nf_tables_dump_obj(struct sk_if (idx > s_idx)memset (&cb->args[1 ],0 ,sizeof (cb->args) -sizeof (cb->args[0 ])); -if (filter && filter->table[0 ] && +if (filter && filter->table &&strcmp (filter->table, table->name)) goto cont; if (filter &&
Greg Kroah-Hartman
maintainerPATCH 34/61 md: always hold reconfig_mutex when calling mddev_suspend()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 4d5324f760aacaefeb721b172aa14bf66045c332 upstream.
Most often mddev_suspend() is called with reconfig_mutex held. Make this a requirement in preparation a subsequent patch. Also require reconfig_mutex to be held for mddev_resume(), partly for symmetry and partly to guarantee no races with incr/decr of mddev->suspend.
Taking the mutex in r5c_disable_writeback_async() is a little tricky as this is called from a work queue via log->disable_writeback_work, and flush_work() is called on that while holding ->reconfig_mutex. If the work item hasn't run before flush_work() is called, the work function will not be able to get the mutex.
So we use mddev_trylock() inside the wait_event() call, and have that abort when conf->log is set to NULL, which happens before flush_work() is called.
We wait in mddev->sb_wait and ensure this is woken
when any of the conditions change. This requires
waking mddev->sb_wait in mddev_unlock(). This is only like to trigger extra wake_ups of threads that needn't
be woken when metadata is being written, and that
doesn't happen often enough that the cost would be noticeable.
--- drivers/md/dm-raid.c | 10 ++++++++-- drivers/md/md.c | 3 +++ drivers/md/raid5-cache.c | 18 +++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-)
drivers/md/dm-raid.c +8 -2
@@ -3637,8 +3637,11 @@ static void raid_postsuspend(struct dm_t {struct raid_set *rs = ti->private; -if (!test_and_set_bit (RT_FLAG_RS_SUSPENDED , &rs->runtime_flags)) +if (!test_and_set_bit (RT_FLAG_RS_SUSPENDED , &rs->runtime_flags)) { +mddev_lock_nointr (&rs->md);mddev_suspend (&rs->md); +mddev_unlock (&rs->md); + } rs->md.ro =1 ; }
@@ -3898,8 +3901,11 @@ static void raid_resume(struct dm_targetif (!(rs->ctr_flags &RESUME_STAY_FROZEN_FLAGS ))clear_bit (MD_RECOVERY_FROZEN , &mddev->recovery); -if (test_and_clear_bit (RT_FLAG_RS_SUSPENDED , &rs->runtime_flags)) +if (test_and_clear_bit (RT_FLAG_RS_SUSPENDED , &rs->runtime_flags)) { +mddev_lock_nointr (mddev);mddev_resume (mddev); +mddev_unlock (mddev); + } }static struct target_type raid_target = {
drivers/md/md.c +3 -0
@@ -344,6 +344,7 @@ static blk_qc_t md_make_request(struct rvoid mddev_suspend (struct mddev *mddev) {WARN_ON_ONCE (mddev->thread && current == mddev->thread->tsk); +lockdep_assert_held (&mddev->reconfig_mutex);if (mddev->suspended++)return ;synchronize_rcu ();
@@ -357,6 +358,7 @@ EXPORT_SYMBOL_GPL(mddev_suspend);void mddev_resume (struct mddev *mddev) { +lockdep_assert_held (&mddev->reconfig_mutex);if (--mddev->suspended)return ;wake_up (&mddev->sb_wait);
@@ -663,6 +665,7 @@ void mddev_unlock(struct mddev *mddev)*/ spin_lock (&pers_lock);md_wakeup_thread (mddev->thread); +wake_up (&mddev->sb_wait);spin_unlock (&pers_lock); }EXPORT_SYMBOL_GPL (mddev_unlock);
drivers/md/raid5-cache.c +13 -5
@@ -693,6 +693,8 @@ static void r5c_disable_writeback_async( struct r5l_log *log = container_of(work, struct r5l_log, disable_writeback_work);struct mddev *mddev = log->rdev->mddev; +struct r5conf *conf = mddev->private; +int locked =0 ;if (log->r5c_journal_mode ==R5C_JOURNAL_MODE_WRITE_THROUGH )return ;
@@ -701,11 +703,15 @@ static void r5c_disable_writeback_async(/* wait superblock change before suspend */ wait_event (mddev->sb_wait, - !test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags)); - -mddev_suspend (mddev); - log->r5c_journal_mode =R5C_JOURNAL_MODE_WRITE_THROUGH ; -mddev_resume (mddev); + conf->log ==NULL || + (!test_bit (MD_SB_CHANGE_PENDING , &mddev->sb_flags) && + (locked =mddev_trylock (mddev)))); +if (locked) { +mddev_suspend (mddev); + log->r5c_journal_mode =R5C_JOURNAL_MODE_WRITE_THROUGH ; +mddev_resume (mddev); +mddev_unlock (mddev); + } }static void r5l_submit_current_io (struct r5l_log *log)
@@ -3161,6 +3167,8 @@ void r5l_exit_log(struct r5conf *conf) conf->log =NULL ;synchronize_rcu (); +/* Ensure disable_writeback_work wakes up and exits */ +wake_up (&conf->mddev->sb_wait);flush_work (&log->disable_writeback_work);md_unregister_thread (&log->reclaim_thread);mempool_destroy (log->meta_pool);
Greg Kroah-Hartman
maintainerPATCH 35/61 md: dont call bitmap_create() while array is quiesced.
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 52a0d49de3d592a3118e13f35985e3d99eaf43df upstream.
bitmap_create() allocates memory with GFP_KERNEL and
so can wait for IO.
If called while the array is quiesced, it could wait indefinitely for write out to the array - deadlock.
So call bitmap_create() before quiescing the array.
--- drivers/md/md.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/md/md.c +10 -6
@@ -6645,22 +6645,26 @@ static int set_bitmap_file(struct mddevreturn -ENOENT ;/* cannot remove what isn't there */ err =0 ;if (mddev->pers) { - mddev->pers->quiesce (mddev,1 );if (fd >=0 ) {struct bitmap *bitmap; bitmap =bitmap_create (mddev,-1 ); + mddev->pers->quiesce (mddev,1 );if (!IS_ERR (bitmap)) { mddev->bitmap = bitmap; err =bitmap_load (mddev); }else err =PTR_ERR (bitmap); - } -if (fd <0 || err) { +if (err) { +bitmap_destroy (mddev); + fd =-1 ; + } + mddev->pers->quiesce (mddev,0 ); + }else if (fd <0 ) { + mddev->pers->quiesce (mddev,1 );bitmap_destroy (mddev); - fd =-1 ;/* make sure to put the file */ + mddev->pers->quiesce (mddev,0 ); } - mddev->pers->quiesce (mddev,0 ); }if (fd <0 ) {struct file *f = mddev->bitmap_info.file;
@@ -6944,8 +6948,8 @@ static int update_array_info(struct mdde mddev->bitmap_info.default_offset; mddev->bitmap_info.space = mddev->bitmap_info.default_space; - mddev->pers->quiesce (mddev,1 ); bitmap =bitmap_create (mddev,-1 ); + mddev->pers->quiesce (mddev,1 );if (!IS_ERR (bitmap)) { mddev->bitmap = bitmap; rv =bitmap_load (mddev);
Greg Kroah-Hartman
maintainerPATCH 36/61 md: move suspend_hi/lo handling into core md code
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit b3143b9a38d5039bcd1f2d1c94039651bfba8043 upstream.
responding to ->suspend_lo and ->suspend_hi is similar to responding to ->suspended. It is best to wait in the common core code without incrementing ->active_io. This allows mddev_suspend()/mddev_resume() to work while requests are waiting for suspend_lo/hi to change. This is will be important after a subsequent patch which uses mddev_suspend() to synchronize updating for suspend_lo/hi.
So move the code for testing suspend_lo/hi out of raid1.c and raid5.c, and place it in md.c
--- drivers/md/md.c | 29 +++++++++++++++++++++++------ drivers/md/raid1.c | 14 +++++--------- drivers/md/raid5.c | 22 ---------------------- 3 files changed, 28 insertions(+), 37 deletions(-)
drivers/md/md.c +23 -6
@@ -266,16 +266,31 @@ static DEFINE_SPINLOCK(all_mddevs_lock);* call has finished, the bio has been linked into some internal structure * and so is visible to ->quiesce(), so we don't need the refcount any more. */ +static bool is_suspended (struct mddev *mddev,struct bio *bio) +{ +if (mddev->suspended) +return true; +if (bio_data_dir (bio) !=WRITE ) +return false; +if (mddev->suspend_lo >= mddev->suspend_hi) +return false; +if (bio->bi_iter.bi_sector >= mddev->suspend_hi) +return false; +if (bio_end_sector (bio) < mddev->suspend_lo) +return false; +return true; +} +void md_handle_request (struct mddev *mddev,struct bio *bio) { check_suspended:rcu_read_lock (); -if (mddev->suspended) { +if (is_suspended (mddev, bio)) {DEFINE_WAIT (__wait);for (;;) {prepare_to_wait (&mddev->sb_wait, &__wait,TASK_UNINTERRUPTIBLE ); -if (!mddev->suspended) +if (!is_suspended (mddev, bio))break ;rcu_read_unlock ();schedule ();
@@ -4849,10 +4864,11 @@ suspend_lo_store(struct mddev *mddev, co goto unlock; old = mddev->suspend_lo; mddev->suspend_lo = new; -if (new >= old) +if (new >= old) {/* Shrinking suspended region */ +wake_up (&mddev->sb_wait); mddev->pers->quiesce (mddev,2 ); -else { + }else {/* Expanding suspended region - need to wait */ mddev->pers->quiesce (mddev,1 ); mddev->pers->quiesce (mddev,0 );
@@ -4892,10 +4908,11 @@ suspend_hi_store(struct mddev *mddev, co goto unlock; old = mddev->suspend_hi; mddev->suspend_hi = new; -if (new <= old) +if (new <= old) {/* Shrinking suspended region */ +wake_up (&mddev->sb_wait); mddev->pers->quiesce (mddev,2 ); -else { + }else {/* Expanding suspended region - need to wait */ mddev->pers->quiesce (mddev,1 ); mddev->pers->quiesce (mddev,0 );
drivers/md/raid1.c +5 -9
@@ -1298,11 +1298,9 @@ static void raid1_write_request(struct m*/ -if ((bio_end_sector (bio) > mddev->suspend_lo && - bio->bi_iter.bi_sector < mddev->suspend_hi) || - (mddev_is_clustered (mddev) && +if (mddev_is_clustered (mddev) && md_cluster_ops->area_resyncing (mddev,WRITE , - bio->bi_iter.bi_sector,bio_end_sector (bio)))) { + bio->bi_iter.bi_sector,bio_end_sector (bio))) {/* * As the suspend_* range is controlled by userspace, we want
@@ -1313,12 +1311,10 @@ static void raid1_write_request(struct msigset_t full, old;prepare_to_wait (&conf->wait_barrier, &w,TASK_INTERRUPTIBLE ); -if ((bio_end_sector (bio) <= mddev->suspend_lo || - bio->bi_iter.bi_sector >= mddev->suspend_hi) && - (!mddev_is_clustered (mddev) || - !md_cluster_ops->area_resyncing (mddev,WRITE , +if (!mddev_is_clustered (mddev) || + !md_cluster_ops->area_resyncing (mddev,WRITE , bio->bi_iter.bi_sector, -bio_end_sector (bio)))) +bio_end_sector (bio)))break ;sigfillset (&full);sigprocmask (SIG_BLOCK , &full, &old);
drivers/md/raid5.c +0 -22
@@ -5686,28 +5686,6 @@ static bool raid5_make_request(struct md goto retry; } -if (rw ==WRITE && - logical_sector >= mddev->suspend_lo && - logical_sector < mddev->suspend_hi) { -raid5_release_stripe (sh); -/* As the suspend_* range is controlled by -* userspace, we want an interruptible -* wait. -*/ -prepare_to_wait (&conf->wait_for_overlap, - &w,TASK_INTERRUPTIBLE ); -if (logical_sector >= mddev->suspend_lo && - logical_sector < mddev->suspend_hi) { -sigset_t full, old; -sigfillset (&full); -sigprocmask (SIG_BLOCK , &full, &old); -schedule (); -sigprocmask (SIG_SETMASK , &old,NULL ); - do_prepare = true; - } - goto retry; - } -if (test_bit (STRIPE_EXPANDING , &sh->state) || !add_stripe_bio (sh, bi, dd_idx, rw, previous)) {/* Stripe is busy expanding or
Greg Kroah-Hartman
maintainerPATCH 37/61 md: use mddev_suspend/resume instead of ->quiesce()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 9e1cc0a54556a6c63dc0cfb7cd7d60d43337bba6 upstream.
mddev_suspend() is a more general interface than calling ->quiesce() and is so more extensible. A future patch will make use of this.
--- drivers/md/md.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/md/md.c +12 -12
@@ -4870,8 +4870,8 @@ suspend_lo_store(struct mddev *mddev, co mddev->pers->quiesce (mddev,2 ); }else {/* Expanding suspended region - need to wait */ - mddev->pers->quiesce (mddev,1 ); - mddev->pers->quiesce (mddev,0 ); +mddev_suspend (mddev); +mddev_resume (mddev); } err =0 ; unlock:
@@ -4914,8 +4914,8 @@ suspend_hi_store(struct mddev *mddev, co mddev->pers->quiesce (mddev,2 ); }else {/* Expanding suspended region - need to wait */ - mddev->pers->quiesce (mddev,1 ); - mddev->pers->quiesce (mddev,0 ); +mddev_suspend (mddev); +mddev_resume (mddev); } err =0 ; unlock:
@@ -6666,7 +6666,7 @@ static int set_bitmap_file(struct mddevstruct bitmap *bitmap; bitmap =bitmap_create (mddev,-1 ); - mddev->pers->quiesce (mddev,1 ); +mddev_suspend (mddev);if (!IS_ERR (bitmap)) { mddev->bitmap = bitmap; err =bitmap_load (mddev);
@@ -6676,11 +6676,11 @@ static int set_bitmap_file(struct mddevbitmap_destroy (mddev); fd =-1 ; } - mddev->pers->quiesce (mddev,0 ); +mddev_resume (mddev); }else if (fd <0 ) { - mddev->pers->quiesce (mddev,1 ); +mddev_suspend (mddev);bitmap_destroy (mddev); - mddev->pers->quiesce (mddev,0 ); +mddev_resume (mddev); } }if (fd <0 ) {
@@ -6966,7 +6966,7 @@ static int update_array_info(struct mdde mddev->bitmap_info.space = mddev->bitmap_info.default_space; bitmap =bitmap_create (mddev,-1 ); - mddev->pers->quiesce (mddev,1 ); +mddev_suspend (mddev);if (!IS_ERR (bitmap)) { mddev->bitmap = bitmap; rv =bitmap_load (mddev);
@@ -6974,7 +6974,7 @@ static int update_array_info(struct mdde rv =PTR_ERR (bitmap);if (rv)bitmap_destroy (mddev); - mddev->pers->quiesce (mddev,0 ); +mddev_resume (mddev); }else {/* remove the bitmap */ if (!mddev->bitmap) {
@@ -6997,9 +6997,9 @@ static int update_array_info(struct mdde mddev->bitmap_info.nodes =0 ; md_cluster_ops->leave (mddev); } - mddev->pers->quiesce (mddev,1 ); +mddev_suspend (mddev);bitmap_destroy (mddev); - mddev->pers->quiesce (mddev,0 ); +mddev_resume (mddev); mddev->bitmap_info.offset =0 ; } }
Greg Kroah-Hartman
maintainerPATCH 38/61 md: allow metadata update while suspending.
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 35bfc52187f6df8779d0f1cebdb52b7f797baf4e upstream.
There are various deadlocks that can occur when a thread holds reconfig_mutex and calls ->quiesce(mddev, 1).
As some write request block waiting for metadata to be updated (e.g. to record device failure), and as the md thread updates the metadata while the reconfig mutex is held, holding the mutex can stop write requests completing, and this prevents ->quiesce(mddev, 1) from completing.
->quiesce() is now usually called from mddev_suspend(), and it is always called with reconfig_mutex held. So at this time it is safe for the thread to update metadata without explicitly taking the lock.
So add 2 new flags, one which says the unlocked updates is allowed, and one which ways it is happening. Then allow it while the quiesce completes, and then wait for it to finish.
--- drivers/md/md.c | 14 ++++++++++++++ drivers/md/md.h | 6 ++++++ 2 files changed, 20 insertions(+)
drivers/md/md.c +14 -0
@@ -364,8 +364,12 @@ void mddev_suspend(struct mddev *mddev)return ;synchronize_rcu ();wake_up (&mddev->sb_wait); +set_bit (MD_ALLOW_SB_UPDATE , &mddev->flags); +smp_mb__after_atomic ();wait_event (mddev->sb_wait,atomic_read (&mddev->active_io) ==0 ); mddev->pers->quiesce (mddev,1 ); +clear_bit_unlock (MD_ALLOW_SB_UPDATE , &mddev->flags); +wait_event (mddev->sb_wait, !test_bit (MD_UPDATING_SB , &mddev->flags));del_timer_sync (&mddev->safemode_timer); }
@@ -8882,6 +8886,16 @@ void md_check_recovery(struct mddev *mdd unlock:wake_up (&mddev->sb_wait);mddev_unlock (mddev); + }else if (test_bit (MD_ALLOW_SB_UPDATE , &mddev->flags) && mddev->sb_flags) { +/* Write superblock - thread that called mddev_suspend() +* holds reconfig_mutex for us. +*/ +set_bit (MD_UPDATING_SB , &mddev->flags); +smp_mb__after_atomic (); +if (test_bit (MD_ALLOW_SB_UPDATE , &mddev->flags)) +md_update_sb (mddev,0 ); +clear_bit_unlock (MD_UPDATING_SB , &mddev->flags); +wake_up (&mddev->sb_wait); } }EXPORT_SYMBOL (md_check_recovery);
drivers/md/md.h +6 -0
@@ -237,6 +237,12 @@ enum mddev_flags {*/ MD_HAS_PPL ,/* The raid array has PPL feature set */ MD_HAS_MULTIPLE_PPLS ,/* The raid array has multiple PPLs feature set */ +MD_ALLOW_SB_UPDATE ,/* md_check_recovery is allowed to update +* the metadata without taking reconfig_mutex. +*/ + MD_UPDATING_SB, /* md_check_recovery is updating the metadata + * without explicitly holding reconfig_mutex. + */ }; enum mddev_sb_flags {
Greg Kroah-Hartman
maintainerPATCH 39/61 md: remove special meaning of ->quiesce(.., 2)
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit b03e0ccb5ab9df3efbe51c87843a1ffbecbafa1f upstream.
The '2' argument means "wake up anything that is waiting". This is an inelegant part of the design and was added to help support management of suspend_lo/suspend_hi setting. Now that suspend_lo/hi is managed in mddev_suspend/resume, that need is gone.
These is still a couple of places where we call 'quiesce' with an argument of '2', but they can safely be changed to call ->quiesce(.., 1); ->quiesce(.., 0) which achieve the same result at the small cost of pausing IO briefly.
This removes a small "optimization" from suspend_{hi,lo}_store, but it isn't clear that optimization served a useful purpose. The code now is a lot clearer.
--- drivers/md/md-cluster.c | 6 +++--- drivers/md/md.c | 34 ++++++++++------------------------ drivers/md/md.h | 9 ++++----- drivers/md/raid0.c | 2 +- drivers/md/raid1.c | 13 +++---------- drivers/md/raid10.c | 10 +++------- drivers/md/raid5-cache.c | 12 ++++++------ drivers/md/raid5-log.h | 2 +- drivers/md/raid5.c | 18 ++++++------------ 9 files changed, 37 insertions(+), 69 deletions(-)
drivers/md/md-cluster.c +3 -3
@@ -442,10 +442,11 @@ static void __remove_suspend_info(structstatic void remove_suspend_info (struct mddev *mddev,int slot) {struct md_cluster_info *cinfo = mddev->cluster_info; + mddev->pers->quiesce (mddev,1 );spin_lock_irq (&cinfo->suspend_lock);__remove_suspend_info (cinfo, slot);spin_unlock_irq (&cinfo->suspend_lock); - mddev->pers->quiesce (mddev,2 ); + mddev->pers->quiesce (mddev,0 ); }
@@ -492,13 +493,12 @@ static void process_suspend_info(struct s->lo = lo; s->hi = hi; mddev->pers->quiesce (mddev,1 ); - mddev->pers->quiesce (mddev,0 );spin_lock_irq (&cinfo->suspend_lock);/* Remove existing entry (if exists) before adding */ __remove_suspend_info (cinfo, slot);list_add (&s->list, &cinfo->suspend_list);spin_unlock_irq (&cinfo->suspend_lock); - mddev->pers->quiesce (mddev,2 ); + mddev->pers->quiesce (mddev,0 ); }static void process_add_new_disk (struct mddev *mddev,struct cluster_msg *cmsg)
drivers/md/md.c +10 -24
@@ -4850,7 +4850,7 @@ suspend_lo_show(struct mddev *mddev, chastatic ssize_t suspend_lo_store (struct mddev *mddev,const char *buf,size_t len) { -unsigned long long old, new; +unsigned long long new;int err; err =kstrtoull (buf,10 , &new);
@@ -4866,17 +4866,10 @@ suspend_lo_store(struct mddev *mddev, coif (mddev->pers ==NULL || mddev->pers->quiesce ==NULL ) goto unlock; - old = mddev->suspend_lo; +mddev_suspend (mddev); mddev->suspend_lo = new; -if (new >= old) { -/* Shrinking suspended region */ -wake_up (&mddev->sb_wait); - mddev->pers->quiesce (mddev,2 ); - }else { -/* Expanding suspended region - need to wait */ -mddev_suspend (mddev); -mddev_resume (mddev); - } +mddev_resume (mddev); + err =0 ; unlock:mddev_unlock (mddev);
@@ -4894,7 +4887,7 @@ suspend_hi_show(struct mddev *mddev, chastatic ssize_t suspend_hi_store (struct mddev *mddev,const char *buf,size_t len) { -unsigned long long old, new; +unsigned long long new;int err; err =kstrtoull (buf,10 , &new);
@@ -4907,20 +4900,13 @@ suspend_hi_store(struct mddev *mddev, coif (err)return err; err = -EINVAL ; -if (mddev->pers ==NULL || - mddev->pers->quiesce ==NULL ) +if (mddev->pers ==NULL ) goto unlock; - old = mddev->suspend_hi; + +mddev_suspend (mddev); mddev->suspend_hi = new; -if (new <= old) { -/* Shrinking suspended region */ -wake_up (&mddev->sb_wait); - mddev->pers->quiesce (mddev,2 ); - }else { -/* Expanding suspended region - need to wait */ -mddev_suspend (mddev); -mddev_resume (mddev); - } +mddev_resume (mddev); + err =0 ; unlock:mddev_unlock (mddev);
drivers/md/md.h +4 -5
@@ -546,12 +546,11 @@ struct md_personalityint (*check_reshape) (struct mddev *mddev);int (*start_reshape) (struct mddev *mddev);void (*finish_reshape) (struct mddev *mddev); -/* quiesce moves between quiescence states -* 0 - fully active -* 1 - no new requests allowed -* others - reserved +/* quiesce suspends or resumes internal processing. +* 1 - stop new actions and wait for action io to complete +* 0 - return to normal behaviour */ -void (*quiesce) (struct mddev *mddev,int state); +void (*quiesce) (struct mddev *mddev,int quiesce);/* takeover is used to transition an array from one * personality to another. The new personality must be able * to handle the data in the current layout.
drivers/md/raid0.c +1 -1
@@ -768,7 +768,7 @@ static void *raid0_takeover(struct mddevreturn ERR_PTR (-EINVAL ); } -static void raid0_quiesce (struct mddev *mddev,int state) +static void raid0_quiesce (struct mddev *mddev,int quiesce) { }
drivers/md/raid1.c +3 -10
@@ -3276,21 +3276,14 @@ static int raid1_reshape(struct mddev *mreturn 0 ; } -static void raid1_quiesce (struct mddev *mddev,int state) +static void raid1_quiesce (struct mddev *mddev,int quiesce) {struct r1conf *conf = mddev->private; -switch (state) { -case 2 :/* wake for suspend */ -wake_up (&conf->wait_barrier); -break ; -case 1 : +if (quiesce)freeze_array (conf,0 ); -break ; -case 0 : +else unfreeze_array (conf); -break ; - } }static void *raid1_takeover (struct mddev *mddev)
drivers/md/raid10.c +3 -7
@@ -3838,18 +3838,14 @@ static void raid10_free(struct mddev *mdkfree (conf); } -static void raid10_quiesce (struct mddev *mddev,int state) +static void raid10_quiesce (struct mddev *mddev,int quiesce) {struct r10conf *conf = mddev->private; -switch (state) { -case 1 : +if (quiesce)raise_barrier (conf,0 ); -break ; -case 0 : +else lower_barrier (conf); -break ; - } }static int raid10_resize (struct mddev *mddev,sector_t sectors)
drivers/md/raid5-cache.c +6 -6
@@ -1589,21 +1589,21 @@ void r5l_wake_reclaim(struct r5l_log *lomd_wakeup_thread (log->reclaim_thread); } -void r5l_quiesce (struct r5l_log *log,int state) +void r5l_quiesce (struct r5l_log *log,int quiesce) {struct mddev *mddev; -if (!log || state ==2 ) +if (!log)return ; -if (state ==0 ) -kthread_unpark (log->reclaim_thread->tsk); -else if (state ==1 ) { + +if (quiesce) {/* make sure r5l_write_super_and_discard_space exits */ mddev = log->rdev->mddev;wake_up (&mddev->sb_wait);kthread_park (log->reclaim_thread->tsk);r5l_wake_reclaim (log, MaxSector);r5l_do_reclaim (log); - } + }else +kthread_unpark (log->reclaim_thread->tsk); }bool r5l_log_disk_error (struct r5conf *conf)
drivers/md/raid5-log.h +1 -1
@@ -9,7 +9,7 @@ extern void r5l_write_stripe_run(structextern void r5l_flush_stripe_to_raid (struct r5l_log *log);extern void r5l_stripe_write_finished (struct stripe_head *sh);extern int r5l_handle_flush_request (struct r5l_log *log,struct bio *bio); -extern void r5l_quiesce (struct r5l_log *log,int state); +extern void r5l_quiesce (struct r5l_log *log,int quiesce);extern bool r5l_log_disk_error (struct r5conf *conf);extern bool r5c_is_writeback (struct r5l_log *log); extern int
drivers/md/raid5.c +6 -12
@@ -8003,16 +8003,12 @@ static void raid5_finish_reshape(struct } } -static void raid5_quiesce (struct mddev *mddev,int state) +static void raid5_quiesce (struct mddev *mddev,int quiesce) {struct r5conf *conf = mddev->private; -switch (state) { -case 2 :/* resume for a suspend */ -wake_up (&conf->wait_for_overlap); -break ; - -case 1 :/* stop all writes */ +if (quiesce) { +/* stop all writes */ lock_all_device_hash_locks_irq (conf);/* '2' tells resync/reshape to pause so that all * active stripes can drain
@@ -8028,17 +8024,15 @@ static void raid5_quiesce(struct mddev *unlock_all_device_hash_locks_irq (conf);/* allow reshape to continue */ wake_up (&conf->wait_for_overlap); -break ; - -case 0 :/* re-enable writes */ + }else { +/* re-enable writes */ lock_all_device_hash_locks_irq (conf); conf->quiesce =0 ;wake_up (&conf->wait_for_quiescent);wake_up (&conf->wait_for_overlap);unlock_all_device_hash_locks_irq (conf); -break ; } -r5l_quiesce (conf->log, state); +r5l_quiesce (conf->log, quiesce); }static void *raid45_takeover_raid0 (struct mddev *mddev,int level)
Greg Kroah-Hartman
maintainerPATCH 40/61 netfilter: dont set F_IFACE on ipv6 fib lookups
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
commit 47b7e7f82802dced3ac73658bf4b77584a63063f upstream.
"fib" starts to behave strangely when an ipv6 default route is added - the FIB lookup returns a route using 'oif' in this case.
This behaviour was inherited from ip6tables rpfilter so change this as well.
Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1221
--- net/ipv6/netfilter/ip6t_rpfilter.c | 4 ---- net/ipv6/netfilter/nft_fib_ipv6.c | 12 ++---------- 2 files changed, 2 insertions(+), 14 deletions(-)
net/ipv6/netfilter/ip6t_rpfilter.c +0 -4
@@ -48,10 +48,6 @@ static bool rpfilter_lookup_reverse6(str } fl6.flowi6_mark = flags &XT_RPFILTER_VALID_MARK ? skb->mark :0 ; -if ((flags &XT_RPFILTER_LOOSE ) ==0 ) { - fl6.flowi6_oif = dev->ifindex; - lookup_flags |=RT6_LOOKUP_F_IFACE ; - } rt = (void *)ip6_route_lookup (net, &fl6, lookup_flags);if (rt->dst.error)
net/ipv6/netfilter/nft_fib_ipv6.c +2 -10
@@ -182,7 +182,6 @@ void nft_fib6_eval(const struct nft_expr } *dest =0 ; - again: rt = (void *)ip6_route_lookup (nft_net (pkt), &fl6, lookup_flags);if (rt->dst.error) goto put_rt_err;
@@ -191,15 +190,8 @@ void nft_fib6_eval(const struct nft_exprif (rt->rt6i_flags & (RTF_REJECT |RTF_ANYCAST |RTF_LOCAL )) goto put_rt_err; -if (oif && oif != rt->rt6i_idev->dev) { -/* multipath route? Try again with F_IFACE */ -if ((lookup_flags &RT6_LOOKUP_F_IFACE ) ==0 ) { - lookup_flags |=RT6_LOOKUP_F_IFACE ; - fl6.flowi6_oif = oif->ifindex; -ip6_rt_put (rt); - goto again; - } - } +if (oif && oif != rt->rt6i_idev->dev) + goto put_rt_err;switch (priv->result) {case NFT_FIB_RESULT_OIF :
Greg Kroah-Hartman
maintainerPATCH 41/61 netfilter: ip6t_rpfilter: provide input interface for route lookup
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Bernat <[email protected]>
commit cede24d1b21d68d84ac5a36c44f7d37daadcc258 upstream.
In commit 47b7e7f82802, this bit was removed at the same time the RT6_LOOKUP_F_IFACE flag was removed. However, it is needed when link-local addresses are used, which is a very common case: when packets are routed, neighbor solicitations are done using link-local addresses. For example, the following neighbor solicitation is not matched by "-m rpfilter":
IP6 fe80::5254:33ff:fe00:1 > ff02::1:ff00:3: ICMP6, neighbor
solicitation, who has 2001:db8::5254:33ff:fe00:3, length 32Commit 47b7e7f82802 doesn't quite explain why we shouldn't use RT6_LOOKUP_F_IFACE in the rpfilter case. I suppose the interface check later in the function would make it redundant. However, the remaining of the routing code is using RT6_LOOKUP_F_IFACE when there is no source address (which matches rpfilter's case with a non-unicast destination, like with neighbor solicitation).
--- net/ipv6/netfilter/ip6t_rpfilter.c | 2 ++ 1 file changed, 2 insertions(+)
net/ipv6/netfilter/ip6t_rpfilter.c +2 -0
@@ -48,6 +48,8 @@ static bool rpfilter_lookup_reverse6(str } fl6.flowi6_mark = flags &XT_RPFILTER_VALID_MARK ? skb->mark :0 ; +if ((flags &XT_RPFILTER_LOOSE ) ==0 ) + fl6.flowi6_oif = dev->ifindex; rt = (void *)ip6_route_lookup (net, &fl6, lookup_flags);if (rt->dst.error)
Greg Kroah-Hartman
maintainerPATCH 42/61 netfilter: nf_tables: use WARN_ON_ONCE instead of BUG_ON in nft_do_chain()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taehee Yoo <[email protected]>
commit adc972c5b88829d38ede08b1069718661c7330ae upstream.
When depth of chain is bigger than NFT_JUMP_STACK_SIZE, the nft_do_chain crashes. But there is no need to crash hard here.
--- net/netfilter/nf_tables_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_core.c +2 -1
@@ -208,7 +208,8 @@ next_rule:switch (regs.verdict.code) {case NFT_JUMP : -BUG_ON (stackptr >=NFT_JUMP_STACK_SIZE ); +if (WARN_ON_ONCE (stackptr >=NFT_JUMP_STACK_SIZE )) +return NF_DROP ; jumpstack[stackptr].chain = chain; jumpstack[stackptr].rule = rule; jumpstack[stackptr].rulenum = rulenum;
Greg Kroah-Hartman
maintainerPATCH 43/61 ARM: dts: imx6q: Use correct SDMA script for SPI5 core
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Nyekjaer <[email protected]>
commit df07101e1c4a29e820df02f9989a066988b160e6 upstream.
According to the reference manual the shp_2_mcu / mcu_2_shp scripts must be used for devices connected through the SPBA.
This fixes an issue we saw with DMA transfers. Sometimes the SPI controller RX FIFO was not empty after a DMA transfer and the driver got stuck in the next PIO transfer when it read one word more than expected.
commit dd4b487b32a35 ("ARM: dts: imx6: Use correct SDMA script for SPI cores") is fixing the same issue but only for SPI1 - 4.
--- arch/arm/boot/dts/imx6q.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/imx6q.dtsi +1 -1
@@ -96,7 +96,7 @@ clocks = <&clks IMX6Q_CLK_ECSPI5>, <&clks IMX6Q_CLK_ECSPI5>; clock-names = "ipg", "per"; - dmas = <&sdma 11 7 1>, <&sdma 12 7 2>; + dmas = <&sdma 11 8 1>, <&sdma 12 8 2>; dma-names = "rx", "tx"; status = "disabled"; };
Greg Kroah-Hartman
maintainerPATCH 44/61 mtd: rawnand: fix return value check for bad block status
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Sahu <[email protected]>
commit e9893e6fa932f42c90c4ac5849fa9aa0f0f00a34 upstream.
Positive return value from read_oob() is making false BAD blocks. For some of the NAND controllers, OOB bytes will be protected with ECC and read_oob() will return number of bitflips. If there is any bitflip in ECC protected OOB bytes for BAD block status page, then that block is getting treated as BAD.
--- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/nand_base.c +1 -1
@@ -440,7 +440,7 @@ static int nand_block_bad(struct mtd_inffor (; page < page_end; page++) { res = chip->ecc.read_oob (mtd, chip, page); -if (res) +if (res <0 )return res; bad = chip->oob_poi[chip->badblockpos];
Greg Kroah-Hartman
maintainerPATCH 46/61 afs: Fix directory permissions check
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 378831e4daec75fbba6d3612bcf3b4dd00ddbf08 ]
Doing faccessat("/afs/some/directory", 0) triggers a BUG in the permissions check code.
Fix this by just removing the BUG section. If no permissions are asked for, just return okay if the file exists.
Also:
(1) Split up the directory check so that it has separate if-statements rather than if-else-if (e.g. checking for MAY_EXEC shouldn't skip the check for MAY_READ and MAY_WRITE).
(2) Check for MAY_CHDIR as MAY_EXEC.
Without the main fix, the following BUG may occur:
kernel BUG at fs/afs/security.c:386!
invalid opcode: 0000 [#1] SMP PTI
...
RIP: 0010:afs_permission+0x19d/0x1a0 [kafs] ... Call Trace: ? inode_permission+0xbe/0x180 ? do_faccessat+0xdc/0x270 ? do_syscall_64+0x60/0x1f0 ? entry_SYSCALL_64_after_hwframe+0x49/0xbe
--- fs/afs/security.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
fs/afs/security.c +3 -7
@@ -323,18 +323,14 @@ int afs_permission(struct inode *inode, mask, access, S_ISDIR(inode->i_mode) ? "dir" : "file");if (S_ISDIR (inode->i_mode)) { -if (mask &MAY_EXEC ) { +if (mask & (MAY_EXEC |MAY_READ |MAY_CHDIR )) {if (!(access &AFS_ACE_LOOKUP )) goto permission_denied; - }else if (mask &MAY_READ ) { -if (!(access &AFS_ACE_LOOKUP )) - goto permission_denied; - }else if (mask &MAY_WRITE ) { + } +if (mask &MAY_WRITE ) {if (!(access & (AFS_ACE_DELETE |/* rmdir, unlink, rename from */ AFS_ACE_INSERT )))/* create, mkdir, symlink, rename to */ goto permission_denied; - }else { -BUG (); } }else {if (!(access &AFS_ACE_LOOKUP ))
Greg Kroah-Hartman
maintainerPATCH 47/61 netfilter: ebtables: handle string from userspace with care
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 94c752f99954797da583a84c4907ff19e92550a4 ]
strlcpy() can't be safely used on a user-space provided string, as it can try to read beyond the buffer's end, if the latter is not NULL terminated.
Leveraging the above, syzbot has been able to trigger the following splat:
BUG: KASAN: stack-out-of-bounds in strlcpy include/linux/string.h:300 [inline] BUG: KASAN: stack-out-of-bounds in compat_mtw_from_user net/bridge/netfilter/ebtables.c:1957 [inline] BUG: KASAN: stack-out-of-bounds in ebt_size_mwt net/bridge/netfilter/ebtables.c:2059 [inline] BUG: KASAN: stack-out-of-bounds in size_entry_mwt net/bridge/netfilter/ebtables.c:2155 [inline] BUG: KASAN: stack-out-of-bounds in compat_copy_entries+0x96c/0x14a0 net/bridge/netfilter/ebtables.c:2194 Write of size 33 at addr ffff8801b0abf888 by task syz-executor0/4504 CPU: 0 PID: 4504 Comm: syz-executor0 Not tainted 4.17.0-rc2+ #40 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1b9/0x294 lib/dump_stack.c:113 print_address_description+0x6c/0x20b mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412 check_memory_region_inline mm/kasan/kasan.c:260 [inline] check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267 memcpy+0x37/0x50 mm/kasan/kasan.c:303 strlcpy include/linux/string.h:300 [inline] compat_mtw_from_user net/bridge/netfilter/ebtables.c:1957 [inline] ebt_size_mwt net/bridge/netfilter/ebtables.c:2059 [inline] size_entry_mwt net/bridge/netfilter/ebtables.c:2155 [inline] compat_copy_entries+0x96c/0x14a0 net/bridge/netfilter/ebtables.c:2194 compat_do_replace+0x483/0x900 net/bridge/netfilter/ebtables.c:2285 compat_do_ebt_set_ctl+0x2ac/0x324 net/bridge/netfilter/ebtables.c:2367 compat_nf_sockopt net/netfilter/nf_sockopt.c:144 [inline] compat_nf_setsockopt+0x9b/0x140 net/netfilter/nf_sockopt.c:156 compat_ip_setsockopt+0xff/0x140 net/ipv4/ip_sockglue.c:1279 inet_csk_compat_setsockopt+0x97/0x120 net/ipv4/inet_connection_sock.c:1041 compat_tcp_setsockopt+0x49/0x80 net/ipv4/tcp.c:2901 compat_sock_common_setsockopt+0xb4/0x150 net/core/sock.c:3050 __compat_sys_setsockopt+0x1ab/0x7c0 net/compat.c:403 __do_compat_sys_setsockopt net/compat.c:416 [inline] __se_compat_sys_setsockopt net/compat.c:413 [inline] __ia32_compat_sys_setsockopt+0xbd/0x150 net/compat.c:413 do_syscall_32_irqs_on arch/x86/entry/common.c:323 [inline] do_fast_syscall_32+0x345/0xf9b arch/x86/entry/common.c:394 entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139 RIP: 0023:0xf7fb3cb9 RSP: 002b:00000000fff0c26c EFLAGS: 00000282 ORIG_RAX: 000000000000016e RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000000000 RDX: 0000000000000080 RSI: 0000000020000300 RDI: 00000000000005f4 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 The buggy address belongs to the page: page:ffffea0006c2afc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0 flags: 0x2fffc0000000000() raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff raw: 0000000000000000 ffffea0006c20101 0000000000000000 0000000000000000 page dumped because: kasan: bad access detected
Fix the issue replacing the unsafe function with strscpy() and taking care of possible errors.
--- net/bridge/netfilter/ebtables.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bridge/netfilter/ebtables.c +2 -1
@@ -1950,7 +1950,8 @@ static int compat_mtw_from_user(struct cint off, pad =0 ;unsigned int size_kern, match_size = mwt->match_size; -strlcpy (name, mwt->u.name,sizeof (name)); +if (strscpy (name, mwt->u.name,sizeof (name)) <0 ) +return -EINVAL ;if (state->buf_kern_start) dst = state->buf_kern_start + state->buf_kern_offset;
Greg Kroah-Hartman
maintainerPATCH 48/61 s390/dasd: use blk_mq_rq_from_pdu for per request data
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Ott <[email protected]>
[ Upstream commit f0f59a2fab8e52b9d582b39da39f22230ca80aee ]
Dasd uses completion_data from struct request to store per request private data - this is problematic since this member is part of a union which is also used by IO schedulers.
Let the block layer maintain space for per request data behind each struct request.
Fixes crashes on block layer timeouts like this one:
Unable to handle kernel pointer dereference in virtual kernel address space
Failing address: 0000000000000000 TEID: 0000000000000483
Fault in home space mode while using kernel ASCE.
AS:0000000001308007 R3:00000000fffc8007 S:00000000fffcc000 P:000000000000013d
Oops: 0004 ilc:2 [#1] PREEMPT SMP
Modules linked in: [...]
CPU: 0 PID: 1480 Comm: kworker/0:2H Not tainted 4.17.0-rc4-00046-gaa3bcd43b5af #203
Hardware name: IBM 3906 M02 702 (LPAR)
Workqueue: kblockd blk_mq_timeout_work
Krnl PSW : 0000000067ac406b 00000000b6960308 (do_raw_spin_trylock+0x30/0x78)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3
Krnl GPRS: 0000000000000c00 0000000000000000 0000000000000000 0000000000000001
0000000000b9d3c8 0000000000000000 0000000000000001 00000000cf9639d8
0000000000000000 0700000000000000 0000000000000000 000000000099f09e
0000000000000000 000000000076e9d0 000000006247bb08 000000006247bae0
Krnl Code: 00000000001c159c: b90400c2 lgr %r12,%r2
00000000001c15a0: a7180000 lhi %r1,0
#00000000001c15a4: 583003a4 l %r3,932
>00000000001c15a8: ba132000 cs %r1,%r3,0(%r2)
00000000001c15ac: a7180001 lhi %r1,1
00000000001c15b0: a784000b brc 8,1c15c6
00000000001c15b4: c0e5004e72aa brasl %r14,b8fb08
00000000001c15ba: 1812 lr %r1,%r2
Call Trace:
([<0700000000000000>] 0x700000000000000)
[<0000000000b9d3d2>] _raw_spin_lock_irqsave+0x7a/0xb8
[<000000000099f09e>] dasd_times_out+0x46/0x278
[<000000000076ea6e>] blk_mq_terminate_expired+0x9e/0x108
[<000000000077497a>] bt_for_each+0x102/0x130
[<0000000000774e54>] blk_mq_queue_tag_busy_iter+0x74/0xd8
[<000000000076fea0>] blk_mq_timeout_work+0x260/0x320
[<0000000000169dd4>] process_one_work+0x3bc/0x708
[<000000000016a382>] worker_thread+0x262/0x408
[<00000000001723a8>] kthread+0x160/0x178
[<0000000000b9e73a>] kernel_thread_starter+0x6/0xc
[<0000000000b9e734>] kernel_thread_starter+0x0/0xc
INFO: lockdep is turned off.
Last Breaking-Event-Address:
[<0000000000b9d3cc>] _raw_spin_lock_irqsave+0x74/0xb8
Kernel panic - not syncing: Fatal exception: panic_on_oops--- drivers/s390/block/dasd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/s390/block/dasd.c +5 -2
@@ -3049,7 +3049,8 @@ static blk_status_t do_dasd_request(stru cqr->callback_data = req; cqr->status =DASD_CQR_FILLED ; cqr->dq = dq; - req->completion_data = cqr; + *((struct dasd_ccw_req **)blk_mq_rq_to_pdu (req)) = cqr; +blk_mq_start_request (req);spin_lock (&block->queue_lock);list_add_tail (&cqr->blocklist, &block->ccw_queue);
@@ -3073,12 +3074,13 @@ out:*/ enum blk_eh_timer_return dasd_times_out (struct request *req,bool reserved) { -struct dasd_ccw_req *cqr = req->completion_data;struct dasd_block *block = req->q->queuedata;struct dasd_device *device; +struct dasd_ccw_req *cqr;unsigned long flags;int rc =0 ; + cqr = *((struct dasd_ccw_req **)blk_mq_rq_to_pdu (req));if (!cqr)return BLK_EH_NOT_HANDLED ;
@@ -3184,6 +3186,7 @@ static int dasd_alloc_queue(struct dasd_int rc; block->tag_set.ops = &dasd_mq_ops; + block->tag_set.cmd_size =sizeof (struct dasd_ccw_req *); block->tag_set.nr_hw_queues =DASD_NR_HW_QUEUES ; block->tag_set.queue_depth =DASD_MAX_LCU_DEV *DASD_REQ_PER_DEV ; block->tag_set.flags =BLK_MQ_F_SHOULD_MERGE ;
Greg Kroah-Hartman
maintainerPATCH 49/61 netfilter: nft_limit: fix packet ratelimiting
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 3e0f64b7dd3149f75e8652ff1df56cffeedc8fc1 ]
Credit calculations for the packet ratelimiting are not correct, as per the applied ratelimit of 25/second and burst 8, a total of 33 packets should have been accepted. This is true in iptables(33) but not in nftables (~65). For packet ratelimiting, use:
div_u64(limit->nsecs, limit->rate) * limit->burst;
to calculate credit, just like in iptables' xt_limit does.
Moreover, use default burst in iptables, users are expecting similar behaviour.
--- net/netfilter/nft_limit.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
net/netfilter/nft_limit.c +24 -14
@@ -51,10 +51,13 @@ static inline bool nft_limit_eval(structreturn !limit->invert; } +/* Use same default as in iptables. */ +#define NFT_LIMIT_PKT_BURST_DEFAULT 5 +static int nft_limit_init (struct nft_limit *limit, -const struct nlattr *const tb[]) +const struct nlattr *const tb[],bool pkts) { -u64 unit; +u64 unit, tokens;if (tb[NFTA_LIMIT_RATE ] ==NULL || tb[NFTA_LIMIT_UNIT ] ==NULL )
@@ -68,18 +71,25 @@ static int nft_limit_init(struct nft_limif (tb[NFTA_LIMIT_BURST ]) limit->burst =ntohl (nla_get_be32 (tb[NFTA_LIMIT_BURST ])); -else - limit->burst =0 ; + +if (pkts && limit->burst ==0 ) + limit->burst =NFT_LIMIT_PKT_BURST_DEFAULT ;if (limit->rate + limit->burst < limit->rate)return -EOVERFLOW ; -/* The token bucket size limits the number of tokens can be -* accumulated. tokens_max specifies the bucket size. -* tokens_max = unit * (rate + burst) / rate. -*/ - limit->tokens =div_u64 (limit->nsecs * (limit->rate + limit->burst), - limit->rate); +if (pkts) { + tokens =div_u64 (limit->nsecs, limit->rate) * limit->burst; + }else { +/* The token bucket size limits the number of tokens can be +* accumulated. tokens_max specifies the bucket size. +* tokens_max = unit * (rate + burst) / rate. +*/ + tokens =div_u64 (limit->nsecs * (limit->rate + limit->burst), + limit->rate); + } + + limit->tokens = tokens; limit->tokens_max = limit->tokens;if (tb[NFTA_LIMIT_FLAGS ]) {
@@ -144,7 +154,7 @@ static int nft_limit_pkts_init(const strstruct nft_limit_pkts *priv =nft_expr_priv (expr);int err; - err =nft_limit_init (&priv->limit, tb); + err =nft_limit_init (&priv->limit, tb, true);if (err <0 )return err;
@@ -185,7 +195,7 @@ static int nft_limit_bytes_init(const st {struct nft_limit *priv =nft_expr_priv (expr); -return nft_limit_init (priv, tb); +return nft_limit_init (priv, tb, false); } static int nft_limit_bytes_dump(struct sk_buff *skb,
@@ -246,7 +256,7 @@ static int nft_limit_obj_pkts_init(conststruct nft_limit_pkts *priv =nft_obj_data (obj);int err; - err =nft_limit_init (&priv->limit, tb); + err =nft_limit_init (&priv->limit, tb, true);if (err <0 )return err;
@@ -289,7 +299,7 @@ static int nft_limit_obj_bytes_init(cons {struct nft_limit *priv =nft_obj_data (obj); -return nft_limit_init (priv, tb); +return nft_limit_init (priv, tb, false); } static int nft_limit_obj_bytes_dump(struct sk_buff *skb,
Greg Kroah-Hartman
maintainerPATCH 50/61 ipvs: fix buffer overflow with sync daemon and service
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julian Anastasov <[email protected]>
[ Upstream commit 52f96757905bbf0edef47f3ee6c7c784e7f8ff8a ]
syzkaller reports for buffer overflow for interface name when starting sync daemons [1]
What we do is that we copy user structure into larger stack buffer but later we search NUL past the stack buffer. The same happens for sched_name when adding/editing virtual server.
We are restricted by IP_VS_SCHEDNAME_MAXLEN and IP_VS_IFNAME_MAXLEN being used as size in include/uapi/linux/ip_vs.h, so they include the space for NUL.
As using strlcpy is wrong for unsafe source, replace it with strscpy and add checks to return EINVAL if source string is not NUL-terminated. The incomplete strlcpy fix comes from 2.6.13.
For the netlink interface reduce the len parameter for IPVS_DAEMON_ATTR_MCAST_IFN and IPVS_SVC_ATTR_SCHED_NAME, so that we get proper EINVAL.
[1]
kernel BUG at lib/string.c:1052!
invalid opcode: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
(ftrace buffer empty)
Modules linked in: CPU: 1 PID: 373 Comm: syz-executor936 Not tainted 4.17.0-rc4+ #45 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 RIP: 0010:fortify_panic+0x13/0x20 lib/string.c:1051 RSP: 0018:ffff8801c976f800 EFLAGS: 00010282 RAX: 0000000000000022 RBX: 0000000000000040 RCX: 0000000000000000 RDX: 0000000000000022 RSI: ffffffff8160f6f1 RDI: ffffed00392edef6 RBP: ffff8801c976f800 R08: ffff8801cf4c62c0 R09: ffffed003b5e4fb0 R10: ffffed003b5e4fb0 R11: ffff8801daf27d87 R12: ffff8801c976fa20 R13: ffff8801c976fae4 R14: ffff8801c976fae0 R15: 000000000000048b FS: 00007fd99f75e700(0000) GS:ffff8801daf00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000200001c0 CR3: 00000001d6843000 CR4: 00000000001406e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: strlen include/linux/string.h:270 [inline] strlcpy include/linux/string.h:293 [inline] do_ip_vs_set_ctl+0x31c/0x1d00 net/netfilter/ipvs/ip_vs_ctl.c:2388 nf_sockopt net/netfilter/nf_sockopt.c:106 [inline] nf_setsockopt+0x7d/0xd0 net/netfilter/nf_sockopt.c:115 ip_setsockopt+0xd8/0xf0 net/ipv4/ip_sockglue.c:1253 udp_setsockopt+0x62/0xa0 net/ipv4/udp.c:2487 ipv6_setsockopt+0x149/0x170 net/ipv6/ipv6_sockglue.c:917 tcp_setsockopt+0x93/0xe0 net/ipv4/tcp.c:3057 sock_common_setsockopt+0x9a/0xe0 net/core/sock.c:3046 __sys_setsockopt+0x1bd/0x390 net/socket.c:1903 __do_sys_setsockopt net/socket.c:1914 [inline] __se_sys_setsockopt net/socket.c:1911 [inline] __x64_sys_setsockopt+0xbe/0x150 net/socket.c:1911 do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x447369 RSP: 002b:00007fd99f75dda8 EFLAGS: 00000246 ORIG_RAX: 0000000000000036 RAX: ffffffffffffffda RBX: 00000000006e39e4 RCX: 0000000000447369 RDX: 000000000000048b RSI: 0000000000000000 RDI: 0000000000000003 RBP: 0000000000000000 R08: 0000000000000018 R09: 0000000000000000 R10: 00000000200001c0 R11: 0000000000000246 R12: 00000000006e39e0 R13: 75a1ff93f0896195 R14: 6f745f3168746576 R15: 0000000000000001 Code: 08 5b 41 5c 41 5d 41 5e 41 5f 5d c3 0f 0b 48 89 df e8 d2 8f 48 fa eb de 55 48 89 fe 48 c7 c7 60 65 64 88 48 89 e5 e8 91 dd f3 f9 <0f> 0b 90 90 90 90 90 90 90 90 90 90 90 55 48 89 e5 41 57 41 56 RIP: fortify_panic+0x13/0x20 lib/string.c:1051 RSP: ffff8801c976f800
--- net/netfilter/ipvs/ip_vs_ctl.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
net/netfilter/ipvs/ip_vs_ctl.c +15 -6
@@ -2384,8 +2384,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmstruct ipvs_sync_daemon_cfg cfg;memset (&cfg,0 ,sizeof (cfg)); -strlcpy (cfg.mcast_ifn, dm->mcast_ifn, -sizeof (cfg.mcast_ifn)); + ret = -EINVAL ; +if (strscpy (cfg.mcast_ifn, dm->mcast_ifn, +sizeof (cfg.mcast_ifn)) <=0 ) + goto out_dec; cfg.syncid = dm->syncid; ret =start_sync_thread (ipvs, &cfg, dm->state); }else {
@@ -2423,12 +2425,19 @@ do_ip_vs_set_ctl(struct sock *sk, int cm } } +if ((cmd ==IP_VS_SO_SET_ADD || cmd ==IP_VS_SO_SET_EDIT ) && +strnlen (usvc.sched_name,IP_VS_SCHEDNAME_MAXLEN ) == +IP_VS_SCHEDNAME_MAXLEN ) { + ret = -EINVAL ; + goto out_unlock; + } +/* Check for valid protocol: TCP or UDP or SCTP, even for fwmark!=0 */ if (usvc.protocol !=IPPROTO_TCP && usvc.protocol !=IPPROTO_UDP && usvc.protocol !=IPPROTO_SCTP ) { -pr_err ("set_ctl: invalid protocol: %d %pI4:%d %s\n" , +pr_err ("set_ctl: invalid protocol: %d %pI4:%d\n" , usvc.protocol, &usvc.addr.ip, -ntohs (usvc.port), usvc.sched_name); +ntohs (usvc.port)); ret = -EFAULT ; goto out_unlock; }
@@ -2850,7 +2859,7 @@ static const struct nla_policy ip_vs_cmdstatic const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX +1 ] = { [IPVS_DAEMON_ATTR_STATE ] = { .type =NLA_U32 }, [IPVS_DAEMON_ATTR_MCAST_IFN ] = { .type =NLA_NUL_STRING , - .len =IP_VS_IFNAME_MAXLEN }, + .len =IP_VS_IFNAME_MAXLEN -1 }, [IPVS_DAEMON_ATTR_SYNC_ID ] = { .type =NLA_U32 }, [IPVS_DAEMON_ATTR_SYNC_MAXLEN ] = { .type =NLA_U16 }, [IPVS_DAEMON_ATTR_MCAST_GROUP ] = { .type =NLA_U32 },
@@ -2868,7 +2877,7 @@ static const struct nla_policy ip_vs_svc [IPVS_SVC_ATTR_PORT] = { .type = NLA_U16 }, [IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 }, [IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING, - .len = IP_VS_SCHEDNAME_MAXLEN }, + .len = IP_VS_SCHEDNAME_MAXLEN - 1 }, [IPVS_SVC_ATTR_PE_NAME] = { .type = NLA_NUL_STRING, .len = IP_VS_PENAME_MAXLEN }, [IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY,
Greg Kroah-Hartman
maintainerPATCH 51/61 iwlwifi: pcie: compare with number of IRQs requested for, not number of CPUs
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hao Wei Tee <[email protected]>
[ Upstream commit ab1068d6866e28bf6427ceaea681a381e5870a4a ]
When there are 16 or more logical CPUs, we request for IWL_MAX_RX_HW_QUEUES (16) IRQs only as we limit to that number of IRQs, but later on we compare the number of IRQs returned to nr_online_cpus+2 instead of max_irqs, the latter being what we actually asked for. This ends up setting num_rx_queues to 17 which causes lots of out-of-bounds array accesses later on.
Compare to max_irqs instead, and also add an assertion in case num_rx_queues > IWM_MAX_RX_HW_QUEUES.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=199551
--- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/wireless/intel/iwlwifi/pcie/trans.c +5 -5
@@ -1499,14 +1499,13 @@ static void iwl_pcie_set_interrupt_capa( struct iwl_trans *trans) {struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans); -int max_irqs, num_irqs, i, ret, nr_online_cpus; +int max_irqs, num_irqs, i, ret;u16 pci_cmd;if (!trans->cfg->mq_rx_supported) goto enable_msi; - nr_online_cpus =num_online_cpus (); - max_irqs =min_t (u32, nr_online_cpus +2 ,IWL_MAX_RX_HW_QUEUES ); + max_irqs =min_t (u32,num_online_cpus () +2 ,IWL_MAX_RX_HW_QUEUES );for (i =0 ; i < max_irqs; i++) trans_pcie->msix_entries[i].entry = i;
@@ -1532,16 +1531,17 @@ static void iwl_pcie_set_interrupt_capa(* Two interrupts less: non rx causes shared with FBQ and RSS. * More than two interrupts: we will use fewer RSS queues. */ -if (num_irqs <= nr_online_cpus) { +if (num_irqs <= max_irqs -2 ) { trans_pcie->trans->num_rx_queues = num_irqs +1 ; trans_pcie->shared_vec_mask =IWL_SHARED_IRQ_NON_RX |IWL_SHARED_IRQ_FIRST_RSS ; - }else if (num_irqs == nr_online_cpus +1 ) { + }else if (num_irqs == max_irqs -1 ) { trans_pcie->trans->num_rx_queues = num_irqs; trans_pcie->shared_vec_mask =IWL_SHARED_IRQ_NON_RX ; }else { trans_pcie->trans->num_rx_queues = num_irqs -1 ; } +WARN_ON (trans_pcie->trans->num_rx_queues >IWL_MAX_RX_HW_QUEUES ); trans_pcie->alloc_vecs = num_irqs; trans_pcie->msix_enabled = true;
Greg Kroah-Hartman
maintainerPATCH 52/61 atm: zatm: fix memcmp casting
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Bornyakov <[email protected]>
[ Upstream commit f9c6442a8f0b1dde9e755eb4ff6fa22bcce4eabc ]
memcmp() returns int, but eprom_try_esi() cast it to unsigned char. One can lose significant bits and get 0 from non-0 value returned by the memcmp().
--- drivers/atm/zatm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/atm/zatm.c +2 -2
@@ -1151,8 +1151,8 @@ static void eprom_get_byte(struct zatm_d } -static unsigned char eprom_try_esi (struct atm_dev *dev,unsigned short cmd, -int offset,int swap) +static int eprom_try_esi (struct atm_dev *dev,unsigned short cmd,int offset, +int swap) {unsigned char buf[ZEPROM_SIZE ];struct zatm_dev *zatm_dev;
Greg Kroah-Hartman
maintainerPATCH 54/61 perf test: "Session topology" dumps core on s390
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <[email protected]>
[ Upstream commit d121109100bda84bbbb199dab97f9d56432ab235 ]
The "perf test Session topology" entry fails with core dump on s390. The root cause is a NULL pointer dereference in function check_cpu_topology() line 76 (or line 82 without -v).
The session->header.env.cpu variable is NULL because on s390 function process_cpu_topology() returns with error:
socket_id number is too big.
You may need to upgrade the perf tool.
and releases the env.cpu variable via zfree() and sets it to NULL.
Here is the gdb output:
(gdb) n
76 pr_debug("CPU %d, core %d, socket %d\n", i,
(gdb) n
Program received signal SIGSEGV, Segmentation fault. 0x00000000010f4d9e in check_cpu_topology (path=0x3ffffffd6c8
"/tmp/perf-test-J6CHMa", map=0x14a1740) at tests/topology.c:76
76 pr_debug("CPU %d, core %d, socket %d\n", i,
(gdb)
Make sure the env.cpu variable is not used when its NULL. Test for NULL pointer and return TEST_SKIP if so.
Output before:
[root@p23lp27 perf]# ./perf test -F 39
39: Session topology :Segmentation fault (core dumped) [root@p23lp27 perf]#
Output after:
[root@p23lp27 perf]# ./perf test -vF 39
39: Session topology :
--- start ---
templ file: /tmp/perf-test-Ajx59D
socket_id number is too big.You may need to upgrade the perf tool. ---- end ----
Session topology: Skip
[root@p23lp27 perf]#
--- tools/perf/tests/topology.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)
tools/perf/tests/topology.c +24 -6
@@ -66,6 +66,27 @@ static int check_cpu_topology(char *path session =perf_session__new (&file, false,NULL );TEST_ASSERT_VAL ("can't get session" , session); +/* On platforms with large numbers of CPUs process_cpu_topology() +* might issue an error while reading the perf.data file section +* HEADER_CPU_TOPOLOGY and the cpu_topology_map pointed to by member +* cpu is a NULL pointer. +* Example: On s390 +* CPU 0 is on core_id 0 and physical_package_id 6 +* CPU 1 is on core_id 1 and physical_package_id 3 +* +* Core_id and physical_package_id are platform and architecture +* dependend and might have higher numbers than the CPU id. +* This actually depends on the configuration. +* +* In this case process_cpu_topology() prints error message: +* "socket_id number is too big. You may need to upgrade the +* perf tool." +* +* This is the reason why this test might be skipped. +*/ +if (!session->header.env.cpu) +return TEST_SKIP ; +for (i =0 ; i < session->header.env.nr_cpus_avail; i++) {if (!cpu_map__has (map, i))continue ;
@@ -91,7 +112,7 @@ int test__session_topology(struct test * {char path[PATH_MAX ];struct cpu_map *map; -int ret =-1 ; +int ret =TEST_FAIL ;TEST_ASSERT_VAL ("can't get templ file" , !get_temp (path));
@@ -106,12 +127,9 @@ int test__session_topology(struct test * goto free_path; } -if (check_cpu_topology (path, map)) - goto free_map; - ret =0 ; - -free_map: + ret =check_cpu_topology (path, map);cpu_map__put (map); + free_path:unlink (path);return ret;
Greg Kroah-Hartman
maintainerPATCH 55/61 perf bpf: Fix NULL return handling in bpf__prepare_load()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: YueHaibing <[email protected]>
[ Upstream commit ab4e32ff5aa797eaea551dbb67946e2fcb56cc7e ]
bpf_object__open()/bpf_object__open_buffer can return error pointer or NULL, check the return values with IS_ERR_OR_NULL() in bpf__prepare_load and bpf__prepare_load_buffer
--- tools/perf/util/bpf-loader.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/util/bpf-loader.c +3 -3
@@ -66,7 +66,7 @@ bpf__prepare_load_buffer(void *obj_buf, } obj =bpf_object__open_buffer (obj_buf, obj_buf_sz, name); -if (IS_ERR (obj)) { +if (IS_ERR_OR_NULL (obj)) {pr_debug ("bpf: failed to load buffer\n" );return ERR_PTR (-EINVAL ); }
@@ -102,14 +102,14 @@ struct bpf_object *bpf__prepare_load(conpr_debug ("bpf: successfull builtin compilation\n" ); obj =bpf_object__open_buffer (obj_buf, obj_buf_sz, filename); -if (!IS_ERR (obj) && llvm_param.dump_obj) +if (!IS_ERR_OR_NULL (obj) && llvm_param.dump_obj)llvm__dump_obj (filename, obj_buf, obj_buf_sz);free (obj_buf); }else obj =bpf_object__open (filename); -if (IS_ERR (obj)) { +if (IS_ERR_OR_NULL (obj)) {pr_debug ("bpf: failed to load %s\n" , filename);return obj; }
Greg Kroah-Hartman
maintainerPATCH 56/61 fs: clear writeback errors in inode_init_always
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Darrick J. Wong" <[email protected]>
[ Upstream commit 829bc787c1a0403e4d886296dd4d90c5f9c1744a ]
In inode_init_always(), we clear the inode mapping flags, which clears any retained error (AS_EIO, AS_ENOSPC) bits. Unfortunately, we do not also clear wb_err, which means that old mapping errors can leak through to new inodes.
This is crucial for the XFS inode allocation path because we recycle old in-core inodes and we do not want error state from an old file to leak into the new file. This bug was discovered by running generic/036 and generic/047 in a loop and noticing that the EIOs generated by the collision of direct and buffered writes in generic/036 would survive the remount between 036 and 047, and get reported to the fsyncs (on different files!) in generic/047.
--- fs/inode.c | 1 + 1 file changed, 1 insertion(+)
fs/inode.c +1 -0
@@ -177,6 +177,7 @@ int inode_init_always(struct super_block mapping->a_ops = &empty_aops; mapping->host = inode; mapping->flags =0 ; + mapping->wb_err =0 ;atomic_set (&mapping->i_mmap_writable,0 );mapping_set_gfp_mask (mapping,GFP_HIGHUSER_MOVABLE ); mapping->private_data =NULL ;
Greg Kroah-Hartman
maintainerPATCH 57/61 sched/core: Fix rules for running on online && !active CPUs
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 175f0e25abeaa2218d431141ce19cf1de70fa82d ]
As already enforced by the WARN() in __set_cpus_allowed_ptr(), the rules for running on an online && !active CPU are stricter than just being a kthread, you need to be a per-cpu kthread.
If you're not strictly per-CPU, you have better CPUs to run on and don't need the partially booted one to get your work done.
The exception is to allow smpboot threads to bootstrap the CPU itself and get kernel 'services' initialized before we allow userspace on it.
--- kernel/sched/core.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-)
kernel/sched/core.c +30 -12
@@ -894,6 +894,33 @@ void check_preempt_curr(struct rq *rq, s }#ifdef CONFIG_SMP + +static inline bool is_per_cpu_kthread (struct task_struct *p) +{ +if (!(p->flags &PF_KTHREAD )) +return false; + +if (p->nr_cpus_allowed !=1 ) +return false; + +return true; +} + +/* +* Per-CPU kthreads are allowed to run on !actie && online CPUs, see +* __set_cpus_allowed_ptr() and select_fallback_rq(). +*/ +static inline bool is_cpu_allowed (struct task_struct *p,int cpu) +{ +if (!cpumask_test_cpu (cpu, &p->cpus_allowed)) +return false; + +if (is_per_cpu_kthread (p)) +return cpu_online (cpu); + +return cpu_active (cpu); +} +/* * This is how migration works: *
@@ -951,16 +978,8 @@ struct migration_arg {static struct rq *__migrate_task (struct rq *rq,struct rq_flags *rf,struct task_struct *p,int dest_cpu) { -if (p->flags &PF_KTHREAD ) { -if (unlikely (!cpu_online (dest_cpu))) -return rq; - }else { -if (unlikely (!cpu_active (dest_cpu))) -return rq; - } -/* Affinity changed (again). */ -if (!cpumask_test_cpu (dest_cpu, &p->cpus_allowed)) +if (!is_cpu_allowed (p, dest_cpu))return rq;update_rq_clock (rq);
@@ -1489,10 +1508,9 @@ static int select_fallback_rq(int cpu, sfor (;;) {/* Any allowed, online CPU? */ for_each_cpu (dest_cpu, &p->cpus_allowed) { -if (!(p->flags &PF_KTHREAD ) && !cpu_active (dest_cpu)) -continue ; -if (!cpu_online (dest_cpu)) +if (!is_cpu_allowed (p, dest_cpu))continue ; + goto out; }
Greg Kroah-Hartman
maintainerPATCH 58/61 sched/core: Require cpu_active() in select_task_rq(), for user tasks
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Burton <[email protected]>
[ Upstream commit 7af443ee1697607541c6346c87385adab2214743 ]
select_task_rq() is used in a few paths to select the CPU upon which a thread should be run - for example it is used by try_to_wake_up() & by fork or exec balancing. As-is it allows use of any online CPU that is present in the task's cpus_allowed mask.
This presents a problem because there is a period whilst CPUs are brought online where a CPU is marked online, but is not yet fully initialized - ie. the period where CPUHP_AP_ONLINE_IDLE <= state < CPUHP_ONLINE. Usually we don't run any user tasks during this window, but there are corner cases where this can happen. An example observed is:
- Some user task A, running on CPU X, forks to create task B.
- sched_fork() calls __set_task_cpu() with cpu=X, setting task B's task_struct::cpu field to X.
- CPU X is offlined.
- Task A, currently somewhere between the __set_task_cpu() in copy_process() and the call to wake_up_new_task(), is migrated to CPU Y by migrate_tasks() when CPU X is offlined.
- CPU X is onlined, but still in the CPUHP_AP_ONLINE_IDLE state. The scheduler is now active on CPU X, but there are no user tasks on the runqueue.
- Task A runs on CPU Y & reaches wake_up_new_task(). This calls select_task_rq() with cpu=X, taken from task B's task_struct, and select_task_rq() allows CPU X to be returned.
- Task A enqueues task B on CPU X's runqueue, via activate_task() &
enqueue_task().
- CPU X now has a user task on its runqueue before it has reached the CPUHP_ONLINE state.
In most cases, the user tasks that schedule on the newly onlined CPU have no idea that anything went wrong, but one case observed to be problematic is if the task goes on to invoke the sched_setaffinity syscall. The newly onlined CPU reaches the CPUHP_AP_ONLINE_IDLE state before the CPU that brought it online calls stop_machine_unpark(). This means that for a portion of the window of time between CPUHP_AP_ONLINE_IDLE & CPUHP_ONLINE the newly onlined CPU's struct cpu_stopper has its enabled field set to false. If a user thread is executed on the CPU during this window and it invokes sched_setaffinity with a CPU mask that does not include the CPU it's running on, then when __set_cpus_allowed_ptr() calls stop_one_cpu() intending to invoke migration_cpu_stop() and perform the actual migration away from the CPU it will simply return -ENOENT rather than calling migration_cpu_stop(). We then return from the sched_setaffinity syscall back to the user task that is now running on a CPU which it just asked not to run on, and which is not present in its cpus_allowed mask.
This patch resolves the problem by having select_task_rq() enforce that user tasks run on CPUs that are active - the same requirement that select_fallback_rq() already enforces. This should ensure that newly onlined CPUs reach the CPUHP_AP_ACTIVE state before being able to schedule user tasks, and also implies that bringup_wait_for_ap() will have called stop_machine_unpark() which resolves the sched_setaffinity issue above.
I haven't yet investigated them, but it may be of interest to review whether any of the actions performed by hotplug states between CPUHP_AP_ONLINE_IDLE & CPUHP_AP_ACTIVE could have similar unintended effects on user tasks that might schedule before they are reached, which might widen the scope of the problem from just affecting the behaviour of sched_setaffinity.
--- kernel/sched/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/sched/core.c +1 -2
@@ -1573,8 +1573,7 @@ int select_task_rq(struct task_struct *p* [ this allows ->select_task() to simply return task_cpu(p) and * not worry about this generic constraint ] */ -if (unlikely (!cpumask_test_cpu (cpu, &p->cpus_allowed) || - !cpu_online (cpu))) +if (unlikely (!is_cpu_allowed (p, cpu))) cpu =select_fallback_rq (task_cpu (p), p);return cpu;
Greg Kroah-Hartman
maintainerPATCH 60/61 net/sonic: Use dma_mapping_error()
In reply to Greg Kroah-Hartman4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Thain <[email protected]>
[ Upstream commit 26de0b76d9ba3200f09c6cb9d9618bda338be5f7 ]
With CONFIG_DMA_API_DEBUG=y, calling sonic_open() produces the message, "DMA-API: device driver failed to check map error". Add the missing dma_mapping_error() call.
--- drivers/net/ethernet/natsemi/sonic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/natsemi/sonic.c +1 -1
@@ -71,7 +71,7 @@ static int sonic_open(struct net_devicefor (i =0 ; i <SONIC_NUM_RRS ; i++) {dma_addr_t laddr =dma_map_single (lp->device,skb_put (lp->rx_skb[i],SONIC_RBSIZE ),SONIC_RBSIZE ,DMA_FROM_DEVICE ); -if (!laddr) { +if (dma_mapping_error (lp->device, laddr)) {while (i >0 ) {/* free any that were mapped successfully */ i--;dma_unmap_single (lp->device, lp->rx_laddr[i],SONIC_RBSIZE ,DMA_FROM_DEVICE );
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.54 release. There are 61 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.
Results from Linaro’s test farm.
No regressions on arm64, arm and x86_64.
Summary
------------------------------------------------------------------------
kernel: 4.14.54-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.14.y
git commit: f0c73a14ce42af51660f44259cca95e19193ed38
git describe: v4.14.53-62-gf0c73a14ce42
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-4.14-oe/build/v4.14.53-62-gf0c73a14ce42
No regressions (compared to build v4.14.53-62-g70a54698ad0b)
Ran 16444 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-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-nptl-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-timers-tests
* ltp-cap_bounds-tests
* ltp-containers-tests
* ltp-math-tests
* ltp-open-posix-tests
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.54 release. There are 61 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun Jul 8 05:46:58 UTC 2018. Anything received after that time might be too late.
Build results:
total: 148 pass: 148 fail: 0 Qemu test results: total: 160 pass: 160 fail: 0`
Details are available at http://kerneltests.org/builders.
Guenter
Greg Kroah-Hartman
maintainerQuoted 6 lines · Guenter Roeck
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.54 release. There are 61 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.
Quoted 8 lines
Quoted 3 lines
Responses should be made by Sun Jul 8 05:46:58 UTC 2018. Anything received after that time might be too late.
Build results:
total: 148 pass: 148 fail: 0 Qemu test results: total: 160 pass: 160 fail: 0`
"0`"? :)
Anyway, thanks for testing both of these and letting me know.
greg k-h
Quoted 11 lines · Greg Kroah-Hartman
Quoted 10 lines · Guenter Roeck
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 4.14.54 release. There are 61 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sun Jul 8 05:46:58 UTC 2018. Anything received after that time might be too late.
Quoted 7 lines
Quoted 4 lines
Build results:
total: 148 pass: 148 fail: 0 Qemu test results: total: 160 pass: 160 fail: 0`"0`"? :)
Long live cut-and-paste. Still have not managed to automate sending those e-mails.
Guenter
Quoted 3 lines
Anyway, thanks for testing both of these and letting me know.
greg k-h