Skip to contentSkip to conversation

4.14.305-rc1 review

PATCH In review Greg Kroah-Hartman 3 participants 65 messages Feb 3, 2023 – Feb 4, 2023

Subsystems (4)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 4.14.305-rc1 review

This is the start of the stable review cycle for the 4.14.305 release. There are 62 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, 05 Feb 2023 10:09:58 +0000. 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.305-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.305-rc1

Peter Chen <[email protected]>
usb: host: xhci-plat: add wakeup entry at sysfs

Eric Dumazet <[email protected]>
ipv6: ensure sane device mtu in tunnels

Michal Hocko <[email protected]>
mm: kvmalloc does not fallback to vmalloc for incompatible gfp flags

Kees Cook <[email protected]>
exit: Use READ_ONCE() for all oops/warn limit reads

Kees Cook <[email protected]>
docs: Fix path paste-o for /sys/kernel/warn_count

Kees Cook <[email protected]>
panic: Expose "warn_count" to sysfs

Kees Cook <[email protected]>
panic: Introduce warn_limit

Kees Cook <[email protected]>
panic: Consolidate open-coded panic_on_warn checks

Kees Cook <[email protected]>
exit: Allow oops_limit to be disabled

Kees Cook <[email protected]>
exit: Expose "oops_count" to sysfs

Jann Horn <[email protected]>
exit: Put an upper limit on how often we can oops

Randy Dunlap <[email protected]>
ia64: make IA64_MCA_RECOVERY bool instead of tristate

Nathan Chancellor <[email protected]>
h8300: Fix build errors from do_exit() to make_task_dead() transition

Nathan Chancellor <[email protected]>
hexagon: Fix function name in die()

Eric W. Biederman <[email protected]>
objtool: Add a missing comma to avoid string concatenation

Eric W. Biederman <[email protected]>
exit: Add and use make_task_dead.

Tiezhu Yang <[email protected]>
panic: unset panic_on_warn inside panic()

Xiaoming Ni <[email protected]>
sysctl: add a new register_sysctl_init() interface

Jan Beulich <[email protected]>
x86/entry/64: Add instruction suffix to SYSRET

Mikulas Patocka <[email protected]>
x86/asm: Fix an assembler warning with current binutils

Christoph Hellwig <[email protected]>
scsi: qla2xxx: don't break the bsg-lib abstractions

Alex Deucher <[email protected]>
drm/radeon/dp: make radeon_dp_get_dp_link_config static

Greg Kroah-Hartman <[email protected]>
xen: Fix up build warning with xen_init_time_ops() reference

Greg Kroah-Hartman <[email protected]>
wifi: brcmfmac: fix up incorrect 4.14.y backport for brcmf_fw_map_chip_to_name()

Thomas Gleixner <[email protected]>
x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL

Dmitry Torokhov <[email protected]>
Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode"

David Christensen <[email protected]>
net/tg3: resolve deadlock in tg3_reset_task() during EEH

Yoshihiro Shimoda <[email protected]>
net: ravb: Fix possible hang if RIS2_QFF1 happen

Marcelo Ricardo Leitner <[email protected]>
sctp: fail if no bound addresses can be used for a given scope

Kuniyuki Iwashima <[email protected]>
netrom: Fix use-after-free of a listening socket.

Sriram Yagnaraman <[email protected]>
netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE

Eric Dumazet <[email protected]>
netlink: annotate data races around sk_state

Eric Dumazet <[email protected]>
netlink: annotate data races around dst_portid and dst_group

Manivannan Sadhasivam <[email protected]>
EDAC/device: Respect any driver-supplied workqueue polling value

Giulio Benetti <[email protected]>
ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment

Steven Rostedt (Google) <[email protected]>
tracing: Make sure trace_printk() can output as soon as it can be used

Petr Pavlu <[email protected]>
module: Don't wait for GOING modules

Alexey V. Vissarionov <[email protected]>
scsi: hpsa: Fix allocation size for scsi_host_alloc()

Archie Pusaka <[email protected]>
Bluetooth: hci_sync: cancel cmd_timer if hci_open failed

Dongliang Mu <[email protected]>
fs: reiserfs: remove useless new_opts in reiserfs_remount

Ian Abbott <[email protected]>
comedi: adv_pci1760: Fix PWM instruction handling

Yang Yingliang <[email protected]>
w1: fix WARNING after calling w1_process()

Yang Yingliang <[email protected]>
w1: fix deadloop in __w1_remove_master_device()

Pietro Borrello <[email protected]>
HID: betop: check shape of output reports

Koba Ko <[email protected]>
dmaengine: Fix double increment of client_count in dma_chan_get()

Randy Dunlap <[email protected]>
net: mlx5: eliminate anonymous module_init & module_exit

Udipto Goswami <[email protected]>
usb: gadget: f_fs: Ensure ep0req is dequeued before free_request

Udipto Goswami <[email protected]>
usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait

Pietro Borrello <[email protected]>
HID: check empty report_list in hid_validate_values()

Heiner Kallweit <[email protected]>
net: mdio: validate parameter addr in mdiobus_get_phy()

Szymon Heidrich <[email protected]>
net: usb: sr9700: Handle negative len

Szymon Heidrich <[email protected]>
wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid

Jisoo Jang <[email protected]>
net: nfc: Fix use-after-free in local_cleanup()

Shang XiaoJing <[email protected]>
phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on()

Raju Rangoju <[email protected]>
amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent

Alexander Potapenko <[email protected]>
affs: initialize fsdata in affs_truncate()

Dean Luick <[email protected]>
IB/hfi1: Reserve user expected TIDs

Dean Luick <[email protected]>
IB/hfi1: Reject a zero-length user expected buffer

Masahiro Yamada <[email protected]>
tomoyo: fix broken dependency on *.conf.default

Miaoqian Lin <[email protected]>
EDAC/highbank: Fix memory leak in highbank_mc_probe()

Jiasheng Jiang <[email protected]>
HID: intel_ish-hid: Add check for ishtp_dma_tx_map

Fabio Estevam <[email protected]>

    ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts'

-------------

Diffstat:

 Documentation/ABI/testing/sysfs-kernel-oops_count  |  6 ++
 Documentation/ABI/testing/sysfs-kernel-warn_count  |  6 ++
 Documentation/sysctl/kernel.txt                    | 20 ++++++
 Makefile                                           |  4 +-
 arch/alpha/kernel/traps.c                          |  6 +-
 arch/alpha/mm/fault.c                              |  2 +-
 arch/arm/boot/dts/imx6qdl-gw560x.dtsi              |  1 -
 arch/arm/kernel/traps.c                            |  2 +-
 arch/arm/mm/fault.c                                |  2 +-
 arch/arm/mm/nommu.c                                |  2 +-
 arch/arm64/kernel/traps.c                          |  2 +-
 arch/arm64/mm/fault.c                              |  2 +-
 arch/h8300/kernel/traps.c                          |  3 +-
 arch/h8300/mm/fault.c                              |  2 +-
 arch/hexagon/kernel/traps.c                        |  2 +-
 arch/ia64/Kconfig                                  |  2 +-
 arch/ia64/kernel/mca_drv.c                         |  2 +-
 arch/ia64/kernel/traps.c                           |  2 +-
 arch/ia64/mm/fault.c                               |  2 +-
 arch/m68k/kernel/traps.c                           |  2 +-
 arch/m68k/mm/fault.c                               |  2 +-
 arch/microblaze/kernel/exceptions.c                |  4 +-
 arch/mips/kernel/traps.c                           |  2 +-
 arch/nios2/kernel/traps.c                          |  4 +-
 arch/openrisc/kernel/traps.c                       |  2 +-
 arch/parisc/kernel/traps.c                         |  2 +-
 arch/powerpc/kernel/traps.c                        |  2 +-
 arch/s390/kernel/dumpstack.c                       |  2 +-
 arch/s390/kernel/nmi.c                             |  2 +-
 arch/sh/kernel/traps.c                             |  2 +-
 arch/sparc/kernel/traps_32.c                       |  4 +-
 arch/sparc/kernel/traps_64.c                       |  4 +-
 arch/x86/entry/entry_32.S                          |  6 +-
 arch/x86/entry/entry_64.S                          |  8 +--
 arch/x86/kernel/dumpstack.c                        |  4 +-
 arch/x86/kernel/i8259.c                            |  1 +
 arch/x86/kernel/irqinit.c                          |  4 +-
 arch/x86/lib/iomap_copy_64.S                       |  2 +-
 arch/x86/xen/time.c                                |  2 +-
 arch/xtensa/kernel/traps.c                         |  2 +-
 drivers/dma/dmaengine.c                            |  7 +-
 drivers/edac/edac_device.c                         | 15 ++---
 drivers/edac/highbank_mc_edac.c                    |  7 +-
 drivers/gpu/drm/radeon/atombios_dp.c               |  8 +--
 drivers/gpu/drm/radeon/radeon_mode.h               |  4 --
 drivers/hid/hid-betopff.c                          | 17 ++---
 drivers/hid/hid-core.c                             |  4 +-
 drivers/hid/intel-ish-hid/ishtp/dma-if.c           | 10 +++
 drivers/infiniband/hw/hfi1/user_exp_rcv.c          | 16 ++---
 drivers/input/mouse/synaptics.c                    |  1 -
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c           | 23 ++++---
 drivers/net/ethernet/broadcom/tg3.c                |  8 +--
 drivers/net/ethernet/mellanox/mlx5/core/main.c     |  8 +--
 drivers/net/ethernet/renesas/ravb_main.c           |  4 +-
 drivers/net/phy/mdio_bus.c                         |  7 +-
 drivers/net/usb/sr9700.c                           |  2 +-
 .../broadcom/brcm80211/brcmfmac/firmware.c         |  2 +-
 drivers/net/wireless/rndis_wlan.c                  | 19 ++----
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c      |  4 +-
 drivers/scsi/hpsa.c                                |  2 +-
 drivers/scsi/qla2xxx/qla_bsg.c                     | 10 ++-
 drivers/scsi/qla2xxx/qla_isr.c                     | 12 +---
 drivers/scsi/qla2xxx/qla_mr.c                      |  3 +-
 drivers/staging/comedi/drivers/adv_pci1760.c       |  2 +-
 drivers/usb/gadget/function/f_fs.c                 |  7 ++
 drivers/usb/host/xhci-plat.c                       |  2 +-
 drivers/w1/w1.c                                    |  6 +-
 drivers/w1/w1_int.c                                |  5 +-
 fs/affs/file.c                                     |  2 +-
 fs/proc/proc_sysctl.c                              | 33 ++++++++++
 fs/reiserfs/super.c                                |  6 --
 include/linux/kernel.h                             |  1 +
 include/linux/sched/task.h                         |  1 +
 include/linux/sysctl.h                             |  3 +
 kernel/exit.c                                      | 72 +++++++++++++++++++++
 kernel/module.c                                    | 26 ++++++--
 kernel/panic.c                                     | 75 +++++++++++++++++++---
 kernel/sched/core.c                                |  3 +-
 kernel/trace/trace.c                               |  2 +
 kernel/trace/trace.h                               |  1 +
 kernel/trace/trace_output.c                        |  3 +-
 mm/kasan/report.c                                  |  3 +-
 mm/util.c                                          |  6 +-
 net/bluetooth/hci_core.c                           |  1 +
 net/ipv6/ip6_gre.c                                 | 12 ++--
 net/ipv6/ip6_tunnel.c                              | 10 +--
 net/ipv6/sit.c                                     |  8 ++-
 net/netfilter/nf_conntrack_proto_sctp.c            | 25 +++++---
 net/netlink/af_netlink.c                           | 31 +++++----
 net/netrom/nr_timer.c                              |  1 +
 net/nfc/llcp_core.c                                |  1 +
 net/sctp/bind_addr.c                               |  6 ++
 security/tomoyo/Makefile                           |  2 +-
 tools/objtool/check.c                              |  3 +-
 94 files changed, 470 insertions(+), 215 deletions(-)
author maintainer
#1 lore raw

PATCH 1/62 ARM: dts: imx6qdl-gw560x: Remove incorrect uart-has-rtscts

From: Fabio Estevam <[email protected]>

[ Upstream commit 9dfbc72256b5de608ad10989bcbafdbbd1ac8d4e ]

The following build warning is seen when running:

make dtbs_check DT_SCHEMA_FILES=fsl-imx-uart.yaml

arch/arm/boot/dts/imx6dl-gw560x.dtb: serial@2020000: rts-gpios: False schema does not allow [[20, 1, 0]]
From schema: Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml

The imx6qdl-gw560x board does not expose the UART RTS and CTS as native UART pins, so 'uart-has-rtscts' should not be used.

Using 'uart-has-rtscts' with 'rts-gpios' is an invalid combination detected by serial.yaml.

Fix the problem by removing the incorrect 'uart-has-rtscts' property.

Fixes b8a559feffb2 ("ARM: dts: imx: add Gateworks Ventana GW5600 support")
---
 arch/arm/boot/dts/imx6qdl-gw560x.dtsi | 1 -
 1 file changed, 1 deletion(-)
arch/arm/boot/dts/imx6qdl-gw560x.dtsi +0 -1
index d894dde6e85d..b2fc09fec2be 100644
@@ -462,7 +462,6 @@ &ssi1 {
 &uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_uart1>;
-	uart-has-rtscts;
 	rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
 	status = "okay";
 };
Signature · 1 line
2.39.0
author maintainer
#2 lore raw

PATCH 2/62 HID: intel_ish-hid: Add check for ishtp_dma_tx_map

In reply to Greg Kroah-Hartman

From: Jiasheng Jiang <[email protected]>

[ Upstream commit b3d40c3ec3dc4ad78017de6c3a38979f57aaaab8 ]

As the kcalloc may return NULL pointer,
it should be better to check the ishtp_dma_tx_map before use in order to avoid NULL pointer dereference.

Fixes 3703f53b99e4 ("HID: intel_ish-hid: ISH Transport layer")
---
 drivers/hid/intel-ish-hid/ishtp/dma-if.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/hid/intel-ish-hid/ishtp/dma-if.c +10 -0
index 2783f3666114..ff4419c8ed4f 100644
@@ -113,6 +113,11 @@ void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev,
 	int required_slots = (size / DMA_SLOT_SIZE)
 		+ 1 * (size % DMA_SLOT_SIZE != 0);
 
+	if (!dev->ishtp_dma_tx_map) {
+		dev_err(dev->devc, "Fail to allocate Tx map\n");
+		return NULL;
+	}
+
 	spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
 	for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) {
 		free = 1;
@@ -159,6 +164,11 @@ void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev,
 		return;
 	}
 
+	if (!dev->ishtp_dma_tx_map) {
+		dev_err(dev->devc, "Fail to allocate Tx map\n");
+		return;
+	}
+
 	i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE;
 	spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
 	for (j = 0; j < acked_slots; j++) {
Signature · 1 line
2.39.0
author maintainer
#3 lore raw

PATCH 3/62 EDAC/highbank: Fix memory leak in highbank_mc_probe()

In reply to Greg Kroah-Hartman

From: Miaoqian Lin <[email protected]>

[ Upstream commit e7a293658c20a7945014570e1921bf7d25d68a36 ]

When devres_open_group() fails, it returns -ENOMEM without freeing memory allocated by edac_mc_alloc().

Call edac_mc_free() on the error handling path to avoid a memory leak.

[ bp: Massage commit message. ]

Fixes a1b01edb2745 ("edac: add support for Calxeda highbank memory controller")
---
 drivers/edac/highbank_mc_edac.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/edac/highbank_mc_edac.c +5 -2
index 6092e61be605..bcf41601a977 100644
@@ -185,8 +185,10 @@ static int highbank_mc_probe(struct platform_device *pdev)
 	drvdata = mci->pvt_info;
 	platform_set_drvdata(pdev, mci);
 
-	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
-		return -ENOMEM;
+	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) {
+		res = -ENOMEM;
+		goto free;
+	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!r) {
@@ -254,6 +256,7 @@ static int highbank_mc_probe(struct platform_device *pdev)
 	edac_mc_del_mc(&pdev->dev);
 err:
 	devres_release_group(&pdev->dev, NULL);
+free:
 	edac_mc_free(mci);
 	return res;
 }
Signature · 1 line
2.39.0
author maintainer
#4 lore raw

PATCH 4/62 tomoyo: fix broken dependency on *.conf.default

In reply to Greg Kroah-Hartman

From: Masahiro Yamada <[email protected]>

[ Upstream commit eaf2213ba563b2d74a1f2c13a6b258273f689802 ]

If *.conf.default is updated, builtin-policy.h should be rebuilt, but this does not work when compiled with O= option.

[Without this commit]

  $ touch security/tomoyo/policy/exception_policy.conf.default
  $ make O=/tmp security/tomoyo/
  make[1]: Entering directory '/tmp'
    GEN     Makefile
    CALL    /home/masahiro/ref/linux/scripts/checksyscalls.sh
    DESCEND objtool
  make[1]: Leaving directory '/tmp'

[With this commit]

  $ touch security/tomoyo/policy/exception_policy.conf.default
  $ make O=/tmp security/tomoyo/
  make[1]: Entering directory '/tmp'
    GEN     Makefile
    CALL    /home/masahiro/ref/linux/scripts/checksyscalls.sh
    DESCEND objtool
    POLICY  security/tomoyo/builtin-policy.h
    CC      security/tomoyo/common.o
    AR      security/tomoyo/built-in.a
  make[1]: Leaving directory '/tmp'

$(srctree)/ is essential because $(wildcard ) does not follow VPATH.

Fixes f02dee2d148b ("tomoyo: Do not generate empty policy files")
---
 security/tomoyo/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
security/tomoyo/Makefile +1 -1
index b7c6a7ffc058..a1ecf68930c7 100644
@@ -10,7 +10,7 @@ endef
 quiet_cmd_policy  = POLICY  $@
       cmd_policy  = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@
 
-$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE
+$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(srctree)/$(src)/policy/*.conf.default) FORCE
 	$(call if_changed,policy)
 
 $(obj)/common.o: $(obj)/builtin-policy.h
Signature · 1 line
2.39.0
author maintainer
#5 lore raw

PATCH 5/62 IB/hfi1: Reject a zero-length user expected buffer

In reply to Greg Kroah-Hartman

From: Dean Luick <[email protected]>

[ Upstream commit 0a0a6e80472c98947d73c3d13bcd7d101895f55d ]

A zero length user buffer makes no sense and the code does not handle it correctly. Instead, reject a zero length as invalid.

---
 drivers/infiniband/hw/hfi1/user_exp_rcv.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/infiniband/hw/hfi1/user_exp_rcv.c +2 -0
index c6d085e1c10d..056ffab86a06 100644
@@ -323,6 +323,8 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
 
 	if (!PAGE_ALIGNED(tinfo->vaddr))
 		return -EINVAL;
+	if (tinfo->length == 0)
+		return -EINVAL;
 
 	tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL);
 	if (!tidbuf)
Signature · 1 line
2.39.0
author maintainer
#6 lore raw

PATCH 6/62 IB/hfi1: Reserve user expected TIDs

In reply to Greg Kroah-Hartman

From: Dean Luick <[email protected]>

[ Upstream commit ecf91551cdd2925ed6d9a9d99074fa5f67b90596 ]

To avoid a race, reserve the number of user expected TIDs before setup.

---
 drivers/infiniband/hw/hfi1/user_exp_rcv.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)
drivers/infiniband/hw/hfi1/user_exp_rcv.c +6 -8
index 056ffab86a06..b17c1fc59f7e 100644
@@ -349,16 +349,13 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
 	/* Find sets of physically contiguous pages */
 	tidbuf->n_psets = find_phys_blocks(tidbuf, pinned);
 
-	/*
-	 * We don't need to access this under a lock since tid_used is per
-	 * process and the same process cannot be in hfi1_user_exp_rcv_clear()
-	 * and hfi1_user_exp_rcv_setup() at the same time.
-	 */
+	/* Reserve the number of expected tids to be used. */
 	spin_lock(&fd->tid_lock);
 	if (fd->tid_used + tidbuf->n_psets > fd->tid_limit)
 		pageset_count = fd->tid_limit - fd->tid_used;
 	else
 		pageset_count = tidbuf->n_psets;
+	fd->tid_used += pageset_count;
 	spin_unlock(&fd->tid_lock);
 
 	if (!pageset_count)
@@ -468,10 +465,11 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd,
 nomem:
 	hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx,
 		  mapped_pages, ret);
+	/* adjust reserved tid_used to actual count */
+	spin_lock(&fd->tid_lock);
+	fd->tid_used -= pageset_count - tididx;
+	spin_unlock(&fd->tid_lock);
 	if (tididx) {
-		spin_lock(&fd->tid_lock);
-		fd->tid_used += tididx;
-		spin_unlock(&fd->tid_lock);
 		tinfo->tidcnt = tididx;
 		tinfo->length = mapped_pages * PAGE_SIZE;
 
Signature · 1 line
2.39.0
author maintainer
#7 lore raw

PATCH 7/62 affs: initialize fsdata in affs_truncate()

In reply to Greg Kroah-Hartman

From: Alexander Potapenko <[email protected]>

[ Upstream commit eef034ac6690118c88f357b00e2b3239c9d8575d ]

When aops->write_begin() does not initialize fsdata, KMSAN may report an error passing the latter to aops->write_end().

Fix this by unconditionally initializing fsdata.

Fixes f2b6a16eb8f5 ("fs: affs convert to new aops")
---
 fs/affs/file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/affs/file.c +1 -1
index ba084b0b214b..82bb38370aa9 100644
@@ -878,7 +878,7 @@ affs_truncate(struct inode *inode)
 	if (inode->i_size > AFFS_I(inode)->mmu_private) {
 		struct address_space *mapping = inode->i_mapping;
 		struct page *page;
-		void *fsdata;
+		void *fsdata = NULL;
 		loff_t isize = inode->i_size;
 		int res;
 
Signature · 1 line
2.39.0
author maintainer
#8 lore raw

PATCH 8/62 amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent

In reply to Greg Kroah-Hartman

From: Raju Rangoju <[email protected]>

[ Upstream commit 579923d84b04abb6cd4cd1fd9974096a2dd1832b ]

There is difference in the TX Flow Control registers (TFCR) between the revisions of the hardware. The older revisions of hardware used to have single register per queue. Whereas, the newer revision of hardware (from ver 30H onwards) have one register per priority.

Update the driver to use the TFCR based on the reported version of the hardware.

Fixes c5aa9e3b8156 ("amd-xgbe: Initial AMD 10GbE platform driver")
---
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
drivers/net/ethernet/amd/xgbe/xgbe-dev.c +15 -8
index 1e4bb33925e6..39d4df40700f 100644
@@ -523,19 +523,28 @@ static void xgbe_disable_vxlan(struct xgbe_prv_data *pdata)
 	netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n");
 }
 
+static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata)
+{
+	unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
+
+	/* From MAC ver 30H the TFCR is per priority, instead of per queue */
+	if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
+		return max_q_count;
+	else
+		return min_t(unsigned int, pdata->tx_q_count, max_q_count);
+}
+
 static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
 {
-	unsigned int max_q_count, q_count;
 	unsigned int reg, reg_val;
-	unsigned int i;
+	unsigned int i, q_count;
 
 	/* Clear MTL flow control */
 	for (i = 0; i < pdata->rx_q_count; i++)
 		XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
 
 	/* Clear MAC flow control */
-	max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-	q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
+	q_count = xgbe_get_fc_queue_count(pdata);
 	reg = MAC_Q0TFCR;
 	for (i = 0; i < q_count; i++) {
 		reg_val = XGMAC_IOREAD(pdata, reg);
@@ -552,9 +561,8 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
 {
 	struct ieee_pfc *pfc = pdata->pfc;
 	struct ieee_ets *ets = pdata->ets;
-	unsigned int max_q_count, q_count;
 	unsigned int reg, reg_val;
-	unsigned int i;
+	unsigned int i, q_count;
 
 	/* Set MTL flow control */
 	for (i = 0; i < pdata->rx_q_count; i++) {
@@ -578,8 +586,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
 	}
 
 	/* Set MAC flow control */
-	max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-	q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
+	q_count = xgbe_get_fc_queue_count(pdata);
 	reg = MAC_Q0TFCR;
 	for (i = 0; i < q_count; i++) {
 		reg_val = XGMAC_IOREAD(pdata, reg);
Signature · 1 line
2.39.0
author maintainer
#9 lore raw

PATCH 9/62 phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on()

In reply to Greg Kroah-Hartman

From: Shang XiaoJing <[email protected]>

[ Upstream commit 5daba914da0e48950e9407ea4d75fa57029c9adc ]

The clk_disable_unprepare() should be called in the error handling of rockchip_usb2phy_power_on().

Fixes 0e08d2a727e6 ("phy: rockchip-inno-usb2: add a new driver for Rockchip usb2phy")
---
 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c +3 -1
index ee7ce5ee53f9..a088cb027657 100644
@@ -477,8 +477,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
 		return ret;
 
 	ret = property_enable(base, &rport->port_cfg->phy_sus, false);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(rphy->clk480m);
 		return ret;
+	}
 
 	/* waiting for the utmi_clk to become stable */
 	usleep_range(1500, 2000);
Signature · 1 line
2.39.0
author maintainer
#10 lore raw

PATCH 10/62 net: nfc: Fix use-after-free in local_cleanup()

In reply to Greg Kroah-Hartman

From: Jisoo Jang <[email protected]>

[ Upstream commit 4bb4db7f3187c6e3de6b229ffc87cdb30a2d22b6 ]

Fix a use-after-free that occurs in kfree_skb() called from local_cleanup(). This could happen when killing nfc daemon (e.g. neard) after detaching an nfc device.
When detaching an nfc device, local_cleanup() called from nfc_llcp_unregister_device() frees local->rx_pending and decreases local->ref by kref_put() in nfc_llcp_local_put().
In the terminating process, nfc daemon releases all sockets and it leads to decreasing local->ref. After the last release of local->ref, local_cleanup() called from local_release() frees local->rx_pending again, which leads to the bug.

Setting local->rx_pending to NULL in local_cleanup() could prevent use-after-free when local_cleanup() is called twice.

Found by a modified version of syzkaller.

BUG: KASAN: use-after-free in kfree_skb()

Call Trace:

dump_stack_lvl (lib/dump_stack.c:106) print_address_description.constprop.0.cold (mm/kasan/report.c:306) kasan_check_range (mm/kasan/generic.c:189)
kfree_skb (net/core/skbuff.c:955)
local_cleanup (net/nfc/llcp_core.c:159) nfc_llcp_local_put.part.0 (net/nfc/llcp_core.c:172) nfc_llcp_local_put (net/nfc/llcp_core.c:181) llcp_sock_destruct (net/nfc/llcp_sock.c:959) __sk_destruct (net/core/sock.c:2133)
sk_destruct (net/core/sock.c:2181)
__sk_free (net/core/sock.c:2192)
sk_free (net/core/sock.c:2203)
llcp_sock_release (net/nfc/llcp_sock.c:646) __sock_release (net/socket.c:650)
sock_close (net/socket.c:1365)
__fput (fs/file_table.c:306)
task_work_run (kernel/task_work.c:179)
ptrace_notify (kernel/signal.c:2354) syscall_exit_to_user_mode_prepare (kernel/entry/common.c:278) syscall_exit_to_user_mode (kernel/entry/common.c:296) do_syscall_64 (arch/x86/entry/common.c:86) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:106)

Allocated by task 4719:

kasan_save_stack (mm/kasan/common.c:45) __kasan_slab_alloc (mm/kasan/common.c:325) slab_post_alloc_hook (mm/slab.h:766) kmem_cache_alloc_node (mm/slub.c:3497) __alloc_skb (net/core/skbuff.c:552) pn533_recv_response (drivers/nfc/pn533/usb.c:65) __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1671) usb_giveback_urb_bh (drivers/usb/core/hcd.c:1704) tasklet_action_common.isra.0 (kernel/softirq.c:797) __do_softirq (kernel/softirq.c:571)

Freed by task 1901:

kasan_save_stack (mm/kasan/common.c:45) kasan_set_track (mm/kasan/common.c:52) kasan_save_free_info (mm/kasan/genericdd.c:518) __kasan_slab_free (mm/kasan/common.c:236) kmem_cache_free (mm/slub.c:3809)
kfree_skbmem (net/core/skbuff.c:874)
kfree_skb (net/core/skbuff.c:931) local_cleanup (net/nfc/llcp_core.c:159) nfc_llcp_unregister_device (net/nfc/llcp_core.c:1617) nfc_unregister_device (net/nfc/core.c:1179) pn53x_unregister_nfc (drivers/nfc/pn533/pn533.c:2846) pn533_usb_disconnect (drivers/nfc/pn533/usb.c:579) usb_unbind_interface (drivers/usb/core/driver.c:458) device_release_driver_internal (drivers/base/dd.c:1279) bus_remove_device (drivers/base/bus.c:529) device_del (drivers/base/core.c:3665) usb_disable_device (drivers/usb/core/message.c:1420) usb_disconnect (drivers/usb/core.c:2261) hub_event (drivers/usb/core/hub.c:5833)

process_one_work (arch/x86/include/asm/jump_label.h:27 include/linux/jump_label.h:212 include/trace/events/workqueue.h:108 kernel/workqueue.c:2281)
worker_thread (include/linux/list.h:282 kernel/workqueue.c:2423)

kthread (kernel/kthread.c:319)
ret_from_fork (arch/x86/entry/entry_64.S:301)

Fixes 3536da06db0b ("NFC: llcp: Clean local timers and works when removing a device")
---
 net/nfc/llcp_core.c | 1 +
 1 file changed, 1 insertion(+)
net/nfc/llcp_core.c +1 -0
index 7e619ff8a653..150f7ffbf6bc 100644
@@ -171,6 +171,7 @@ static void local_cleanup(struct nfc_llcp_local *local)
 	cancel_work_sync(&local->rx_work);
 	cancel_work_sync(&local->timeout_work);
 	kfree_skb(local->rx_pending);
+	local->rx_pending = NULL;
 	del_timer_sync(&local->sdreq_timer);
 	cancel_work_sync(&local->sdreq_timeout_work);
 	nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
Signature · 1 line
2.39.0
author maintainer
#11 lore raw

PATCH 11/62 wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid

In reply to Greg Kroah-Hartman

From: Szymon Heidrich <[email protected]>

[ Upstream commit b870e73a56c4cccbec33224233eaf295839f228c ]

Since resplen and respoffs are signed integers sufficiently large values of unsigned int len and offset members of RNDIS response will result in negative values of prior variables. This may be utilized to bypass implemented security checks to either extract memory contents by manipulating offset or overflow the data buffer via memcpy by manipulating both offset and len.

Additionally assure that sum of resplen and respoffs does not overflow so buffer boundaries are kept.

Fixes 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond")
---
 drivers/net/wireless/rndis_wlan.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)
drivers/net/wireless/rndis_wlan.c +6 -13
index d4947e3a909e..0376a2a74572 100644
@@ -712,8 +712,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
 		struct rndis_query	*get;
 		struct rndis_query_c	*get_c;
 	} u;
-	int ret, buflen;
-	int resplen, respoffs, copylen;
+	int ret;
+	size_t buflen, resplen, respoffs, copylen;
 
 	buflen = *len + sizeof(*u.get);
 	if (buflen < CONTROL_BUFFER_SIZE)
@@ -748,22 +748,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len)
 
 		if (respoffs > buflen) {
 			/* Device returned data offset outside buffer, error. */
-			netdev_dbg(dev->net, "%s(%s): received invalid "
-				"data offset: %d > %d\n", __func__,
-				oid_to_string(oid), respoffs, buflen);
+			netdev_dbg(dev->net,
+				   "%s(%s): received invalid data offset: %zu > %zu\n",
+				   __func__, oid_to_string(oid), respoffs, buflen);
 
 			ret = -EINVAL;
 			goto exit_unlock;
 		}
 
-		if ((resplen + respoffs) > buflen) {
-			/* Device would have returned more data if buffer would
-			 * have been big enough. Copy just the bits that we got.
-			 */
-			copylen = buflen - respoffs;
-		} else {
-			copylen = resplen;
-		}
+		copylen = min(resplen, buflen - respoffs);
 
 		if (copylen > *len)
 			copylen = *len;
Signature · 1 line
2.39.0
author maintainer
#12 lore raw

PATCH 12/62 net: usb: sr9700: Handle negative len

In reply to Greg Kroah-Hartman

From: Szymon Heidrich <[email protected]>

[ Upstream commit ecf7cf8efb59789e2b21d2f9ab926142579092b2 ]

Packet len computed as difference of length word extracted from skb data and four may result in a negative value. In such case processing of the buffer should be interrupted rather than setting sr_skb->len to an unexpectedly large value (due to cast from signed to unsigned integer) and passing sr_skb to usbnet_skb_return.

Fixes e9da0b56fe27 ("sr9700: sanity check for packet length")
---
 drivers/net/usb/sr9700.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/sr9700.c +1 -1
index a97dd62b9d54..dbdb027abe47 100644
@@ -410,7 +410,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 		/* ignore the CRC length */
 		len = (skb->data[1] | (skb->data[2] << 8)) - 4;
 
-		if (len > ETH_FRAME_LEN || len > skb->len)
+		if (len > ETH_FRAME_LEN || len > skb->len || len < 0)
 			return 0;
 
 		/* the last packet of current skb */
Signature · 1 line
2.39.0
author maintainer
#13 lore raw

PATCH 13/62 net: mdio: validate parameter addr in mdiobus_get_phy()

In reply to Greg Kroah-Hartman

From: Heiner Kallweit <[email protected]>

[ Upstream commit 867dbe784c5010a466f00a7d1467c1c5ea569c75 ]

The caller may pass any value as addr, what may result in an out-of-bounds access to array mdio_map. One existing case is stmmac_init_phy() that may pass -1 as addr. Therefore validate addr before using it.

Fixes 7f854420fbfe ("phy: Add API for {un}registering an mdio device to a bus.")
---
 drivers/net/phy/mdio_bus.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/phy/mdio_bus.c +6 -1
index 7a813449d0d1..a9a0638a9b7a 100644
@@ -70,7 +70,12 @@ EXPORT_SYMBOL(mdiobus_unregister_device);
 
 struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
 {
-	struct mdio_device *mdiodev = bus->mdio_map[addr];
+	struct mdio_device *mdiodev;
+
+	if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map))
+		return NULL;
+
+	mdiodev = bus->mdio_map[addr];
 
 	if (!mdiodev)
 		return NULL;
Signature · 1 line
2.39.0
author maintainer
#14 lore raw

PATCH 14/62 HID: check empty report_list in hid_validate_values()

In reply to Greg Kroah-Hartman

From: Pietro Borrello <[email protected]>

[ Upstream commit b12fece4c64857e5fab4290bf01b2e0317a88456 ]

Add a check for empty report_list in hid_validate_values(). The missing check causes a type confusion when issuing a list_entry() on an empty report_list.
The problem is caused by the assumption that the device must have valid report_list. While this will be true for all normal HID devices, a suitably malicious device can violate the assumption.

Fixes 1b15d2e5b807 ("HID: core: fix validation of report id 0")
---
 drivers/hid/hid-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hid/hid-core.c +2 -2
index a3debe38d2c7..ab78c1e6f37d 100644
@@ -984,8 +984,8 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
 		 * Validating on id 0 means we should examine the first
 		 * report in the list.
 		 */
-		report = list_entry(
-				hid->report_enum[type].report_list.next,
+		report = list_first_entry_or_null(
+				&hid->report_enum[type].report_list,
 				struct hid_report, list);
 	} else {
 		report = hid->report_enum[type].report_id_hash[id];
Signature · 1 line
2.39.0
author maintainer
#15 lore raw

PATCH 15/62 usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait

In reply to Greg Kroah-Hartman

From: Udipto Goswami <[email protected]>

[ Upstream commit 6a19da111057f69214b97c62fb0ac59023970850 ]

While performing fast composition switch, there is a possibility that the process of ffs_ep0_write/ffs_ep0_read get into a race condition due to ep0req being freed up from functionfs_unbind.

Consider the scenario that the ffs_ep0_write calls the ffs_ep0_queue_wait by taking a lock &ffs->ev.waitq.lock. However, the functionfs_unbind isn't bounded so it can go ahead and mark the ep0req to NULL, and since there is no NULL check in ffs_ep0_queue_wait we will end up in use-after-free.

Fix this by making a serialized execution between the two functions using a mutex_lock(ffs->mutex).

---
 drivers/usb/gadget/function/f_fs.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/usb/gadget/function/f_fs.c +5 -0
index 13a38ed806df..df880fe73088 100644
@@ -274,6 +274,9 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len)
 	struct usb_request *req = ffs->ep0req;
 	int ret;
 
+	if (!req)
+		return -EINVAL;
+
 	req->zero     = len < le16_to_cpu(ffs->ev.setup.wLength);
 
 	spin_unlock_irq(&ffs->ev.waitq.lock);
@@ -1797,10 +1800,12 @@ static void functionfs_unbind(struct ffs_data *ffs)
 	ENTER();
 
 	if (!WARN_ON(!ffs->gadget)) {
+		mutex_lock(&ffs->mutex);
 		usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
 		ffs->ep0req = NULL;
 		ffs->gadget = NULL;
 		clear_bit(FFS_FL_BOUND, &ffs->flags);
+		mutex_unlock(&ffs->mutex);
 		ffs_data_put(ffs);
 	}
 }
Signature · 1 line
2.39.0
author maintainer
#16 lore raw

PATCH 16/62 usb: gadget: f_fs: Ensure ep0req is dequeued before free_request

In reply to Greg Kroah-Hartman

From: Udipto Goswami <[email protected]>

[ Upstream commit ce405d561b020e5a46340eb5146805a625dcacee ]

As per the documentation, function usb_ep_free_request guarantees the request will not be queued or no longer be re-queued (or otherwise used). However, with the current implementation it doesn't make sure that the request in ep0 isn't reused.

Fix this by dequeuing the ep0req on functionfs_unbind before freeing the request to align with the definition.

---
 drivers/usb/gadget/function/f_fs.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/usb/gadget/function/f_fs.c +2 -0
index df880fe73088..946cf039eddd 100644
@@ -1800,6 +1800,8 @@ static void functionfs_unbind(struct ffs_data *ffs)
 	ENTER();
 
 	if (!WARN_ON(!ffs->gadget)) {
+		/* dequeue before freeing ep0req */
+		usb_ep_dequeue(ffs->gadget->ep0, ffs->ep0req);
 		mutex_lock(&ffs->mutex);
 		usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req);
 		ffs->ep0req = NULL;
Signature · 1 line
2.39.0
author maintainer
#17 lore raw

PATCH 17/62 net: mlx5: eliminate anonymous module_init & module_exit

In reply to Greg Kroah-Hartman

From: Randy Dunlap <[email protected]>

[ Upstream commit 2c1e1b949024989e20907b84e11a731a50778416 ]

Eliminate anonymous module_init() and module_exit(), which can lead to confusion or ambiguity when reading System.map, crashes/oops/bugs, or an initcall_debug log.

Give each of these init and exit functions unique driver-specific names to eliminate the anonymous names.

Example 1: (System.map)
ffffffff832fc78c t init
ffffffff832fc79e t init
ffffffff832fc8f8 t init

Example 2: (initcall_debug log)
calling init+0x0/0x12 @ 1
initcall init+0x0/0x12 returned 0 after 15 usecs
calling init+0x0/0x60 @ 1
initcall init+0x0/0x60 returned 0 after 2 usecs
calling init+0x0/0x9a @ 1
initcall init+0x0/0x9a returned 0 after 74 usecs

Fixes e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters")
Cc Eli Cohen <[email protected]>
Cc Saeed Mahameed <[email protected]>
Cc Leon Romanovsky <[email protected]>
---
 drivers/net/ethernet/mellanox/mlx5/core/main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/main.c +4 -4
index 049d9d19c66d..840ce070bddf 100644
@@ -1615,7 +1615,7 @@ static void mlx5_core_verify_params(void)
 	}
 }
 
-static int __init init(void)
+static int __init mlx5_init(void)
 {
 	int err;
 
@@ -1637,7 +1637,7 @@ static int __init init(void)
 	return err;
 }
 
-static void __exit cleanup(void)
+static void __exit mlx5_cleanup(void)
 {
 #ifdef CONFIG_MLX5_CORE_EN
 	mlx5e_cleanup();
@@ -1646,5 +1646,5 @@ static void __exit cleanup(void)
 	mlx5_unregister_debugfs();
 }
 
-module_init(init);
-module_exit(cleanup);
+module_init(mlx5_init);
+module_exit(mlx5_cleanup);
Signature · 1 line
2.39.0
author maintainer
#18 lore raw

PATCH 18/62 dmaengine: Fix double increment of client_count in dma_chan_get()

In reply to Greg Kroah-Hartman

From: Koba Ko <[email protected]>

[ Upstream commit f3dc1b3b4750851a94212dba249703dd0e50bb20 ]

The first time dma_chan_get() is called for a channel the channel client_count is incorrectly incremented twice for public channels, first in balance_ref_count(), and again prior to returning. This results in an incorrect client count which will lead to the channel resources not being freed when they should be. A simple
test of repeated module load and unload of async_tx on a Dell Power Edge R7425 also shows this resulting in a kref underflow warning.

[  124.329662] async_tx: api initialized (async)
[  129.000627] async_tx: api initialized (async)
[  130.047839] ------------[ cut here ]------------
[  130.052472] refcount_t: underflow; use-after-free.
[  130.057279] WARNING: CPU: 3 PID: 19364 at lib/refcount.c:28
refcount_warn_saturate+0xba/0x110
[  130.065811] Modules linked in: async_tx(-) rfkill intel_rapl_msr

intel_rapl_common amd64_edac edac_mce_amd ipmi_ssif kvm_amd dcdbas kvm mgag200 drm_shmem_helper acpi_ipmi irqbypass drm_kms_helper ipmi_si syscopyarea sysfillrect rapl pcspkr ipmi_devintf sysimgblt fb_sys_fops k10temp i2c_piix4 ipmi_msghandler acpi_power_meter acpi_cpufreq vfat fat drm fuse xfs libcrc32c sd_mod t10_pi sg ahci crct10dif_pclmul libahci crc32_pclmul crc32c_intel ghash_clmulni_intel igb megaraid_sas i40e libata i2c_algo_bit ccp sp5100_tco dca dm_mirror dm_region_hash dm_log dm_mod [last unloaded: async_tx]

[  130.117361] CPU: 3 PID: 19364 Comm: modprobe Kdump: loaded Not
tainted 5.14.0-185.el9.x86_64 #1
[  130.126091] Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS
1.18.0 01/17/2022
[  130.133806] RIP: 0010:refcount_warn_saturate+0xba/0x110
[  130.139041] Code: 01 01 e8 6d bd 55 00 0f 0b e9 72 9d 8a 00 80 3d
26 18 9c 01 00 75 85 48 c7 c7 f8 a3 03 9d c6 05 16 18 9c 01 01 e8 4a
bd 55 00 <0f> 0b e9 4f 9d 8a 00 80 3d 01 18 9c 01 00 0f 85 5e ff ff ff
48 c7
[  130.157807] RSP: 0018:ffffbf98898afe68 EFLAGS: 00010286
[  130.163036] RAX: 0000000000000000 RBX: ffff9da06028e598 RCX: 0000000000000000
[  130.170172] RDX: ffff9daf9de26480 RSI: ffff9daf9de198a0 RDI: ffff9daf9de198a0
[  130.177316] RBP: ffff9da7cddf3970 R08: 0000000000000000 R09: 00000000ffff7fff
[  130.184459] R10: ffffbf98898afd00 R11: ffffffff9d9e8c28 R12: ffff9da7cddf1970
[  130.191596] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  130.198739] FS:  00007f646435c740(0000) GS:ffff9daf9de00000(0000)
knlGS:0000000000000000
[  130.206832] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  130.212586] CR2: 00007f6463b214f0 CR3: 00000008ab98c000 CR4: 00000000003506e0
[  130.219729] Call Trace:
[  130.222192]  <TASK>
[  130.224305]  dma_chan_put+0x10d/0x110
[  130.227988]  dmaengine_put+0x7a/0xa0
[  130.231575]  __do_sys_delete_module.constprop.0+0x178/0x280
[  130.237157]  ? syscall_trace_enter.constprop.0+0x145/0x1d0
[  130.242652]  do_syscall_64+0x5c/0x90
[  130.246240]  ? exc_page_fault+0x62/0x150
[  130.250178]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  130.255243] RIP: 0033:0x7f6463a3f5ab
[  130.258830] Code: 73 01 c3 48 8b 0d 75 a8 1b 00 f7 d8 64 89 01 48
83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00
00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 45 a8 1b 00 f7 d8 64 89
01 48
[  130.277591] RSP: 002b:00007fff22f972c8 EFLAGS: 00000206 ORIG_RAX:
00000000000000b0
[  130.285164] RAX: ffffffffffffffda RBX: 000055b6786edd40 RCX: 00007f6463a3f5ab
[  130.292303] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055b6786edda8
[  130.299443] RBP: 000055b6786edd40 R08: 0000000000000000 R09: 0000000000000000
[  130.306584] R10: 00007f6463b9eac0 R11: 0000000000000206 R12: 000055b6786edda8
[  130.313731] R13: 0000000000000000 R14: 000055b6786edda8 R15: 00007fff22f995f8
[  130.320875]  </TASK>
[  130.323081] ---[ end trace eff7156d56b5cf25 ]---

cat /sys/class/dma/dma0chan*/in_use would get the wrong result. 2
2
2

---
 drivers/dma/dmaengine.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/dma/dmaengine.c +4 -3
index faaaf10311ec..ef93045d7d7f 100644
@@ -225,7 +225,8 @@ static int dma_chan_get(struct dma_chan *chan)
 	/* The channel is already in use, update client count */
 	if (chan->client_count) {
 		__module_get(owner);
-		goto out;
+		chan->client_count++;
+		return 0;
 	}
 
 	if (!try_module_get(owner))
@@ -238,11 +239,11 @@ static int dma_chan_get(struct dma_chan *chan)
 			goto err_out;
 	}
 
+	chan->client_count++;
+
 	if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask))
 		balance_ref_count(chan);
 
-out:
-	chan->client_count++;
 	return 0;
 
 err_out:
Signature · 1 line
2.39.0
author maintainer
#19 lore raw

PATCH 19/62 HID: betop: check shape of output reports

In reply to Greg Kroah-Hartman

From: Pietro Borrello <[email protected]>

[ Upstream commit 3782c0d6edf658b71354a64d60aa7a296188fc90 ]

betopff_init() only checks the total sum of the report counts for each report field to be at least 4, but hid_betopff_play() expects 4 report fields.
A device advertising an output report with one field and 4 report counts would pass the check but crash the kernel with a NULL pointer dereference in hid_betopff_play().

Fixes 52cd7785f3cd ("HID: betop: add drivers/hid/hid-betopff.c")
---
 drivers/hid/hid-betopff.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/hid/hid-betopff.c +9 -8
index 9b60efe6ec44..ba386e5aa055 100644
@@ -63,7 +63,6 @@ static int betopff_init(struct hid_device *hid)
 	struct list_head *report_list =
 			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
 	struct input_dev *dev;
-	int field_count = 0;
 	int error;
 	int i, j;
 
@@ -89,19 +88,21 @@ static int betopff_init(struct hid_device *hid)
 	 * -----------------------------------------
 	 * Do init them with default value.
 	 */
+	if (report->maxfield < 4) {
+		hid_err(hid, "not enough fields in the report: %d\n",
+				report->maxfield);
+		return -ENODEV;
+	}
 	for (i = 0; i < report->maxfield; i++) {
+		if (report->field[i]->report_count < 1) {
+			hid_err(hid, "no values in the field\n");
+			return -ENODEV;
+		}
 		for (j = 0; j < report->field[i]->report_count; j++) {
 			report->field[i]->value[j] = 0x00;
-			field_count++;
 		}
 	}
 
-	if (field_count < 4) {
-		hid_err(hid, "not enough fields in the report: %d\n",
-				field_count);
-		return -ENODEV;
-	}
-
 	betopff = kzalloc(sizeof(*betopff), GFP_KERNEL);
 	if (!betopff)
 		return -ENOMEM;
Signature · 1 line
2.39.0
author maintainer
#20 lore raw

PATCH 20/62 w1: fix deadloop in __w1_remove_master_device()

In reply to Greg Kroah-Hartman

From: Yang Yingliang <[email protected]>

[ Upstream commit 25d5648802f12ae486076ceca5d7ddf1fef792b2 ]

I got a deadloop report while doing device(ds2482) add/remove test:

  [  162.241881] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1.
  [  163.272251] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1.
  [  164.296157] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1.
  ...

__w1_remove_master_device() can't return, because the dev->refcnt is not zero.

w1_add_master_device() |
w1_alloc_dev() |

    atomic_set(&dev->refcnt, 2)		|
  kthread_run()				|
					|__w1_remove_master_device()
					|  kthread_stop()
  // KTHREAD_SHOULD_STOP is set,	|
  // threadfn(w1_process) won't be	|
  // called.				|
  kthread()				|
					|  // refcnt will never be 0, it's deadloop.
					|  while (atomic_read(&dev->refcnt)) {...}

After calling w1_add_master_device(), w1_process() is not really invoked, before w1_process() starting, if kthread_stop() is called in __w1_remove_master_device(), w1_process() will never be called, the refcnt can not be decreased, then it causes deadloop in remove function because of non-zero refcnt.

We need to make sure w1_process() is really started, so move the set refcnt into w1_process() to fix this problem.

---
 drivers/w1/w1.c     | 2 ++
 drivers/w1/w1_int.c | 5 ++---
 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/w1/w1.c +2 -0
index 6f9e9505b34c..44315f9fd669 100644
@@ -1136,6 +1136,8 @@ int w1_process(void *data)
 	/* remainder if it woke up early */
 	unsigned long jremain = 0;
 
+	atomic_inc(&dev->refcnt);
+
 	for (;;) {
 
 		if (!jremain && dev->search_count) {
drivers/w1/w1_int.c +2 -3
index 1c776178f598..eb851eb44300 100644
@@ -60,10 +60,9 @@ static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
 	dev->search_count	= w1_search_count;
 	dev->enable_pullup	= w1_enable_pullup;
 
-	/* 1 for w1_process to decrement
-	 * 1 for __w1_remove_master_device to decrement
+	/* For __w1_remove_master_device to decrement
 	 */
-	atomic_set(&dev->refcnt, 2);
+	atomic_set(&dev->refcnt, 1);
 
 	INIT_LIST_HEAD(&dev->slist);
 	INIT_LIST_HEAD(&dev->async_list);
Signature · 1 line
2.39.0
author maintainer
#21 lore raw

PATCH 21/62 w1: fix WARNING after calling w1_process()

In reply to Greg Kroah-Hartman

From: Yang Yingliang <[email protected]>

[ Upstream commit 36225a7c72e9e3e1ce4001b6ce72849f5c9a2d3b ]

I got the following WARNING message while removing driver(ds2482):

------------[ cut here ]------------
do not call blocking ops when !TASK_RUNNING; state=1 set at [<000000002d50bfb6>] w1_process+0x9e/0x1d0 [wire]
WARNING: CPU: 0 PID: 262 at kernel/sched/core.c:9817 __might_sleep+0x98/0xa0
CPU: 0 PID: 262 Comm: w1_bus_master1 Tainted: G                 N 6.1.0-rc3+ #307
RIP: 0010:__might_sleep+0x98/0xa0
Call Trace:
 exit_signals+0x6c/0x550
 do_exit+0x2b4/0x17e0
 kthread_exit+0x52/0x60
 kthread+0x16d/0x1e0
 ret_from_fork+0x1f/0x30

The state of task is set to TASK_INTERRUPTIBLE in loop in w1_process(), set it to TASK_RUNNING when it breaks out of the loop to avoid the warning.

---
 drivers/w1/w1.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/w1/w1.c +3 -1
index 44315f9fd669..4d43c373e5c6 100644
@@ -1165,8 +1165,10 @@ int w1_process(void *data)
 		 */
 		mutex_unlock(&dev->list_mutex);
 
-		if (kthread_should_stop())
+		if (kthread_should_stop()) {
+			__set_current_state(TASK_RUNNING);
 			break;
+		}
 
 		/* Only sleep when the search is active. */
 		if (dev->search_count) {
Signature · 1 line
2.39.0
author maintainer
#22 lore raw

PATCH 22/62 comedi: adv_pci1760: Fix PWM instruction handling

In reply to Greg Kroah-Hartman

From: Ian Abbott <[email protected]>

commit 2efb6edd52dc50273f5e68ad863dd1b1fb2f2d1c upstream.

(Actually, this is fixing the "Read the Current Status" command sent to the device's outgoing mailbox, but it is only currently used for the PWM instructions.)

The PCI-1760 is operated mostly by sending commands to a set of Outgoing Mailbox registers, waiting for the command to complete, and reading the result from the Incoming Mailbox registers. One of these commands is the "Read the Current Status" command. The number of this command is 0x07 (see the User's Manual for the PCI-1760 at
<https://advdownload.advantech.com/productfile/Downloadfile2/1-11P6653/PCI-1760.pdf>.
The PCI1760_CMD_GET_STATUS macro defined in the driver should expand to this command number 0x07, but unfortunately it currently expands to 0x03. (Command number 0x03 is not defined in the User's Manual.) Correct the definition of the PCI1760_CMD_GET_STATUS macro to fix it.

This is used by all the PWM subdevice related instructions handled by pci1760_pwm_insn_config() which are probably all broken. The effect of sending the undefined command number 0x03 is not known.

Fixes 14b93bb6bbf0 ("staging: comedi: adv_pci_dio: separate out PCI-1760 support")
Cc <[email protected]> # v4.5+
---
 drivers/staging/comedi/drivers/adv_pci1760.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/staging/comedi/drivers/adv_pci1760.c +1 -1
@@ -68,7 +68,7 @@
 #define PCI1760_CMD_CLR_IMB2		0x00	/* Clears IMB2 */
 #define PCI1760_CMD_SET_DO		0x01	/* Set output state */
 #define PCI1760_CMD_GET_DO		0x02	/* Read output status */
-#define PCI1760_CMD_GET_STATUS		0x03	/* Read current status */
+#define PCI1760_CMD_GET_STATUS		0x07	/* Read current status */
 #define PCI1760_CMD_GET_FW_VER		0x0e	/* Read firware version */
 #define PCI1760_CMD_GET_HW_VER		0x0f	/* Read hardware version */
 #define PCI1760_CMD_SET_PWM_HI(x)	(0x10 + (x) * 2) /* Set "hi" period */
author maintainer
#23 lore raw

PATCH 23/62 fs: reiserfs: remove useless new_opts in reiserfs_remount

In reply to Greg Kroah-Hartman

From: Dongliang Mu <[email protected]>

commit 81dedaf10c20959bdf5624f9783f408df26ba7a4 upstream.

Since the commit c3d98ea08291 ("VFS: Don't use save/replace_mount_options if not using generic_show_options") eliminates replace_mount_options in reiserfs_remount, but does not handle the allocated new_opts, it will cause memory leak in the reiserfs_remount.

Because new_opts is useless in reiserfs_mount, so we fix this bug by removing the useless new_opts in reiserfs_remount.

Fixes c3d98ea08291 ("VFS: Don't use save/replace_mount_options if not using generic_show_options")
---
 fs/reiserfs/super.c |    6 ------
 1 file changed, 6 deletions(-)
fs/reiserfs/super.c +0 -6
@@ -1443,7 +1443,6 @@ static int reiserfs_remount(struct super
 	unsigned long safe_mask = 0;
 	unsigned int commit_max_age = (unsigned int)-1;
 	struct reiserfs_journal *journal = SB_JOURNAL(s);
-	char *new_opts;
 	int err;
 	char *qf_names[REISERFS_MAXQUOTAS];
 	unsigned int qfmt = 0;
@@ -1451,10 +1450,6 @@ static int reiserfs_remount(struct super
 	int i;
 #endif
 
-	new_opts = kstrdup(arg, GFP_KERNEL);
-	if (arg && !new_opts)
-		return -ENOMEM;
-
 	sync_filesystem(s);
 	reiserfs_write_lock(s);
 
@@ -1605,7 +1600,6 @@ out_ok_unlocked:
 out_err_unlock:
 	reiserfs_write_unlock(s);
 out_err:
-	kfree(new_opts);
 	return err;
 }
 
author maintainer
#24 lore raw

PATCH 24/62 Bluetooth: hci_sync: cancel cmd_timer if hci_open failed

In reply to Greg Kroah-Hartman

From: Archie Pusaka <[email protected]>

commit 97dfaf073f5881c624856ef293be307b6166115c upstream.

If a command is already sent, we take care of freeing it, but we also need to cancel the timeout as well.

---
 net/bluetooth/hci_core.c | 1 +
 1 file changed, 1 insertion(+)
net/bluetooth/hci_core.c +1 -0
index 81a151ca4a24..1fd6498e3387 100644
@@ -1479,6 +1479,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
 			hdev->flush(hdev);
 
 		if (hdev->sent_cmd) {
+			cancel_delayed_work_sync(&hdev->cmd_timer);
 			kfree_skb(hdev->sent_cmd);
 			hdev->sent_cmd = NULL;
 		}
Signature · 1 line
2.39.0
author maintainer
#25 lore raw

PATCH 25/62 scsi: hpsa: Fix allocation size for scsi_host_alloc()

In reply to Greg Kroah-Hartman

From: Alexey V. Vissarionov <[email protected]>

[ Upstream commit bbbd25499100c810ceaf5193c3cfcab9f7402a33 ]

The 'h' is a pointer to struct ctlr_info, so it's just 4 or 8 bytes, while the structure itself is much bigger.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

---
 drivers/scsi/hpsa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/hpsa.c +1 -1
index 6b25c5ce13ed..34434b7107ee 100644
@@ -5627,7 +5627,7 @@ static int hpsa_scsi_host_alloc(struct ctlr_info *h)
 {
 	struct Scsi_Host *sh;
 
-	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h));
+	sh = scsi_host_alloc(&hpsa_driver_template, sizeof(struct ctlr_info));
 	if (sh == NULL) {
 		dev_err(&h->pdev->dev, "scsi_host_alloc failed\n");
 		return -ENOMEM;
Signature · 1 line
2.39.0
author maintainer
#26 lore raw

PATCH 26/62 module: Dont wait for GOING modules

In reply to Greg Kroah-Hartman

From: Petr Pavlu <[email protected]>

commit 0254127ab977e70798707a7a2b757c9f3c971210 upstream.

During a system boot, it can happen that the kernel receives a burst of requests to insert the same module but loading it eventually fails during its init call. For instance, udev can make a request to insert a frequency module for each individual CPU when another frequency module is already loaded which causes the init function of the new module to return an error.

Since commit 6e6de3dee51a ("kernel/module.c: Only return -EEXIST for modules that have finished loading"), the kernel waits for modules in MODULE_STATE_GOING state to finish unloading before making another attempt to load the same module.

This creates unnecessary work in the described scenario and delays the boot. In the worst case, it can prevent udev from loading drivers for other devices and might cause timeouts of services waiting on them and subsequently a failed boot.

This patch attempts a different solution for the problem 6e6de3dee51a was trying to solve. Rather than waiting for the unloading to complete, it returns a different error code (-EBUSY) for modules in the GOING state. This should avoid the error situation that was described in 6e6de3dee51a (user space attempting to load a dependent module because the -EEXIST error code would suggest to user space that the first module had been loaded successfully), while avoiding the delay situation too.

This has been tested on linux-next since December 2022 and passes all kmod selftests except test 0009 with module compression enabled but it has been confirmed that this issue has existed and has gone unnoticed since prior to this commit and can also be reproduced without module compression with a simple usleep(5000000) on tools/modprobe.c [0]. These failures are caused by hitting the kernel mod_concurrent_max and can happen either due to a self inflicted kernel module auto-loead DoS somehow or on a system with large CPU count and each CPU count incorrectly triggering many module auto-loads. Both of those issues need to be fixed in-kernel.

[0] https://lore.kernel.org/all/Y9A4fiobL6IHp%2F%[email protected]/

Fixes 6e6de3dee51a ("kernel/module.c: Only return -EEXIST for modules that have finished loading")
[mcgrof: enhance commit log with testing and kmod test result interpretation ]
---
 kernel/module.c |   26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)
kernel/module.c +21 -5
@@ -3451,7 +3451,8 @@ static bool finished_loading(const char
 	sched_annotate_sleep();
 	mutex_lock(&module_mutex);
 	mod = find_module_all(name, strlen(name), true);
-	ret = !mod || mod->state == MODULE_STATE_LIVE;
+	ret = !mod || mod->state == MODULE_STATE_LIVE
+		|| mod->state == MODULE_STATE_GOING;
 	mutex_unlock(&module_mutex);
 
 	return ret;
@@ -3603,20 +3604,35 @@ static int add_unformed_module(struct mo
 
 	mod->state = MODULE_STATE_UNFORMED;
 
-again:
 	mutex_lock(&module_mutex);
 	old = find_module_all(mod->name, strlen(mod->name), true);
 	if (old != NULL) {
-		if (old->state != MODULE_STATE_LIVE) {
+		if (old->state == MODULE_STATE_COMING
+		    || old->state == MODULE_STATE_UNFORMED) {
 			/* Wait in case it fails to load. */
 			mutex_unlock(&module_mutex);
 			err = wait_event_interruptible(module_wq,
 					       finished_loading(mod->name));
 			if (err)
 				goto out_unlocked;
-			goto again;
+
+			/* The module might have gone in the meantime. */
+			mutex_lock(&module_mutex);
+			old = find_module_all(mod->name, strlen(mod->name),
+					      true);
 		}
-		err = -EEXIST;
+
+		/*
+		 * We are here only when the same module was being loaded. Do
+		 * not try to load it again right now. It prevents long delays
+		 * caused by serialized module load failures. It might happen
+		 * when more devices of the same type trigger load of
+		 * a particular module.
+		 */
+		if (old && old->state == MODULE_STATE_LIVE)
+			err = -EEXIST;
+		else
+			err = -EBUSY;
 		goto out;
 	}
 	mod_update_bounds(mod);
author maintainer
#27 lore raw

PATCH 27/62 tracing: Make sure trace_printk() can output as soon as it can be used

In reply to Greg Kroah-Hartman

From: Steven Rostedt (Google) <[email protected]>

commit 3bb06eb6e9acf7c4a3e1b5bc87aed398ff8e2253 upstream.

Currently trace_printk() can be used as soon as early_trace_init() is called from start_kernel(). But if a crash happens, and "ftrace_dump_on_oops" is set on the kernel command line, all you get will be:

  [    0.456075]   <idle>-0         0dN.2. 347519us : Unknown type 6
  [    0.456075]   <idle>-0         0dN.2. 353141us : Unknown type 6
  [    0.456075]   <idle>-0         0dN.2. 358684us : Unknown type 6

This is because the trace_printk() event (type 6) hasn't been registered yet. That gets done via an early_initcall(), which may be early, but not early enough.

Instead of registering the trace_printk() event (and other ftrace events, which are not trace events) via an early_initcall(), have them registered at the same time that trace_printk() can be used. This way, if there is a crash before early_initcall(), then the trace_printk()s will actually be useful.

Cc Masami Hiramatsu <[email protected]>
Fixes e725c731e3bb1 ("tracing: Split tracing initialization into two for early initialization")
---
 kernel/trace/trace.c        |    2 ++
 kernel/trace/trace.h        |    1 +
 kernel/trace/trace_output.c |    3 +--
 3 files changed, 4 insertions(+), 2 deletions(-)
kernel/trace/trace.c +2 -0
@@ -8487,6 +8487,8 @@ void __init early_trace_init(void)
 			static_key_enable(&tracepoint_printk_key.key);
 	}
 	tracer_alloc_buffers();
+
+	init_events();
 }
 
 void __init trace_init(void)
kernel/trace/trace.h +1 -0
@@ -1531,6 +1531,7 @@ trace_find_event_field(struct trace_even
 extern void trace_event_enable_cmd_record(bool enable);
 extern void trace_event_enable_tgid_record(bool enable);
 
+extern int init_events(void);
 extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
 extern int event_trace_del_tracer(struct trace_array *tr);
 
kernel/trace/trace_output.c +1 -2
@@ -1394,7 +1394,7 @@ static struct trace_event *events[] __in
 	NULL
 };
 
-__init static int init_events(void)
+__init int init_events(void)
 {
 	struct trace_event *event;
 	int i, ret;
@@ -1412,4 +1412,3 @@ __init static int init_events(void)
 
 	return 0;
 }
-early_initcall(init_events);
author maintainer
#28 lore raw

PATCH 28/62 ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment

In reply to Greg Kroah-Hartman

From: Giulio Benetti <[email protected]>

commit a4e03921c1bb118e6718e0a3b0322a2c13ed172b upstream.

zero_page is a void* pointer but memblock_alloc() returns phys_addr_t type so this generates a warning while using clang and with -Wint-error enabled that becomes and error. So let's cast the return of memblock_alloc() to (void *).

Cc <[email protected]> # 4.14.x +
Fixes 340a982825f7 ("ARM: 9266/1: mm: fix no-MMU ZERO_PAGE() implementation")
---
 arch/arm/mm/nommu.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/nommu.c +1 -1
@@ -379,7 +379,7 @@ void __init paging_init(const struct mac
 	mpu_setup();
 
 	/* allocate the zero page. */
-	zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+	zero_page = (void *)memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 	if (!zero_page)
 		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
 		      __func__, PAGE_SIZE, PAGE_SIZE);
author maintainer
#29 lore raw

PATCH 29/62 EDAC/device: Respect any driver-supplied workqueue polling value

In reply to Greg Kroah-Hartman

From: Manivannan Sadhasivam <[email protected]>

commit cec669ff716cc83505c77b242aecf6f7baad869d upstream.

The EDAC drivers may optionally pass the poll_msec value. Use that value if available, else fall back to 1000ms.

[ bp: Touchups. ]

---
 drivers/edac/edac_device.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)
drivers/edac/edac_device.c +7 -8
@@ -34,6 +34,9 @@
 static DEFINE_MUTEX(device_ctls_mutex);
 static LIST_HEAD(edac_device_list);
 
+/* Default workqueue processing interval on this instance, in msecs */
+#define DEFAULT_POLL_INTERVAL 1000
+
 #ifdef CONFIG_EDAC_DEBUG
 static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
 {
@@ -366,7 +369,7 @@ static void edac_device_workq_function(s
 	 * whole one second to save timers firing all over the period
 	 * between integral seconds
 	 */
-	if (edac_dev->poll_msec == 1000)
+	if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
 		edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
 	else
 		edac_queue_work(&edac_dev->work, edac_dev->delay);
@@ -396,7 +399,7 @@ static void edac_device_workq_setup(stru
 	 * timers firing on sub-second basis, while they are happy
 	 * to fire together on the 1 second exactly
 	 */
-	if (edac_dev->poll_msec == 1000)
+	if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
 		edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
 	else
 		edac_queue_work(&edac_dev->work, edac_dev->delay);
@@ -430,7 +433,7 @@ void edac_device_reset_delay_period(stru
 	edac_dev->delay	    = msecs_to_jiffies(msec);
 
 	/* See comment in edac_device_workq_setup() above */
-	if (edac_dev->poll_msec == 1000)
+	if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL)
 		edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay));
 	else
 		edac_mod_work(&edac_dev->work, edac_dev->delay);
@@ -472,11 +475,7 @@ int edac_device_add_device(struct edac_d
 		/* This instance is NOW RUNNING */
 		edac_dev->op_state = OP_RUNNING_POLL;
 
-		/*
-		 * enable workq processing on this instance,
-		 * default = 1000 msec
-		 */
-		edac_device_workq_setup(edac_dev, 1000);
+		edac_device_workq_setup(edac_dev, edac_dev->poll_msec ?: DEFAULT_POLL_INTERVAL);
 	} else {
 		edac_dev->op_state = OP_RUNNING_INTERRUPT;
 	}
author maintainer
#30 lore raw

PATCH 30/62 netlink: annotate data races around dst_portid and dst_group

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit 004db64d185a5f23dfb891d7701e23713b2420ee ]

netlink_getname(), netlink_sendmsg() and netlink_getsockbyportid() can read nlk->dst_portid and nlk->dst_group while another thread is changing them.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/netlink/af_netlink.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)
net/netlink/af_netlink.c +14 -9
index 1b2e99ce54e5..1547d0825668 100644
@@ -1062,8 +1062,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 
 	if (addr->sa_family == AF_UNSPEC) {
 		sk->sk_state	= NETLINK_UNCONNECTED;
-		nlk->dst_portid	= 0;
-		nlk->dst_group  = 0;
+		/* dst_portid and dst_group can be read locklessly */
+		WRITE_ONCE(nlk->dst_portid, 0);
+		WRITE_ONCE(nlk->dst_group, 0);
 		return 0;
 	}
 	if (addr->sa_family != AF_NETLINK)
@@ -1085,8 +1086,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 
 	if (err == 0) {
 		sk->sk_state	= NETLINK_CONNECTED;
-		nlk->dst_portid = nladdr->nl_pid;
-		nlk->dst_group  = ffs(nladdr->nl_groups);
+		/* dst_portid and dst_group can be read locklessly */
+		WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid);
+		WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups));
 	}
 
 	return err;
@@ -1104,8 +1106,9 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
 	*addr_len = sizeof(*nladdr);
 
 	if (peer) {
-		nladdr->nl_pid = nlk->dst_portid;
-		nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
+		/* Paired with WRITE_ONCE() in netlink_connect() */
+		nladdr->nl_pid = READ_ONCE(nlk->dst_portid);
+		nladdr->nl_groups = netlink_group_mask(READ_ONCE(nlk->dst_group));
 	} else {
 		nladdr->nl_pid = nlk->portid;
 		netlink_lock_table();
@@ -1134,8 +1137,9 @@ static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
 
 	/* Don't bother queuing skb if kernel socket has no input function */
 	nlk = nlk_sk(sock);
+	/* dst_portid can be changed in netlink_connect() */
 	if (sock->sk_state == NETLINK_CONNECTED &&
-	    nlk->dst_portid != nlk_sk(ssk)->portid) {
+	    READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) {
 		sock_put(sock);
 		return ERR_PTR(-ECONNREFUSED);
 	}
@@ -1847,8 +1851,9 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
 			goto out;
 		netlink_skb_flags |= NETLINK_SKB_DST;
 	} else {
-		dst_portid = nlk->dst_portid;
-		dst_group = nlk->dst_group;
+		/* Paired with WRITE_ONCE() in netlink_connect() */
+		dst_portid = READ_ONCE(nlk->dst_portid);
+		dst_group = READ_ONCE(nlk->dst_group);
 	}
 
 	/* Paired with WRITE_ONCE() in netlink_insert() */
Signature · 1 line
2.39.0
author maintainer
#31 lore raw

PATCH 31/62 netlink: annotate data races around sk_state

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

[ Upstream commit 9b663b5cbb15b494ef132a3c937641c90646eb73 ]

netlink_getsockbyportid() reads sk_state while a concurrent netlink_connect() can change its value.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 net/netlink/af_netlink.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
net/netlink/af_netlink.c +6 -4
index 1547d0825668..d7b0a7aa29a8 100644
@@ -1061,7 +1061,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 		return -EINVAL;
 
 	if (addr->sa_family == AF_UNSPEC) {
-		sk->sk_state	= NETLINK_UNCONNECTED;
+		/* paired with READ_ONCE() in netlink_getsockbyportid() */
+		WRITE_ONCE(sk->sk_state, NETLINK_UNCONNECTED);
 		/* dst_portid and dst_group can be read locklessly */
 		WRITE_ONCE(nlk->dst_portid, 0);
 		WRITE_ONCE(nlk->dst_group, 0);
@@ -1085,7 +1086,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 		err = netlink_autobind(sock);
 
 	if (err == 0) {
-		sk->sk_state	= NETLINK_CONNECTED;
+		/* paired with READ_ONCE() in netlink_getsockbyportid() */
+		WRITE_ONCE(sk->sk_state, NETLINK_CONNECTED);
 		/* dst_portid and dst_group can be read locklessly */
 		WRITE_ONCE(nlk->dst_portid, nladdr->nl_pid);
 		WRITE_ONCE(nlk->dst_group, ffs(nladdr->nl_groups));
@@ -1137,8 +1139,8 @@ static struct sock *netlink_getsockbyportid(struct sock *ssk, u32 portid)
 
 	/* Don't bother queuing skb if kernel socket has no input function */
 	nlk = nlk_sk(sock);
-	/* dst_portid can be changed in netlink_connect() */
-	if (sock->sk_state == NETLINK_CONNECTED &&
+	/* dst_portid and sk_state can be changed in netlink_connect() */
+	if (READ_ONCE(sock->sk_state) == NETLINK_CONNECTED &&
 	    READ_ONCE(nlk->dst_portid) != nlk_sk(ssk)->portid) {
 		sock_put(sock);
 		return ERR_PTR(-ECONNREFUSED);
Signature · 1 line
2.39.0
author maintainer
#32 lore raw

PATCH 32/62 netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE

In reply to Greg Kroah-Hartman

From: Sriram Yagnaraman <[email protected]>

[ Upstream commit a9993591fa94246b16b444eea55d84c54608282a ]

RFC 9260, Sec 8.5.1 states that for ABORT/SHUTDOWN_COMPLETE, the chunk MUST be accepted if the vtag of the packet matches its own tag and the T bit is not set OR if it is set to its peer's vtag and the T bit is set in chunk flags. Otherwise the packet MUST be silently dropped.

Update vtag verification for ABORT/SHUTDOWN_COMPLETE based on the above description.

Fixes 9fb9cbb1082d ("[NETFILTER]: Add nf_conntrack subsystem.")
---
 net/netfilter/nf_conntrack_proto_sctp.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
net/netfilter/nf_conntrack_proto_sctp.c +16 -9
index 6303a88af12b..1278b27c625a 100644
@@ -343,22 +343,29 @@ static int sctp_packet(struct nf_conn *ct,
 	for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
 		/* Special cases of Verification tag check (Sec 8.5.1) */
 		if (sch->type == SCTP_CID_INIT) {
-			/* Sec 8.5.1 (A) */
+			/* (A) vtag MUST be zero */
 			if (sh->vtag != 0)
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_ABORT) {
-			/* Sec 8.5.1 (B) */
-			if (sh->vtag != ct->proto.sctp.vtag[dir] &&
-			    sh->vtag != ct->proto.sctp.vtag[!dir])
+			/* (B) vtag MUST match own vtag if T flag is unset OR
+			 * MUST match peer's vtag if T flag is set
+			 */
+			if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[dir]) ||
+			    ((sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[!dir]))
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
-			/* Sec 8.5.1 (C) */
-			if (sh->vtag != ct->proto.sctp.vtag[dir] &&
-			    sh->vtag != ct->proto.sctp.vtag[!dir] &&
-			    sch->flags & SCTP_CHUNK_FLAG_T)
+			/* (C) vtag MUST match own vtag if T flag is unset OR
+			 * MUST match peer's vtag if T flag is set
+			 */
+			if ((!(sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[dir]) ||
+			    ((sch->flags & SCTP_CHUNK_FLAG_T) &&
+			     sh->vtag != ct->proto.sctp.vtag[!dir]))
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_COOKIE_ECHO) {
-			/* Sec 8.5.1 (D) */
+			/* (D) vtag must be same as init_vtag as found in INIT_ACK */
 			if (sh->vtag != ct->proto.sctp.vtag[dir])
 				goto out_unlock;
 		} else if (sch->type == SCTP_CID_HEARTBEAT ||
Signature · 1 line
2.39.0
author maintainer
#33 lore raw

PATCH 33/62 netrom: Fix use-after-free of a listening socket.

In reply to Greg Kroah-Hartman

From: Kuniyuki Iwashima <[email protected]>

[ Upstream commit 409db27e3a2eb5e8ef7226ca33be33361b3ed1c9 ]

syzbot reported a use-after-free in do_accept(), precisely nr_accept() as sk_prot_alloc() allocated the memory and sock_put() frees it. [0]

The issue could happen if the heartbeat timer is fired and nr_heartbeat_expiry() calls nr_destroy_socket(), where a socket has SOCK_DESTROY or a listening socket has SOCK_DEAD.

In this case, the first condition cannot be true. SOCK_DESTROY is flagged in nr_release() only when the file descriptor is close()d, but accept() is being called for the listening socket, so the second condition must be true.

Usually, the AF_NETROM listener neither starts timers nor sets SOCK_DEAD. However, the condition is met if connect() fails before listen(). connect() starts the t1 timer and heartbeat timer, and t1timer calls nr_disconnect() when timeout happens. Then, SOCK_DEAD is set, and if we call listen(), the heartbeat timer calls nr_destroy_socket().

nr_connect

    nr_establish_data_link(sk)
      nr_start_t1timer(sk)
    nr_start_heartbeat(sk)
                                    nr_t1timer_expiry
                                      nr_disconnect(sk, ETIMEDOUT)
                                        nr_sk(sk)->state = NR_STATE_0
                                        sk->sk_state = TCP_CLOSE
                                        sock_set_flag(sk, SOCK_DEAD)
nr_listen
  if (sk->sk_state != TCP_LISTEN)
    sk->sk_state = TCP_LISTEN
                                    nr_heartbeat_expiry
                                      switch (nr->state)
                                      case NR_STATE_0
                                        if (sk->sk_state == TCP_LISTEN &&
                                            sock_flag(sk, SOCK_DEAD))
                                          nr_destroy_socket(sk)

This path seems expected, and nr_destroy_socket() is called to clean up resources. Initially, there was sock_hold() before nr_destroy_socket() so that the socket would not be freed, but the commit 517a16b1a88b ("netrom: Decrease sock refcount when sock timers expire") accidentally removed it.

To fix use-after-free, let's add sock_hold().

[0]:

BUG: KASAN: use-after-free in do_accept+0x483/0x510 net/socket.c:1848
Read of size 8 at addr ffff88807978d398 by task syz-executor.3/5315

CPU: 0 PID: 5315 Comm: syz-executor.3 Not tainted 6.2.0-rc3-syzkaller-00165-gd9fc1511728c #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106
 print_address_description mm/kasan/report.c:306 [inline]
 print_report+0x15e/0x461 mm/kasan/report.c:417
 kasan_report+0xbf/0x1f0 mm/kasan/report.c:517
 do_accept+0x483/0x510 net/socket.c:1848
 __sys_accept4_file net/socket.c:1897 [inline]
 __sys_accept4+0x9a/0x120 net/socket.c:1927
 __do_sys_accept net/socket.c:1944 [inline]
 __se_sys_accept net/socket.c:1941 [inline]
 __x64_sys_accept+0x75/0xb0 net/socket.c:1941
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7fa436a8c0c9
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fa437784168 EFLAGS: 00000246 ORIG_RAX: 000000000000002b
RAX: ffffffffffffffda RBX: 00007fa436bac050 RCX: 00007fa436a8c0c9
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000005
RBP: 00007fa436ae7ae9 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffebc6700df R14: 00007fa437784300 R15: 0000000000022000
 </TASK>

Allocated by task 5294:
 kasan_save_stack+0x22/0x40 mm/kasan/common.c:45
 kasan_set_track+0x25/0x30 mm/kasan/common.c:52
 ____kasan_kmalloc mm/kasan/common.c:371 [inline]
 ____kasan_kmalloc mm/kasan/common.c:330 [inline]
 __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380
 kasan_kmalloc include/linux/kasan.h:211 [inline]
 __do_kmalloc_node mm/slab_common.c:968 [inline]
 __kmalloc+0x5a/0xd0 mm/slab_common.c:981
 kmalloc include/linux/slab.h:584 [inline]
 sk_prot_alloc+0x140/0x290 net/core/sock.c:2038
 sk_alloc+0x3a/0x7a0 net/core/sock.c:2091
 nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433
 __sock_create+0x359/0x790 net/socket.c:1515
 sock_create net/socket.c:1566 [inline]
 __sys_socket_create net/socket.c:1603 [inline]
 __sys_socket_create net/socket.c:1588 [inline]
 __sys_socket+0x133/0x250 net/socket.c:1636
 __do_sys_socket net/socket.c:1649 [inline]
 __se_sys_socket net/socket.c:1647 [inline]
 __x64_sys_socket+0x73/0xb0 net/socket.c:1647
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd

Freed by task 14:
 kasan_save_stack+0x22/0x40 mm/kasan/common.c:45
 kasan_set_track+0x25/0x30 mm/kasan/common.c:52
 kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518
 ____kasan_slab_free mm/kasan/common.c:236 [inline]
 ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200
 kasan_slab_free include/linux/kasan.h:177 [inline]
 __cache_free mm/slab.c:3394 [inline]
 __do_kmem_cache_free mm/slab.c:3580 [inline]
 __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587
 sk_prot_free net/core/sock.c:2074 [inline]
 __sk_destruct+0x5df/0x750 net/core/sock.c:2166
 sk_destruct net/core/sock.c:2181 [inline]
 __sk_free+0x175/0x460 net/core/sock.c:2192
 sk_free+0x7c/0xa0 net/core/sock.c:2203
 sock_put include/net/sock.h:1991 [inline]
 nr_heartbeat_expiry+0x1d7/0x460 net/netrom/nr_timer.c:148
 call_timer_fn+0x1da/0x7c0 kernel/time/timer.c:1700
 expire_timers+0x2c6/0x5c0 kernel/time/timer.c:1751
 __run_timers kernel/time/timer.c:2022 [inline]
 __run_timers kernel/time/timer.c:1995 [inline]
 run_timer_softirq+0x326/0x910 kernel/time/timer.c:2035
 __do_softirq+0x1fb/0xadc kernel/softirq.c:571
Fixes 517a16b1a88b ("netrom: Decrease sock refcount when sock timers expire")
Reported-by [email protected]
---
 net/netrom/nr_timer.c | 1 +
 1 file changed, 1 insertion(+)
net/netrom/nr_timer.c +1 -0
index d1a0b7056743..1fb9084bb937 100644
@@ -125,6 +125,7 @@ static void nr_heartbeat_expiry(unsigned long param)
 		   is accepted() it isn't 'dead' so doesn't get removed. */
 		if (sock_flag(sk, SOCK_DESTROY) ||
 		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
+			sock_hold(sk);
 			bh_unlock_sock(sk);
 			nr_destroy_socket(sk);
 			goto out;
Signature · 1 line
2.39.0
author maintainer
#34 lore raw

PATCH 34/62 sctp: fail if no bound addresses can be used for a given scope

In reply to Greg Kroah-Hartman

From: Marcelo Ricardo Leitner <[email protected]>

[ Upstream commit 458e279f861d3f61796894cd158b780765a1569f ]

Currently, if you bind the socket to something like:

        servaddr.sin6_family = AF_INET6;
        servaddr.sin6_port = htons(0);
        servaddr.sin6_scope_id = 0;
        inet_pton(AF_INET6, "::1", &servaddr.sin6_addr);

And then request a connect to:

        connaddr.sin6_family = AF_INET6;
        connaddr.sin6_port = htons(20000);
        connaddr.sin6_scope_id = if_nametoindex("lo");
        inet_pton(AF_INET6, "fe88::1", &connaddr.sin6_addr);

What the stack does is:
- bind the socket
- create a new asoc
- to handle the connect
- copy the addresses that can be used for the given scope
- try to connect

But the copy returns 0 addresses, and the effect is that it ends up trying to connect as if the socket wasn't bound, which is not the desired behavior. This unexpected behavior also allows KASLR leaks through SCTP diag interface.

The fix here then is, if when trying to copy the addresses that can be used for the scope used in connect() it returns 0 addresses, bail out. This is what TCP does with a similar reproducer.

---
 net/sctp/bind_addr.c | 6 ++++++
 1 file changed, 6 insertions(+)
net/sctp/bind_addr.c +6 -0
index f8a283245672..d723942e5e65 100644
@@ -88,6 +88,12 @@ int sctp_bind_addr_copy(struct net *net, struct sctp_bind_addr *dest,
 		}
 	}
 
+	/* If somehow no addresses were found that can be used with this
+	 * scope, it's an error.
+	 */
+	if (list_empty(&dest->address_list))
+		error = -ENETUNREACH;
+
 out:
 	if (error)
 		sctp_bind_addr_clean(dest);
Signature · 1 line
2.39.0
author maintainer
#35 lore raw

PATCH 35/62 net: ravb: Fix possible hang if RIS2_QFF1 happen

In reply to Greg Kroah-Hartman

From: Yoshihiro Shimoda <[email protected]>

[ Upstream commit f3c07758c9007a6bfff5290d9e19d3c41930c897 ]

Since this driver enables the interrupt by RIC2_QFE1, this driver should clear the interrupt flag if it happens. Otherwise, the interrupt causes to hang the system.

Note that this also fix a minor coding style (a comment indentation) around the fixed code.

Fixes c156633f1353 ("Renesas Ethernet AVB driver proper")
---
 drivers/net/ethernet/renesas/ravb_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/renesas/ravb_main.c +2 -2
index 4c8a4e6efb9f..4acea1ab6000 100644
@@ -727,14 +727,14 @@ static void ravb_error_interrupt(struct net_device *ndev)
 	ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS);
 	if (eis & EIS_QFS) {
 		ris2 = ravb_read(ndev, RIS2);
-		ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED),
+		ravb_write(ndev, ~(RIS2_QFF0 | RIS2_QFF1 | RIS2_RFFF | RIS2_RESERVED),
 			   RIS2);
 
 		/* Receive Descriptor Empty int */
 		if (ris2 & RIS2_QFF0)
 			priv->stats[RAVB_BE].rx_over_errors++;
 
-		    /* Receive Descriptor Empty int */
+		/* Receive Descriptor Empty int */
 		if (ris2 & RIS2_QFF1)
 			priv->stats[RAVB_NC].rx_over_errors++;
 
Signature · 1 line
2.39.0
author maintainer
#36 lore raw

PATCH 36/62 net/tg3: resolve deadlock in tg3_reset_task() during EEH

In reply to Greg Kroah-Hartman

From: David Christensen <[email protected]>

[ Upstream commit 6c4ca03bd890566d873e3593b32d034bf2f5a087 ]

During EEH error injection testing, a deadlock was encountered in the tg3 driver when tg3_io_error_detected() was attempting to cancel outstanding reset tasks:

crash> foreach UN bt
...
PID: 159 TASK: c0000000067c6000 CPU: 8 COMMAND: "eehd"
...
#5 [c00000000681f990] __cancel_work_timer at c00000000019fd18 #6 [c00000000681fa30] tg3_io_error_detected at c00800000295f098 [tg3] #7 [c00000000681faf0] eeh_report_error at c00000000004e25c
...

PID: 290 TASK: c000000036e5f800 CPU: 6 COMMAND: "kworker/6:1"
...
#4 [c00000003721fbc0] rtnl_lock at c000000000c940d8 #5 [c00000003721fbe0] tg3_reset_task at c008000002969358 [tg3] #6 [c00000003721fc60] process_one_work at c00000000019e5c4
...

PID: 296 TASK: c000000037a65800 CPU: 21 COMMAND: "kworker/21:1"
...
#4 [c000000037247bc0] rtnl_lock at c000000000c940d8 #5 [c000000037247be0] tg3_reset_task at c008000002969358 [tg3] #6 [c000000037247c60] process_one_work at c00000000019e5c4
...

PID: 655 TASK: c000000036f49000 CPU: 16 COMMAND: "kworker/16:2"
...:1

#4 [c0000000373ebbc0] rtnl_lock at c000000000c940d8 #5 [c0000000373ebbe0] tg3_reset_task at c008000002969358 [tg3] #6 [c0000000373ebc60] process_one_work at c00000000019e5c4
...

Code inspection shows that both tg3_io_error_detected() and tg3_reset_task() attempt to acquire the RTNL lock at the beginning of their code blocks. If tg3_reset_task() should happen to execute between the times when tg3_io_error_deteced() acquires the RTNL lock and tg3_reset_task_cancel() is called, a deadlock will occur.

Moving tg3_reset_task_cancel() call earlier within the code block, prior to acquiring RTNL, prevents this from happening, but also exposes another deadlock issue where tg3_reset_task() may execute AFTER tg3_io_error_detected() has executed:

crash> foreach UN bt
PID: 159 TASK: c0000000067d2000 CPU: 9 COMMAND: "eehd"
...
#4 [c000000006867a60] rtnl_lock at c000000000c940d8
#5 [c000000006867a80] tg3_io_slot_reset at c0080000026c2ea8 [tg3] #6 [c000000006867b00] eeh_report_reset at c00000000004de88
...
PID: 363 TASK: c000000037564000 CPU: 6 COMMAND: "kworker/6:1"
...
#3 [c000000036c1bb70] msleep at c000000000259e6c
#4 [c000000036c1bba0] napi_disable at c000000000c6b848 #5 [c000000036c1bbe0] tg3_reset_task at c0080000026d942c [tg3] #6 [c000000036c1bc60] process_one_work at c00000000019e5c4
...

This issue can be avoided by aborting tg3_reset_task() if EEH error recovery is already in progress.

Fixes db84bf43ef23 ("tg3: tg3_reset_task() needs to use rtnl_lock to synchronize")
---
 drivers/net/ethernet/broadcom/tg3.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +4 -4
index 3279a6e48f3b..e0eacfc46dd4 100644
@@ -11158,7 +11158,7 @@ static void tg3_reset_task(struct work_struct *work)
 	rtnl_lock();
 	tg3_full_lock(tp, 0);
 
-	if (!netif_running(tp->dev)) {
+	if (tp->pcierr_recovery || !netif_running(tp->dev)) {
 		tg3_flag_clear(tp, RESET_TASK_PENDING);
 		tg3_full_unlock(tp);
 		rtnl_unlock();
@@ -18190,6 +18190,9 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
 
 	netdev_info(netdev, "PCI I/O error detected\n");
 
+	/* Want to make sure that the reset task doesn't run */
+	tg3_reset_task_cancel(tp);
+
 	rtnl_lock();
 
 	/* Could be second call or maybe we don't have netdev yet */
@@ -18206,9 +18209,6 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
 
 	tg3_timer_stop(tp);
 
-	/* Want to make sure that the reset task doesn't run */
-	tg3_reset_task_cancel(tp);
-
 	netif_device_detach(netdev);
 
 	/* Clean up software state, even if MMIO is blocked */
Signature · 1 line
2.39.0
author maintainer
#37 lore raw

PATCH 37/62 Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode"

In reply to Greg Kroah-Hartman

From: Dmitry Torokhov <[email protected]>

commit 3c44e2b6cde674797b76e76d3a903a63ce8a18bb upstream.

This reverts commit ac5408991ea6b06e29129b4d4861097c4c3e0d59 because it causes loss of keyboard on HP 15-da1xxx.

Fixes ac5408991ea6 ("Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode")

Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1206358

---
 drivers/input/mouse/synaptics.c |    1 -
 1 file changed, 1 deletion(-)
drivers/input/mouse/synaptics.c +0 -1
@@ -192,7 +192,6 @@ static const char * const smbus_pnp_ids[
 	"SYN3221", /* HP 15-ay000 */
 	"SYN323d", /* HP Spectre X360 13-w013dx */
 	"SYN3257", /* HP Envy 13-ad105ng */
-	"SYN3286", /* HP Laptop 15-da3001TU */
 	NULL
 };
 
author maintainer
#38 lore raw

PATCH 38/62 x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL

In reply to Greg Kroah-Hartman

From: Thomas Gleixner <[email protected]>

commit 5fa55950729d0762a787451dc52862c3f850f859 upstream.

Baoquan reported that after triggering a crash the subsequent crash-kernel fails to boot about half of the time. It triggers a NULL pointer dereference in the periodic tick code.

This happens because the legacy timer interrupt (IRQ0) is resent in software which happens in soft interrupt (tasklet) context. In this context get_irq_regs() returns NULL which leads to the NULL pointer dereference.

The reason for the resend is a spurious APIC interrupt on the IRQ0 vector which is captured and leads to a resend when the legacy timer interrupt is enabled. This is wrong because the legacy PIC interrupts are level triggered and therefore should never be resent in software, but nothing ever sets the IRQ_LEVEL flag on those interrupts, so the core code does not know about their trigger type.

Ensure that IRQ_LEVEL is set when the legacy PCI interrupts are set up.

---
 arch/x86/kernel/i8259.c   |    1 +
 arch/x86/kernel/irqinit.c |    4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)
arch/x86/kernel/i8259.c +1 -0
@@ -114,6 +114,7 @@ static void make_8259A_irq(unsigned int
 	disable_irq_nosync(irq);
 	io_apic_irqs &= ~(1<<irq);
 	irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+	irq_set_status_flags(irq, IRQ_LEVEL);
 	enable_irq(irq);
 }
 
arch/x86/kernel/irqinit.c +3 -1
@@ -67,8 +67,10 @@ void __init init_ISA_irqs(void)
 #endif
 	legacy_pic->init(0);
 
-	for (i = 0; i < nr_legacy_irqs(); i++)
+	for (i = 0; i < nr_legacy_irqs(); i++) {
 		irq_set_chip_and_handler(i, chip, handle_level_irq);
+		irq_set_status_flags(i, IRQ_LEVEL);
+	}
 }
 
 void __init init_IRQ(void)
author maintainer
#39 lore raw

PATCH 39/62 wifi: brcmfmac: fix up incorrect 4.14.y backport for brcmf_fw_map_chip_to_name()

In reply to Greg Kroah-Hartman

From: Greg Kroah-Hartman <[email protected]>

In commit bc45aa1911bf699b9905f12414e3c1879d6b784f which is commit 81d17f6f3331f03c8eafdacea68ab773426c1e3c upstream, the return value of the error condition needs to be reworked to return a real error and not NULL.

---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +1 -1
@@ -574,7 +574,7 @@ int brcmf_fw_map_chip_to_name(u32 chip,
 
 	if (chiprev >= BITS_PER_TYPE(u32)) {
 		brcmf_err("Invalid chip revision %u\n", chiprev);
-		return NULL;
+		return -EINVAL;
 	}
 
 	for (i = 0; i < table_size; i++) {
author maintainer
#40 lore raw

PATCH 40/62 xen: Fix up build warning with xen_init_time_ops() reference

In reply to Greg Kroah-Hartman

From: Greg Kroah-Hartman <[email protected]>

Somehow the xen_init_time_ops() reference got out of sync in the 4.14.y tree (or it never was in sync), and now there's a build warning. Fix that up by making xen_init_time_ops() be __init, not __ref.

---
 arch/x86/xen/time.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/xen/time.c +1 -1
index 03706331f567..8ecc38110bcc 100644
@@ -516,7 +516,7 @@ static void __init xen_time_init(void)
 		pvclock_gtod_register_notifier(&xen_pvclock_gtod_notifier);
 }
 
-void __ref xen_init_time_ops(void)
+void __init xen_init_time_ops(void)
 {
 	xen_sched_clock_offset = xen_clocksource_read();
 	pv_time_ops = xen_time_ops;
Signature · 1 line
2.39.1
author maintainer
#41 lore raw

PATCH 41/62 drm/radeon/dp: make radeon_dp_get_dp_link_config static

In reply to Greg Kroah-Hartman

From: Alex Deucher <[email protected]>

commit d3f04c98ead2b89887e1e3c09b26e4917bacdd9e upstream.

It's not used outside this file any longer.

---
 drivers/gpu/drm/radeon/atombios_dp.c |    8 ++++----
 drivers/gpu/drm/radeon/radeon_mode.h |    4 ----
 2 files changed, 4 insertions(+), 8 deletions(-)
drivers/gpu/drm/radeon/atombios_dp.c +4 -4
@@ -302,10 +302,10 @@ static int convert_bpc_to_bpp(int bpc)
 
 /***** radeon specific DP functions *****/
 
-int radeon_dp_get_dp_link_config(struct drm_connector *connector,
-				 const u8 dpcd[DP_DPCD_SIZE],
-				 unsigned pix_clock,
-				 unsigned *dp_lanes, unsigned *dp_rate)
+static int radeon_dp_get_dp_link_config(struct drm_connector *connector,
+					const u8 dpcd[DP_DPCD_SIZE],
+					unsigned pix_clock,
+					unsigned *dp_lanes, unsigned *dp_rate)
 {
 	int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector));
 	static const unsigned link_rates[3] = { 162000, 270000, 540000 };
drivers/gpu/drm/radeon/radeon_mode.h +0 -4
@@ -762,10 +762,6 @@ extern u8 radeon_dp_getsinktype(struct r
 extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
 extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
 				    struct drm_connector *connector);
-extern int radeon_dp_get_dp_link_config(struct drm_connector *connector,
-					const u8 *dpcd,
-					unsigned pix_clock,
-					unsigned *dp_lanes, unsigned *dp_rate);
 extern void radeon_dp_set_rx_power_state(struct drm_connector *connector,
 					 u8 power_state);
 extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector);
author maintainer
#42 lore raw

PATCH 42/62 scsi: qla2xxx: dont break the bsg-lib abstractions

In reply to Greg Kroah-Hartman

From: Christoph Hellwig <[email protected]>

commit 05231a3bb7981b01f6933c0a847fcaac25622bfd upstream.

Always use bsg_job->reply instead of scsi_req(bsg_job->req)->sense), as they always point to the same memory.

Never set scsi_req(bsg_job->req)->result and we'll set that value through bsg_job_done.

[mkp: applied by hand, fixed whitespace]

---
 drivers/scsi/qla2xxx/qla_bsg.c |   10 ++++------
 drivers/scsi/qla2xxx/qla_isr.c |   12 +++---------
 drivers/scsi/qla2xxx/qla_mr.c  |    3 +--
 3 files changed, 8 insertions(+), 17 deletions(-)
drivers/scsi/qla2xxx/qla_bsg.c +4 -6
@@ -924,9 +924,9 @@ qla2x00_process_loopback(struct bsg_job
 
 	bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
 	    sizeof(response) + sizeof(uint8_t);
-	fw_sts_ptr = ((uint8_t *)scsi_req(bsg_job->req)->sense) +
-	    sizeof(struct fc_bsg_reply);
-	memcpy(fw_sts_ptr, response, sizeof(response));
+	fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply);
+	memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), response,
+			sizeof(response));
 	fw_sts_ptr += sizeof(response);
 	*fw_sts_ptr = command_sent;
 
@@ -2558,13 +2558,11 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_
 						ql_log(ql_log_warn, vha, 0x7089,
 						    "mbx abort_command "
 						    "failed.\n");
-						scsi_req(bsg_job->req)->result =
 						bsg_reply->result = -EIO;
 					} else {
 						ql_dbg(ql_dbg_user, vha, 0x708a,
 						    "mbx abort_command "
 						    "success.\n");
-						scsi_req(bsg_job->req)->result =
 						bsg_reply->result = 0;
 					}
 					spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -2575,7 +2573,7 @@ qla24xx_bsg_timeout(struct bsg_job *bsg_
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 	ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
-	scsi_req(bsg_job->req)->result = bsg_reply->result = -ENXIO;
+	bsg_reply->result = -ENXIO;
 	return 0;
 
 done:
drivers/scsi/qla2xxx/qla_isr.c +3 -9
@@ -1540,7 +1540,6 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vh
 	struct fc_bsg_reply *bsg_reply;
 	uint16_t comp_status;
 	uint32_t fw_status[3];
-	uint8_t* fw_sts_ptr;
 	int res;
 
 	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
@@ -1601,11 +1600,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vh
 			    type, sp->handle, comp_status, fw_status[1], fw_status[2],
 			    le16_to_cpu(((struct els_sts_entry_24xx *)
 				pkt)->total_byte_count));
-			fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) +
-				sizeof(struct fc_bsg_reply);
-			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
-		}
-		else {
+		} else {
 			ql_dbg(ql_dbg_user, vha, 0x5040,
 			    "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
 			    "error subcode 1=0x%x error subcode 2=0x%x.\n",
@@ -1616,10 +1611,9 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vh
 				    pkt)->error_subcode_2));
 			res = DID_ERROR << 16;
 			bsg_reply->reply_payload_rcv_len = 0;
-			fw_sts_ptr = ((uint8_t*)scsi_req(bsg_job->req)->sense) +
-					sizeof(struct fc_bsg_reply);
-			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
 		}
+		memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply),
+		       fw_status, sizeof(fw_status));
 		ql_dump_buffer(ql_dbg_user + ql_dbg_buffer, vha, 0x5056,
 				(uint8_t *)pkt, sizeof(*pkt));
 	}
drivers/scsi/qla2xxx/qla_mr.c +1 -2
@@ -2222,8 +2222,7 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t
 		memcpy(fstatus.reserved_3,
 		    pkt->reserved_2, 20 * sizeof(uint8_t));
 
-		fw_sts_ptr = ((uint8_t *)scsi_req(bsg_job->req)->sense) +
-		    sizeof(struct fc_bsg_reply);
+		fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply);
 
 		memcpy(fw_sts_ptr, (uint8_t *)&fstatus,
 		    sizeof(struct qla_mt_iocb_rsp_fx00));
author maintainer
#43 lore raw

PATCH 43/62 x86/asm: Fix an assembler warning with current binutils

In reply to Greg Kroah-Hartman

From: Mikulas Patocka <[email protected]>

commit 55d235361fccef573990dfa5724ab453866e7816 upstream.

Fix a warning: "found movsd'; assuming movsl' was meant"

---
 arch/x86/lib/iomap_copy_64.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/lib/iomap_copy_64.S +1 -1
@@ -22,6 +22,6 @@
  */
 ENTRY(__iowrite32_copy)
 	movl %edx,%ecx
-	rep movsd
+	rep movsl
 	ret
 ENDPROC(__iowrite32_copy)
author maintainer
#44 lore raw

PATCH 44/62 x86/entry/64: Add instruction suffix to SYSRET

In reply to Greg Kroah-Hartman

From: Jan Beulich <[email protected]>

commit b2b1d94cdfd4e906d3936dab2850096a4a0c2017 upstream.

ignore_sysret() contains an unsuffixed SYSRET instruction. gas correctly interprets this as SYSRETL, but leaving it up to gas to guess when there is no register operand that implies a size is bad practice, and upstream gas is likely to warn about this in the future. Use SYSRETL explicitly. This does not change the assembled output.

---
 arch/x86/entry/entry_64.S |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/entry/entry_64.S +1 -1
@@ -1669,7 +1669,7 @@ END(nmi)
 ENTRY(ignore_sysret)
 	UNWIND_HINT_EMPTY
 	mov	$-ENOSYS, %eax
-	sysret
+	sysretl
 END(ignore_sysret)
 
 ENTRY(rewind_stack_do_exit)
author maintainer
#45 lore raw

PATCH 45/62 sysctl: add a new register_sysctl_init() interface

In reply to Greg Kroah-Hartman

From: Xiaoming Ni <[email protected]>

commit 3ddd9a808cee7284931312f2f3e854c9617f44b2 upstream.

Patch series "sysctl: first set of kernel/sysctl cleanups", v2.

Finally had time to respin the series of the work we had started last year on cleaning up the kernel/sysct.c kitchen sink. People keeps stuffing their sysctls in that file and this creates a maintenance burden. So this effort is aimed at placing sysctls where they actually belong.

I'm going to split patches up into series as there is quite a bit of work.

This first set adds register_sysctl_init() for uses of registerting a sysctl on the init path, adds const where missing to a few places, generalizes common values so to be more easy to share, and starts the move of a few kernel/sysctl.c out where they belong.

The majority of rework on v2 in this first patch set is 0-day fixes. Eric Biederman's feedback is later addressed in subsequent patch sets.

I'll only post the first two patch sets for now. We can address the rest once the first two patch sets get completely reviewed / Acked.

This patch (of 9):

The kernel/sysctl.c is a kitchen sink where everyone leaves their dirty dishes, this makes it very difficult to maintain.

To help with this maintenance let's start by moving sysctls to places where they actually belong. The proc sysctl maintainers do not want to know what sysctl knobs you wish to add for your own piece of code, we just care about the core logic.

Today though folks heavily rely on tables on kernel/sysctl.c so they can easily just extend this table with their needed sysctls. In order to help users move their sysctls out we need to provide a helper which can be used during code initialization.

We special-case the initialization use of register_sysctl() since it *is* safe to fail, given all that sysctls do is provide a dynamic interface to query or modify at runtime an existing variable. So the use case of register_sysctl() on init should *not* stop if the sysctls don't end up getting registered. It would be counter productive to stop boot if a simple sysctl registration failed.

Provide a helper for init then, and document the recommended init levels to use for callers of this routine. We will later use this in subsequent patches to start slimming down kernel/sysctl.c tables and moving sysctl registration to the code which actually needs these sysctls.

[[email protected]: major commit log and documentation rephrasing also moved to fs/proc/proc_sysctl.c ]

Cc Iurii Zaikin <[email protected]>
Cc "Eric W. Biederman" <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Greg Kroah-Hartman <[email protected]>
Cc Paul Turner <[email protected]>
Cc Andy Shevchenko <[email protected]>
Cc Sebastian Reichel <[email protected]>
Cc Tetsuo Handa <[email protected]>
Cc Petr Mladek <[email protected]>
Cc Sergey Senozhatsky <[email protected]>
Cc Qing Wang <[email protected]>
Cc Benjamin LaHaise <[email protected]>
Cc Al Viro <[email protected]>
Cc Jan Kara <[email protected]>
Cc Amir Goldstein <[email protected]>
Cc Stephen Kitt <[email protected]>
Cc Antti Palosaari <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Benjamin Herrenschmidt <[email protected]>
Cc Clemens Ladisch <[email protected]>
Cc David Airlie <[email protected]>
Cc Jani Nikula <[email protected]>
Cc Joel Becker <[email protected]>
Cc Joonas Lahtinen <[email protected]>
Cc Joseph Qi <[email protected]>
Cc Julia Lawall <[email protected]>
Cc Lukas Middendorf <[email protected]>
Cc Mark Fasheh <[email protected]>
Cc Phillip Potter <[email protected]>
Cc Rodrigo Vivi <[email protected]>
Cc Douglas Gilbert <[email protected]>
Cc James E.J. Bottomley <[email protected]>
Cc Jani Nikula <[email protected]>
Cc John Ogness <[email protected]>
Cc Martin K. Petersen <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
Cc Steven Rostedt (VMware) <[email protected]>
Cc Suren Baghdasaryan <[email protected]>
Cc "Theodore Ts'o" <[email protected]>
---
 fs/proc/proc_sysctl.c  |   33 +++++++++++++++++++++++++++++++++
 include/linux/sysctl.h |    3 +++
 2 files changed, 36 insertions(+)
fs/proc/proc_sysctl.c +33 -0
@@ -13,6 +13,7 @@
 #include <linux/namei.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/kmemleak.h>
 #include "internal.h"
 
 static const struct dentry_operations proc_sys_dentry_operations;
@@ -1370,6 +1371,38 @@ struct ctl_table_header *register_sysctl
 }
 EXPORT_SYMBOL(register_sysctl);
 
+/**
+ * __register_sysctl_init() - register sysctl table to path
+ * @path: path name for sysctl base
+ * @table: This is the sysctl table that needs to be registered to the path
+ * @table_name: The name of sysctl table, only used for log printing when
+ *              registration fails
+ *
+ * The sysctl interface is used by userspace to query or modify at runtime
+ * a predefined value set on a variable. These variables however have default
+ * values pre-set. Code which depends on these variables will always work even
+ * if register_sysctl() fails. If register_sysctl() fails you'd just loose the
+ * ability to query or modify the sysctls dynamically at run time. Chances of
+ * register_sysctl() failing on init are extremely low, and so for both reasons
+ * this function does not return any error as it is used by initialization code.
+ *
+ * Context: Can only be called after your respective sysctl base path has been
+ * registered. So for instance, most base directories are registered early on
+ * init before init levels are processed through proc_sys_init() and
+ * sysctl_init().
+ */
+void __init __register_sysctl_init(const char *path, struct ctl_table *table,
+				 const char *table_name)
+{
+	struct ctl_table_header *hdr = register_sysctl(path, table);
+
+	if (unlikely(!hdr)) {
+		pr_err("failed when register_sysctl %s to %s\n", table_name, path);
+		return;
+	}
+	kmemleak_not_leak(hdr);
+}
+
 static char *append_path(const char *path, char *pos, const char *name)
 {
 	int namelen;
include/linux/sysctl.h +3 -0
@@ -198,6 +198,9 @@ struct ctl_table_header *register_sysctl
 void unregister_sysctl_table(struct ctl_table_header * table);
 
 extern int sysctl_init(void);
+extern void __register_sysctl_init(const char *path, struct ctl_table *table,
+				 const char *table_name);
+#define register_sysctl_init(path, table) __register_sysctl_init(path, table, #table)
 
 extern struct ctl_table sysctl_mount_point[];
 
author maintainer
#46 lore raw

PATCH 46/62 panic: unset panic_on_warn inside panic()

In reply to Greg Kroah-Hartman

From: Tiezhu Yang <[email protected]>

commit 1a2383e8b84c0451fd9b1eec3b9aab16f30b597c upstream.

In the current code, the following three places need to unset panic_on_warn before calling panic() to avoid recursive panics:

kernel/kcsan/report.c: print_report()
kernel/sched/core.c: __schedule_bug()
mm/kfence/report.c: kfence_report_error()

In order to avoid copy-pasting "panic_on_warn = 0" all over the places, it is better to move it inside panic() and then remove it from the other places.

---
 kernel/panic.c |   20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
kernel/panic.c +11 -9
@@ -139,6 +139,16 @@ void panic(const char *fmt, ...)
 	int old_cpu, this_cpu;
 	bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers;
 
+	if (panic_on_warn) {
+		/*
+		 * This thread may hit another WARN() in the panic path.
+		 * Resetting this prevents additional WARN() from panicking the
+		 * system on this thread.  Other threads are blocked by the
+		 * panic_mutex in panic().
+		 */
+		panic_on_warn = 0;
+	}
+
 	/*
 	 * Disable local interrupts. This will prevent panic_smp_self_stop
 	 * from deadlocking the first cpu that invokes the panic, since
@@ -536,16 +546,8 @@ void __warn(const char *file, int line,
 	if (args)
 		vprintk(args->fmt, args->args);
 
-	if (panic_on_warn) {
-		/*
-		 * This thread may hit another WARN() in the panic path.
-		 * Resetting this prevents additional WARN() from panicking the
-		 * system on this thread.  Other threads are blocked by the
-		 * panic_mutex in panic().
-		 */
-		panic_on_warn = 0;
+	if (panic_on_warn)
 		panic("panic_on_warn set ...\n");
-	}
 
 	print_modules();
 
author maintainer
#47 lore raw

PATCH 47/62 exit: Add and use make_task_dead.

In reply to Greg Kroah-Hartman

From: "Eric W. Biederman" <[email protected]>

commit 0e25498f8cd43c1b5aa327f373dd094e9a006da7 upstream.

There are two big uses of do_exit. The first is it's design use to be the guts of the exit(2) system call. The second use is to terminate a task after something catastrophic has happened like a NULL pointer in kernel code.

Add a function make_task_dead that is initialy exactly the same as do_exit to cover the cases where do_exit is called to handle catastrophic failure. In time this can probably be reduced to just a light wrapper around do_task_dead. For now keep it exactly the same so that there will be no behavioral differences introducing this new concept.

Replace all of the uses of do_exit that use it for catastraphic task cleanup with make_task_dead to make it clear what the code is doing.

As part of this rename rewind_stack_do_exit
rewind_stack_and_make_dead.

---
 arch/alpha/kernel/traps.c           |    6 +++---
 arch/alpha/mm/fault.c               |    2 +-
 arch/arm/kernel/traps.c             |    2 +-
 arch/arm/mm/fault.c                 |    2 +-
 arch/arm64/kernel/traps.c           |    2 +-
 arch/arm64/mm/fault.c               |    2 +-
 arch/h8300/kernel/traps.c           |    2 +-
 arch/h8300/mm/fault.c               |    2 +-
 arch/hexagon/kernel/traps.c         |    2 +-
 arch/ia64/kernel/mca_drv.c          |    2 +-
 arch/ia64/kernel/traps.c            |    2 +-
 arch/ia64/mm/fault.c                |    2 +-
 arch/m68k/kernel/traps.c            |    2 +-
 arch/m68k/mm/fault.c                |    2 +-
 arch/microblaze/kernel/exceptions.c |    4 ++--
 arch/mips/kernel/traps.c            |    2 +-
 arch/nios2/kernel/traps.c           |    4 ++--
 arch/openrisc/kernel/traps.c        |    2 +-
 arch/parisc/kernel/traps.c          |    2 +-
 arch/powerpc/kernel/traps.c         |    2 +-
 arch/s390/kernel/dumpstack.c        |    2 +-
 arch/s390/kernel/nmi.c              |    2 +-
 arch/sh/kernel/traps.c              |    2 +-
 arch/sparc/kernel/traps_32.c        |    4 +---
 arch/sparc/kernel/traps_64.c        |    4 +---
 arch/x86/entry/entry_32.S           |    6 +++---
 arch/x86/entry/entry_64.S           |    6 +++---
 arch/x86/kernel/dumpstack.c         |    4 ++--
 arch/xtensa/kernel/traps.c          |    2 +-
 include/linux/sched/task.h          |    1 +
 kernel/exit.c                       |    9 +++++++++
 tools/objtool/check.c               |    3 ++-
 32 files changed, 50 insertions(+), 43 deletions(-)
arch/alpha/kernel/traps.c +3 -3
@@ -192,7 +192,7 @@ die_if_kernel(char * str, struct pt_regs
 		local_irq_enable();
 		while (1);
 	}
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 #ifndef CONFIG_MATHEMU
@@ -609,7 +609,7 @@ do_entUna(void * va, unsigned long opcod
 
 	printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n",
 		pc, va, opcode, reg);
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 
 got_exception:
 	/* Ok, we caught the exception, but we don't want it.  Is there
@@ -664,7 +664,7 @@ got_exception:
 		local_irq_enable();
 		while (1);
 	}
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 /*
arch/alpha/mm/fault.c +1 -1
@@ -206,7 +206,7 @@ retry:
 	printk(KERN_ALERT "Unable to handle kernel paging request at "
 	       "virtual address %016lx\n", address);
 	die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 
 	/* We ran out of memory, or some other thing happened to us that
 	   made us unable to handle the page fault gracefully.  */
arch/arm/kernel/traps.c +1 -1
@@ -342,7 +342,7 @@ static void oops_end(unsigned long flags
 	if (panic_on_oops)
 		panic("Fatal exception");
 	if (signr)
-		do_exit(signr);
+		make_task_dead(signr);
 }
 
 /*
arch/arm/mm/fault.c +1 -1
@@ -150,7 +150,7 @@ __do_kernel_fault(struct mm_struct *mm,
 	show_pte(mm, addr);
 	die("Oops", regs, fsr);
 	bust_spinlocks(0);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 /*
arch/arm64/kernel/traps.c +1 -1
@@ -223,7 +223,7 @@ void die(const char *str, struct pt_regs
 	raw_spin_unlock_irqrestore(&die_lock, flags);
 
 	if (ret != NOTIFY_STOP)
-		do_exit(SIGSEGV);
+		make_task_dead(SIGSEGV);
 }
 
 void arm64_notify_die(const char *str, struct pt_regs *regs,
arch/arm64/mm/fault.c +1 -1
@@ -288,7 +288,7 @@ static void __do_kernel_fault(unsigned l
 	show_pte(addr);
 	die("Oops", regs, esr);
 	bust_spinlocks(0);
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 /*
arch/h8300/kernel/traps.c +1 -1
@@ -110,7 +110,7 @@ void die(const char *str, struct pt_regs
 	dump(fp);
 
 	spin_unlock_irq(&die_lock);
-	do_exit(SIGSEGV);
+	make_dead_task(SIGSEGV);
 }
 
 static int kstack_depth_to_print = 24;
arch/h8300/mm/fault.c +1 -1
@@ -52,7 +52,7 @@ asmlinkage int do_page_fault(struct pt_r
 	printk(" at virtual address %08lx\n", address);
 	if (!user_mode(regs))
 		die("Oops", regs, error_code);
-	do_exit(SIGKILL);
+	make_dead_task(SIGKILL);
 
 	return 1;
 }
arch/hexagon/kernel/traps.c +1 -1
@@ -234,7 +234,7 @@ int die(const char *str, struct pt_regs
 		panic("Fatal exception");
 
 	oops_exit();
-	do_exit(err);
+	make_dead_task(err);
 	return 0;
 }
 
arch/ia64/kernel/mca_drv.c +1 -1
@@ -176,7 +176,7 @@ mca_handler_bh(unsigned long paddr, void
 	spin_unlock(&mca_bh_lock);
 
 	/* This process is about to be killed itself */
-	do_exit(SIGKILL);
+	make_task_dead(SIGKILL);
 }
 
 /**
arch/ia64/kernel/traps.c +1 -1
@@ -85,7 +85,7 @@ die (const char *str, struct pt_regs *re
 	if (panic_on_oops)
 		panic("Fatal exception");
 
-  	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 	return 0;
 }
 
arch/ia64/mm/fault.c +1 -1
@@ -300,7 +300,7 @@ retry:
 		regs = NULL;
 	bust_spinlocks(0);
 	if (regs)
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	return;
 
   out_of_memory:
arch/m68k/kernel/traps.c +1 -1
@@ -1141,7 +1141,7 @@ void die_if_kernel (char *str, struct pt
 	pr_crit("%s: %08x\n", str, nr);
 	show_registers(fp);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 asmlinkage void set_esp0(unsigned long ssp)
arch/m68k/mm/fault.c +1 -1
@@ -50,7 +50,7 @@ int send_fault_sig(struct pt_regs *regs)
 			pr_alert("Unable to handle kernel access");
 		pr_cont(" at virtual address %p\n", siginfo.si_addr);
 		die_if_kernel("Oops", regs, 0 /*error_code*/);
-		do_exit(SIGKILL);
+		make_task_dead(SIGKILL);
 	}
 
 	return 1;
arch/microblaze/kernel/exceptions.c +2 -2
@@ -44,10 +44,10 @@ void die(const char *str, struct pt_regs
 	pr_warn("Oops: %s, sig: %ld\n", str, err);
 	show_regs(fp);
 	spin_unlock_irq(&die_lock);
-	/* do_exit() should take care of panic'ing from an interrupt
+	/* make_task_dead() should take care of panic'ing from an interrupt
 	 * context so we don't handle it here
 	 */
-	do_exit(err);
+	make_task_dead(err);
 }
 
 /* for user application debugging */
arch/mips/kernel/traps.c +1 -1
@@ -414,7 +414,7 @@ void __noreturn die(const char *str, str
 	if (regs && kexec_should_crash(current))
 		crash_kexec(regs);
 
-	do_exit(sig);
+	make_task_dead(sig);
 }
 
 extern struct exception_table_entry __start___dbe_table[];
arch/nios2/kernel/traps.c +2 -2
@@ -43,10 +43,10 @@ void die(const char *str, struct pt_regs
 	show_regs(regs);
 	spin_unlock_irq(&die_lock);
 	/*
-	 * do_exit() should take care of panic'ing from an interrupt
+	 * make_task_dead() should take care of panic'ing from an interrupt
 	 * context so we don't handle it here
 	 */
-	do_exit(err);
+	make_task_dead(err);
 }
 
 void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr)
arch/openrisc/kernel/traps.c +1 -1
@@ -265,7 +265,7 @@ void die(const char *str, struct pt_regs
 	__asm__ __volatile__("l.nop   1");
 	do {} while (1);
 #endif
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 /* This is normally the 'Oops' routine */
arch/parisc/kernel/traps.c +1 -1
@@ -290,7 +290,7 @@ void die_if_kernel(char *str, struct pt_
 		panic("Fatal exception");
 
 	oops_exit();
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 /* gdb uses break 4,8 */
arch/powerpc/kernel/traps.c +1 -1
@@ -211,7 +211,7 @@ static void oops_end(unsigned long flags
 		panic("Fatal exception in interrupt");
 	if (panic_on_oops)
 		panic("Fatal exception");
-	do_exit(signr);
+	make_task_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
arch/s390/kernel/dumpstack.c +1 -1
@@ -186,5 +186,5 @@ void die(struct pt_regs *regs, const cha
 	if (panic_on_oops)
 		panic("Fatal exception: panic_on_oops");
 	oops_exit();
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
arch/s390/kernel/nmi.c +1 -1
@@ -94,7 +94,7 @@ void s390_handle_mcck(void)
 		       "malfunction (code 0x%016lx).\n", mcck.mcck_code);
 		printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
 		       current->comm, current->pid);
-		do_exit(SIGSEGV);
+		make_task_dead(SIGSEGV);
 	}
 }
 EXPORT_SYMBOL_GPL(s390_handle_mcck);
arch/sh/kernel/traps.c +1 -1
@@ -57,7 +57,7 @@ void die(const char *str, struct pt_regs
 	if (panic_on_oops)
 		panic("Fatal exception");
 
-	do_exit(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 void die_if_kernel(const char *str, struct pt_regs *regs, long err)
arch/sparc/kernel/traps_32.c +1 -3
@@ -86,9 +86,7 @@ void __noreturn die_if_kernel(char *str,
 	}
 	printk("Instruction DUMP:");
 	instruction_dump ((unsigned long *) regs->pc);
-	if(regs->psr & PSR_PS)
-		do_exit(SIGKILL);
-	do_exit(SIGSEGV);
+	make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV);
 }
 
 void do_hw_interrupt(struct pt_regs *regs, unsigned long type)
arch/sparc/kernel/traps_64.c +1 -3
@@ -2547,9 +2547,7 @@ void __noreturn die_if_kernel(char *str,
 	}
 	if (panic_on_oops)
 		panic("Fatal exception");
-	if (regs->tstate & TSTATE_PRIV)
-		do_exit(SIGKILL);
-	do_exit(SIGSEGV);
+	make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV);
 }
 EXPORT_SYMBOL(die_if_kernel);
 
arch/x86/entry/entry_32.S +3 -3
@@ -1068,13 +1068,13 @@ ENTRY(async_page_fault)
 END(async_page_fault)
 #endif
 
-ENTRY(rewind_stack_do_exit)
+ENTRY(rewind_stack_and_make_dead)
 	/* Prevent any naive code from trying to unwind to our caller. */
 	xorl	%ebp, %ebp
 
 	movl	PER_CPU_VAR(cpu_current_top_of_stack), %esi
 	leal	-TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp
 
-	call	do_exit
+	call	make_task_dead
 1:	jmp 1b
-END(rewind_stack_do_exit)
+END(rewind_stack_and_make_dead)
arch/x86/entry/entry_64.S +3 -3
@@ -1672,7 +1672,7 @@ ENTRY(ignore_sysret)
 	sysretl
 END(ignore_sysret)
 
-ENTRY(rewind_stack_do_exit)
+ENTRY(rewind_stack_and_make_dead)
 	UNWIND_HINT_FUNC
 	/* Prevent any naive code from trying to unwind to our caller. */
 	xorl	%ebp, %ebp
@@ -1681,5 +1681,5 @@ ENTRY(rewind_stack_do_exit)
 	leaq	-PTREGS_SIZE(%rax), %rsp
 	UNWIND_HINT_REGS
 
-	call	do_exit
-END(rewind_stack_do_exit)
+	call	make_task_dead
+END(rewind_stack_and_make_dead)
arch/x86/kernel/dumpstack.c +2 -2
@@ -271,7 +271,7 @@ unsigned long oops_begin(void)
 EXPORT_SYMBOL_GPL(oops_begin);
 NOKPROBE_SYMBOL(oops_begin);
 
-void __noreturn rewind_stack_do_exit(int signr);
+void __noreturn rewind_stack_and_make_dead(int signr);
 
 void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
 {
@@ -303,7 +303,7 @@ void oops_end(unsigned long flags, struc
 	 * reuse the task stack and that existing poisons are invalid.
 	 */
 	kasan_unpoison_task_stack(current);
-	rewind_stack_do_exit(signr);
+	rewind_stack_and_make_dead(signr);
 }
 NOKPROBE_SYMBOL(oops_end);
 
arch/xtensa/kernel/traps.c +1 -1
@@ -547,5 +547,5 @@ void die(const char * str, struct pt_reg
 	if (panic_on_oops)
 		panic("Fatal exception");
 
-	do_exit(err);
+	make_task_dead(err);
 }
include/linux/sched/task.h +1 -0
@@ -36,6 +36,7 @@ extern int sched_fork(unsigned long clon
 extern void sched_dead(struct task_struct *p);
 
 void __noreturn do_task_dead(void);
+void __noreturn make_task_dead(int signr);
 
 extern void proc_caches_init(void);
 
kernel/exit.c +9 -0
@@ -920,6 +920,15 @@ void __noreturn do_exit(long code)
 }
 EXPORT_SYMBOL_GPL(do_exit);
 
+void __noreturn make_task_dead(int signr)
+{
+	/*
+	 * Take the task off the cpu after something catastrophic has
+	 * happened.
+	 */
+	do_exit(signr);
+}
+
 void complete_and_exit(struct completion *comp, long code)
 {
 	if (comp)
tools/objtool/check.c +2 -1
@@ -159,6 +159,7 @@ static int __dead_end_function(struct ob
 		"panic",
 		"do_exit",
 		"do_task_dead",
+		"make_task_dead",
 		"__module_put_and_exit",
 		"complete_and_exit",
 		"kvm_spurious_fault",
@@ -166,7 +167,7 @@ static int __dead_end_function(struct ob
 		"lbug_with_loc",
 		"fortify_panic",
 		"machine_real_restart",
-		"rewind_stack_do_exit",
+		"rewind_stack_and_make_dead"
 	};
 
 	if (func->bind == STB_WEAK)
author maintainer
#48 lore raw

PATCH 48/62 objtool: Add a missing comma to avoid string concatenation

In reply to Greg Kroah-Hartman

From: "Eric W. Biederman" <[email protected]>

commit 1fb466dff904e4a72282af336f2c355f011eec61 upstream.

Recently the kbuild robot reported two new errors:

Quoted 2 lines
Quoted 2 lines

lib/kunit/kunit-example-test.o: warning: objtool: .text.unlikely: unexpected end of section arch/x86/kernel/dumpstack.o: warning: objtool: oops_end() falls through to next function show_opcodes()

I don't know why they did not occur in my test setup but after digging it I realized I had accidentally dropped a comma in tools/objtool/check.c when I renamed rewind_stack_do_exit to rewind_stack_and_make_dead.

Add that comma back to fix objtool errors.

---
 tools/objtool/check.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/objtool/check.c +1 -1
@@ -167,7 +167,7 @@ static int __dead_end_function(struct ob
 		"lbug_with_loc",
 		"fortify_panic",
 		"machine_real_restart",
-		"rewind_stack_and_make_dead"
+		"rewind_stack_and_make_dead",
 	};
 
 	if (func->bind == STB_WEAK)
author maintainer
#49 lore raw

PATCH 49/62 hexagon: Fix function name in die()

In reply to Greg Kroah-Hartman

From: Nathan Chancellor <[email protected]>

commit 4f0712ccec09c071e221242a2db9a6779a55a949 upstream.

When building ARCH=hexagon defconfig:

arch/hexagon/kernel/traps.c:217:2: error: implicit declaration of function 'make_dead_task' [-Werror,-Wimplicit-function-declaration]

        make_dead_task(err);
        ^

The function's name is make_task_dead(), change it so there is no more build error.

---
 arch/hexagon/kernel/traps.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/hexagon/kernel/traps.c +1 -1
@@ -234,7 +234,7 @@ int die(const char *str, struct pt_regs
 		panic("Fatal exception");
 
 	oops_exit();
-	make_dead_task(err);
+	make_task_dead(err);
 	return 0;
 }
 
author maintainer
#50 lore raw

PATCH 50/62 h8300: Fix build errors from do_exit() to make_task_dead() transition

In reply to Greg Kroah-Hartman

From: Nathan Chancellor <[email protected]>

commit ab4ababdf77ccc56c7301c751dff49c79709c51c upstream.

When building ARCH=h8300 defconfig:

arch/h8300/kernel/traps.c: In function 'die':
arch/h8300/kernel/traps.c:109:2: error: implicit declaration of function 'make_dead_task' [-Werror=implicit-function-declaration]

  109 |  make_dead_task(SIGSEGV);
      |  ^~~~~~~~~~~~~~

arch/h8300/mm/fault.c: In function 'do_page_fault':
arch/h8300/mm/fault.c:54:2: error: implicit declaration of function 'make_dead_task' [-Werror=implicit-function-declaration]

   54 |  make_dead_task(SIGKILL);
      |  ^~~~~~~~~~~~~~

The function's name is make_task_dead(), change it so there is no more build error.

Additionally, include linux/sched/task.h in arch/h8300/kernel/traps.c to avoid the same error because do_exit()'s declaration is in kernel.h but make_task_dead()'s is in task.h, which is not included in traps.c.

---
 arch/h8300/kernel/traps.c |    3 ++-
 arch/h8300/mm/fault.c     |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
arch/h8300/kernel/traps.c +2 -1
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/task.h>
 #include <linux/mm_types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -110,7 +111,7 @@ void die(const char *str, struct pt_regs
 	dump(fp);
 
 	spin_unlock_irq(&die_lock);
-	make_dead_task(SIGSEGV);
+	make_task_dead(SIGSEGV);
 }
 
 static int kstack_depth_to_print = 24;
arch/h8300/mm/fault.c +1 -1
@@ -52,7 +52,7 @@ asmlinkage int do_page_fault(struct pt_r
 	printk(" at virtual address %08lx\n", address);
 	if (!user_mode(regs))
 		die("Oops", regs, error_code);
-	make_dead_task(SIGKILL);
+	make_task_dead(SIGKILL);
 
 	return 1;
 }
author maintainer
#51 lore raw

PATCH 51/62 ia64: make IA64_MCA_RECOVERY bool instead of tristate

In reply to Greg Kroah-Hartman

From: Randy Dunlap <[email protected]>

commit dbecf9b8b8ce580f4e11afed9d61e8aa294cddd2 upstream.

In linux-next, IA64_MCA_RECOVERY uses the (new) function make_task_dead(), which is not exported for use by modules. Instead of exporting it for one user, convert IA64_MCA_RECOVERY to be a bool Kconfig symbol.

In a config file from "kernel test robot <[email protected]>" for a different problem, this linker error was exposed when CONFIG_IA64_MCA_RECOVERY=m.

Fixes this build error:

ERROR: modpost: "make_task_dead" [arch/ia64/kernel/mca_recovery.ko] undefined!

---
 arch/ia64/Kconfig |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/ia64/Kconfig +1 -1
@@ -461,7 +461,7 @@ config ARCH_PROC_KCORE_TEXT
 	depends on PROC_KCORE
 
 config IA64_MCA_RECOVERY
-	tristate "MCA recovery from errors other than TLB."
+	bool "MCA recovery from errors other than TLB."
 
 config PERFMON
 	bool "Performance monitor support"
author maintainer
#52 lore raw

PATCH 52/62 exit: Put an upper limit on how often we can oops

In reply to Greg Kroah-Hartman

From: Jann Horn <[email protected]>

commit d4ccd54d28d3c8598e2354acc13e28c060961dbb upstream.

Many Linux systems are configured to not panic on oops; but allowing an attacker to oops the system **really** often can make even bugs that look completely unexploitable exploitable (like NULL dereferences and such) if each crash elevates a refcount by one or a lock is taken in read mode, and this causes a counter to eventually overflow.

The most interesting counters for this are 32 bits wide (like open-coded refcounts that don't use refcount_t). (The ldsem reader count on 32-bit platforms is just 16 bits, but probably nobody cares about 32-bit platforms that much nowadays.)

So let's panic the system if the kernel is constantly oopsing.

The speed of oopsing 2^32 times probably depends on several factors, like how long the stack trace is and which unwinder you're using; an empirically important one is whether your console is showing a graphical environment or a text console that oopses will be printed to.
In a quick single-threaded benchmark, it looks like oopsing in a vfork() child with a very short stack trace only takes ~510 microseconds per run when a graphical console is active; but switching to a text console that oopses are printed to slows it down around 87x, to ~45 milliseconds per run.
(Adding more threads makes this faster, but the actual oops printing happens under &die_lock on x86, so you can maybe speed this up by a factor of around 2 and then any further improvement gets eaten up by lock contention.)

It looks like it would take around 8-12 days to overflow a 32-bit counter with repeated oopsing on a multi-core X86 system running a graphical environment; both me (in an X86 VM) and Seth (with a distro kernel on normal hardware in a standard configuration) got numbers in that ballpark.

12 days aren't *that* short on a desktop system, and you'd likely need much longer on a typical server system (assuming that people don't run graphical desktop environments on their servers), and this is a *very* noisy and violent approach to exploiting the kernel; and it also seems to take orders of magnitude longer on some machines, probably because stuff like EFI pstore will slow it down a ton if that's active.

---
 Documentation/sysctl/kernel.txt |    9 ++++++++
 kernel/exit.c                   |   43 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)
Documentation/sysctl/kernel.txt +9 -0
@@ -48,6 +48,7 @@ show up in /proc/sys/kernel:
 - msgmnb
 - msgmni
 - nmi_watchdog
+- oops_limit
 - osrelease
 - ostype
 - overflowgid
@@ -515,6 +516,14 @@ scanned for a given scan.
 
 ==============================================================
 
+oops_limit:
+
+Number of kernel oopses after which the kernel should panic when
+``panic_on_oops`` is not set. Setting this to 0 or 1 has the same effect
+as setting ``panic_on_oops=1``.
+
+==============================================================
+
 osrelease, ostype & version:
 
 # cat osrelease
kernel/exit.c +43 -0

59 lines not on this page · raw message

author maintainer
#53 lore raw

PATCH 53/62 exit: Expose "oops_count" to sysfs

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit 9db89b41117024f80b38b15954017fb293133364 upstream.

Since Oops count is now tracked and is a fairly interesting signal, add the entry /sys/kernel/oops_count to expose it to userspace.

---
 Documentation/ABI/testing/sysfs-kernel-oops_count |    6 ++++++
 kernel/exit.c                                     |   22 ++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-oops_count
Documentation/ABI/testing/sysfs-kernel-oops_count new file +6 -0
@@ -0,0 +1,6 @@
+What:		/sys/kernel/oops_count
+Date:		November 2022
+KernelVersion:	6.2.0
+Contact:	Linux Kernel Hardening List <[email protected]>
+Description:
+		Shows how many times the system has Oopsed since last boot.
kernel/exit.c +20 -2
@@ -62,6 +62,7 @@
 #include <linux/random.h>
 #include <linux/rcuwait.h>
 #include <linux/compat.h>
+#include <linux/sysfs.h>
 
 #include <linux/uaccess.h>
 #include <asm/unistd.h>
@@ -95,6 +96,25 @@ static __init int kernel_exit_sysctls_in
 late_initcall(kernel_exit_sysctls_init);
 #endif
 
+static atomic_t oops_count = ATOMIC_INIT(0);
+
+#ifdef CONFIG_SYSFS
+static ssize_t oops_count_show(struct kobject *kobj, struct kobj_attribute *attr,
+			       char *page)
+{
+	return sysfs_emit(page, "%d\n", atomic_read(&oops_count));
+}
+
+static struct kobj_attribute oops_count_attr = __ATTR_RO(oops_count);
+
+static __init int kernel_exit_sysfs_init(void)
+{
+	sysfs_add_file_to_group(kernel_kobj, &oops_count_attr.attr, NULL);
+	return 0;
+}
+late_initcall(kernel_exit_sysfs_init);
+#endif
+
 static void __unhash_process(struct task_struct *p, bool group_dead)
 {
 	nr_threads--;
@@ -949,8 +969,6 @@ EXPORT_SYMBOL_GPL(do_exit);
 
 void __noreturn make_task_dead(int signr)
 {
-	static atomic_t oops_count = ATOMIC_INIT(0);
-
 	/*
 	 * Take the task off the cpu after something catastrophic has
 	 * happened.
author maintainer
#54 lore raw

PATCH 54/62 exit: Allow oops_limit to be disabled

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit de92f65719cd672f4b48397540b9f9eff67eca40 upstream.

In preparation for keeping oops_limit logic in sync with warn_limit, have oops_limit == 0 disable checking the Oops counter.

Cc Jann Horn <[email protected]>
Cc Jonathan Corbet <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Baolin Wang <[email protected]>
Cc "Jason A. Donenfeld" <[email protected]>
Cc Eric Biggers <[email protected]>
Cc Huang Ying <[email protected]>
Cc "Eric W. Biederman" <[email protected]>
Cc Arnd Bergmann <[email protected]>
---
 Documentation/sysctl/kernel.txt |    5 +++--
 kernel/exit.c                   |    2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)
Documentation/sysctl/kernel.txt +3 -2
@@ -519,8 +519,9 @@ scanned for a given scan.
 oops_limit:
 
 Number of kernel oopses after which the kernel should panic when
-``panic_on_oops`` is not set. Setting this to 0 or 1 has the same effect
-as setting ``panic_on_oops=1``.
+``panic_on_oops`` is not set. Setting this to 0 disables checking
+the count. Setting this to  1 has the same effect as setting
+``panic_on_oops=1``. The default value is 10000.
 
 ==============================================================
 
kernel/exit.c +1 -1
@@ -984,7 +984,7 @@ void __noreturn make_task_dead(int signr
 	 * To make sure this can't happen, place an upper bound on how often the
 	 * kernel may oops without panic().
 	 */
-	if (atomic_inc_return(&oops_count) >= READ_ONCE(oops_limit))
+	if (atomic_inc_return(&oops_count) >= READ_ONCE(oops_limit) && oops_limit)
 		panic("Oopsed too often (kernel.oops_limit is %d)", oops_limit);
 
 	do_exit(signr);
author maintainer
#55 lore raw

PATCH 55/62 panic: Consolidate open-coded panic_on_warn checks

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit 79cc1ba7badf9e7a12af99695a557e9ce27ee967 upstream.

Several run-time checkers (KASAN, UBSAN, KFENCE, KCSAN, sched) roll their own warnings, and each check "panic_on_warn". Consolidate this into a single function so that future instrumentation can be added in a single location.

Cc Marco Elver <[email protected]>
Cc Dmitry Vyukov <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Juri Lelli <[email protected]>
Cc Vincent Guittot <[email protected]>
Cc Dietmar Eggemann <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Ben Segall <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Daniel Bristot de Oliveira <[email protected]>
Cc Valentin Schneider <[email protected]>
Cc Andrey Ryabinin <[email protected]>
Cc Alexander Potapenko <[email protected]>
Cc Andrey Konovalov <[email protected]>
Cc Vincenzo Frascino <[email protected]>
Cc Andrew Morton <[email protected]>
Cc David Gow <[email protected]>
Cc tangmeng <[email protected]>
Cc Jann Horn <[email protected]>
Cc Shuah Khan <[email protected]>
Cc Petr Mladek <[email protected]>
Cc "Paul E. McKenney" <[email protected]>
Cc Sebastian Andrzej Siewior <[email protected]>
Cc "Guilherme G. Piccoli" <[email protected]>
Cc Tiezhu Yang <[email protected]>
---
 include/linux/kernel.h |    1 +
 kernel/panic.c         |    9 +++++++--
 kernel/sched/core.c    |    3 +--
 mm/kasan/report.c      |    3 +--
 4 files changed, 10 insertions(+), 6 deletions(-)
include/linux/kernel.h +1 -0
@@ -293,6 +293,7 @@ extern long (*panic_blink)(int state);
 __printf(1, 2)
 void panic(const char *fmt, ...) __noreturn __cold;
 void nmi_panic(struct pt_regs *regs, const char *msg);
+void check_panic_on_warn(const char *origin);
 extern void oops_enter(void);
 extern void oops_exit(void);
 void print_oops_end_marker(void);
kernel/panic.c +7 -2
@@ -122,6 +122,12 @@ void nmi_panic(struct pt_regs *regs, con
 }
 EXPORT_SYMBOL(nmi_panic);
 
+void check_panic_on_warn(const char *origin)
+{
+	if (panic_on_warn)
+		panic("%s: panic_on_warn set ...\n", origin);
+}
+
 /**
  *	panic - halt the system
  *	@fmt: The text string to print
@@ -546,8 +552,7 @@ void __warn(const char *file, int line,
 	if (args)
 		vprintk(args->fmt, args->args);
 
-	if (panic_on_warn)
-		panic("panic_on_warn set ...\n");
+	check_panic_on_warn("kernel");
 
 	print_modules();
 
kernel/sched/core.c +1 -2
@@ -3185,8 +3185,7 @@ static noinline void __schedule_bug(stru
 		print_ip_sym(preempt_disable_ip);
 		pr_cont("\n");
 	}
-	if (panic_on_warn)
-		panic("scheduling while atomic\n");
+	check_panic_on_warn("scheduling while atomic");
 
 	dump_stack();
 	add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
mm/kasan/report.c +1 -2
@@ -172,8 +172,7 @@ static void kasan_end_report(unsigned lo
 	pr_err("==================================================================\n");
 	add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
 	spin_unlock_irqrestore(&report_lock, *flags);
-	if (panic_on_warn)
-		panic("panic_on_warn set ...\n");
+	check_panic_on_warn("KASAN");
 	kasan_enable_current();
 }
 
author maintainer
#56 lore raw

PATCH 56/62 panic: Introduce warn_limit

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit 9fc9e278a5c0b708eeffaf47d6eb0c82aa74ed78 upstream.

Like oops_limit, add warn_limit for limiting the number of warnings when panic_on_warn is not set.

Cc Jonathan Corbet <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Baolin Wang <[email protected]>
Cc "Jason A. Donenfeld" <[email protected]>
Cc Eric Biggers <[email protected]>
Cc Huang Ying <[email protected]>
Cc Petr Mladek <[email protected]>
Cc tangmeng <[email protected]>
Cc "Guilherme G. Piccoli" <[email protected]>
Cc Tiezhu Yang <[email protected]>
Cc Sebastian Andrzej Siewior <[email protected]>
---
 Documentation/sysctl/kernel.txt |   10 ++++++++++
 kernel/panic.c                  |   27 +++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)
Documentation/sysctl/kernel.txt +10 -0
@@ -94,6 +94,7 @@ show up in /proc/sys/kernel:
 - threads-max
 - unprivileged_bpf_disabled
 - unknown_nmi_panic
+- warn_limit
 - watchdog
 - watchdog_thresh
 - version
@@ -1072,6 +1073,15 @@ example.  If a system hangs up, try pres
 
 ==============================================================
 
+warn_limit:
+
+Number of kernel warnings after which the kernel should panic when
+``panic_on_warn`` is not set. Setting this to 0 disables checking
+the warning count. Setting this to 1 has the same effect as setting
+``panic_on_warn=1``. The default value is 0.
+
+==============================================================
+
 watchdog:
 
 This parameter can be used to disable or enable the soft lockup detector
kernel/panic.c +27 -0
@@ -39,6 +39,7 @@ static int pause_on_oops_flag;
 static DEFINE_SPINLOCK(pause_on_oops_lock);
 bool crash_kexec_post_notifiers;
 int panic_on_warn __read_mostly;
+static unsigned int warn_limit __read_mostly;
 
 int panic_timeout = CONFIG_PANIC_TIMEOUT;
 EXPORT_SYMBOL_GPL(panic_timeout);
@@ -47,6 +48,26 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list
 
 EXPORT_SYMBOL(panic_notifier_list);
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table kern_panic_table[] = {
+	{
+		.procname       = "warn_limit",
+		.data           = &warn_limit,
+		.maxlen         = sizeof(warn_limit),
+		.mode           = 0644,
+		.proc_handler   = proc_douintvec,
+	},
+	{ }
+};
+
+static __init int kernel_panic_sysctls_init(void)
+{
+	register_sysctl_init("kernel", kern_panic_table);
+	return 0;
+}
+late_initcall(kernel_panic_sysctls_init);
+#endif
+
 static long no_blink(int state)
 {
 	return 0;
@@ -124,8 +145,14 @@ EXPORT_SYMBOL(nmi_panic);
 
 void check_panic_on_warn(const char *origin)
 {
+	static atomic_t warn_count = ATOMIC_INIT(0);
+
 	if (panic_on_warn)
 		panic("%s: panic_on_warn set ...\n", origin);
+
+	if (atomic_inc_return(&warn_count) >= READ_ONCE(warn_limit) && warn_limit)
+		panic("%s: system warned too often (kernel.warn_limit is %d)",
+		      origin, warn_limit);
 }
 
 /**
author maintainer
#57 lore raw

PATCH 57/62 panic: Expose "warn_count" to sysfs

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit 8b05aa26336113c4cea25f1c333ee8cd4fc212a6 upstream.

Since Warn count is now tracked and is a fairly interesting signal, add the entry /sys/kernel/warn_count to expose it to userspace.

---
 Documentation/ABI/testing/sysfs-kernel-warn_count |    6 ++++++
 kernel/panic.c                                    |   22 ++++++++++++++++++++--
 2 files changed, 26 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-kernel-warn_count
Documentation/ABI/testing/sysfs-kernel-warn_count new file +6 -0
@@ -0,0 +1,6 @@
+What:		/sys/kernel/oops_count
+Date:		November 2022
+KernelVersion:	6.2.0
+Contact:	Linux Kernel Hardening List <[email protected]>
+Description:
+		Shows how many times the system has Warned since last boot.
kernel/panic.c +20 -2
@@ -28,6 +28,7 @@
 #include <linux/console.h>
 #include <linux/bug.h>
 #include <linux/ratelimit.h>
+#include <linux/sysfs.h>
 
 #define PANIC_TIMER_STEP 100
 #define PANIC_BLINK_SPD 18
@@ -68,6 +69,25 @@ static __init int kernel_panic_sysctls_i
 late_initcall(kernel_panic_sysctls_init);
 #endif
 
+static atomic_t warn_count = ATOMIC_INIT(0);
+
+#ifdef CONFIG_SYSFS
+static ssize_t warn_count_show(struct kobject *kobj, struct kobj_attribute *attr,
+			       char *page)
+{
+	return sysfs_emit(page, "%d\n", atomic_read(&warn_count));
+}
+
+static struct kobj_attribute warn_count_attr = __ATTR_RO(warn_count);
+
+static __init int kernel_panic_sysfs_init(void)
+{
+	sysfs_add_file_to_group(kernel_kobj, &warn_count_attr.attr, NULL);
+	return 0;
+}
+late_initcall(kernel_panic_sysfs_init);
+#endif
+
 static long no_blink(int state)
 {
 	return 0;
@@ -145,8 +165,6 @@ EXPORT_SYMBOL(nmi_panic);
 
 void check_panic_on_warn(const char *origin)
 {
-	static atomic_t warn_count = ATOMIC_INIT(0);
-
 	if (panic_on_warn)
 		panic("%s: panic_on_warn set ...\n", origin);
 
author maintainer
#58 lore raw

PATCH 58/62 docs: Fix path paste-o for /sys/kernel/warn_count

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit 00dd027f721e0458418f7750d8a5a664ed3e5994 upstream.

Running "make htmldocs" shows that "/sys/kernel/oops_count" was duplicated. This should have been "warn_count":

Warning: /sys/kernel/oops_count is defined 2 times:
./Documentation/ABI/testing/sysfs-kernel-warn_count:0 ./Documentation/ABI/testing/sysfs-kernel-oops_count:0

Fix the typo.

---
 Documentation/ABI/testing/sysfs-kernel-warn_count |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/ABI/testing/sysfs-kernel-warn_count +1 -1
@@ -1,4 +1,4 @@
-What:		/sys/kernel/oops_count
+What:		/sys/kernel/warn_count
 Date:		November 2022
 KernelVersion:	6.2.0
 Contact:	Linux Kernel Hardening List <[email protected]>
author maintainer
#59 lore raw

PATCH 59/62 exit: Use READ_ONCE() for all oops/warn limit reads

In reply to Greg Kroah-Hartman

From: Kees Cook <[email protected]>

commit 7535b832c6399b5ebfc5b53af5c51dd915ee2538 upstream.

Use a temporary variable to take full advantage of READ_ONCE() behavior. Without this, the report (and even the test) might be out of sync with the initial test.

Fixes 9fc9e278a5c0 ("panic: Introduce warn_limit")
Fixes d4ccd54d28d3 ("exit: Put an upper limit on how often we can oops")
Cc "Eric W. Biederman" <[email protected]>
Cc Jann Horn <[email protected]>
Cc Arnd Bergmann <[email protected]>
Cc Petr Mladek <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Luis Chamberlain <[email protected]>
Cc Marco Elver <[email protected]>
Cc tangmeng <[email protected]>
Cc Sebastian Andrzej Siewior <[email protected]>
Cc Tiezhu Yang <[email protected]>
---
 kernel/exit.c  |    6 ++++--
 kernel/panic.c |    7 +++++--
 2 files changed, 9 insertions(+), 4 deletions(-)
kernel/exit.c +4 -2
@@ -973,6 +973,7 @@ void __noreturn make_task_dead(int signr
 	 * Take the task off the cpu after something catastrophic has
 	 * happened.
 	 */
+	unsigned int limit;
 
 	/*
 	 * Every time the system oopses, if the oops happens while a reference
@@ -984,8 +985,9 @@ void __noreturn make_task_dead(int signr
 	 * To make sure this can't happen, place an upper bound on how often the
 	 * kernel may oops without panic().
 	 */
-	if (atomic_inc_return(&oops_count) >= READ_ONCE(oops_limit) && oops_limit)
-		panic("Oopsed too often (kernel.oops_limit is %d)", oops_limit);
+	limit = READ_ONCE(oops_limit);
+	if (atomic_inc_return(&oops_count) >= limit && limit)
+		panic("Oopsed too often (kernel.oops_limit is %d)", limit);
 
 	do_exit(signr);
 }
kernel/panic.c +5 -2
@@ -165,12 +165,15 @@ EXPORT_SYMBOL(nmi_panic);
 
 void check_panic_on_warn(const char *origin)
 {
+	unsigned int limit;
+
 	if (panic_on_warn)
 		panic("%s: panic_on_warn set ...\n", origin);
 
-	if (atomic_inc_return(&warn_count) >= READ_ONCE(warn_limit) && warn_limit)
+	limit = READ_ONCE(warn_limit);
+	if (atomic_inc_return(&warn_count) >= limit && limit)
 		panic("%s: system warned too often (kernel.warn_limit is %d)",
-		      origin, warn_limit);
+		      origin, limit);
 }
 
 /**
author maintainer
#60 lore raw

PATCH 60/62 mm: kvmalloc does not fallback to vmalloc for incompatible gfp flags

In reply to Greg Kroah-Hartman

From: Michal Hocko <[email protected]>

commit ce91f6ee5b3bbbad8caff61b1c46d845c8db19bf upstream.

kvmalloc warned about incompatible gfp_mask to catch abusers (mostly GFP_NOFS) with an intention that this will motivate authors of the code to fix those. Linus argues that this just motivates people to do even more hacks like

	if (gfp == GFP_KERNEL)
		kvmalloc
	else
		kmalloc

I haven't seen this happening much (Linus pointed to bucket_lock special cases an atomic allocation but my git foo hasn't found much more) but it is true that we can grow those in future. Therefore Linus suggested to simply not fallback to vmalloc for incompatible gfp flags and rather stick with the kmalloc path.

---
 mm/util.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
mm/util.c +4 -2
@@ -400,7 +400,8 @@ EXPORT_SYMBOL(vm_mmap);
  * __GFP_RETRY_MAYFAIL is supported, and it should be used only if kmalloc is
  * preferable to the vmalloc fallback, due to visible performance drawbacks.
  *
- * Any use of gfp flags outside of GFP_KERNEL should be consulted with mm people.
+ * Please note that any use of gfp flags outside of GFP_KERNEL is careful to not
+ * fall back to vmalloc.
  */
 void *kvmalloc_node(size_t size, gfp_t flags, int node)
 {
@@ -411,7 +412,8 @@ void *kvmalloc_node(size_t size, gfp_t f
 	 * vmalloc uses GFP_KERNEL for some internal allocations (e.g page tables)
 	 * so the given set of flags has to be compatible.
 	 */
-	WARN_ON_ONCE((flags & GFP_KERNEL) != GFP_KERNEL);
+	if ((flags & GFP_KERNEL) != GFP_KERNEL)
+		return kmalloc_node(size, flags, node);
 
 	/*
 	 * We want to attempt a large physically contiguous block first because
author maintainer
#61 lore raw

PATCH 61/62 ipv6: ensure sane device mtu in tunnels

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

commit d89d7ff01235f218dad37de84457717f699dee79 upstream.

Another syzbot report [1] with no reproducer hints at a bug in ip6_gre tunnel (dev:ip6gretap0)

Since ipv6 mcast code makes sure to read dev->mtu once and applies a sanity check on it (see commit b9b312a7a451 "ipv6: mcast: better catch silly mtu values"), a remaining possibility is that a layer is able to set dev->mtu to an underflowed value (high order bit set).

This could happen indeed in ip6gre_tnl_link_config_route(), ip6_tnl_link_config() and ipip6_tunnel_bind_dev()

Make sure to sanitize mtu value in a local variable before it is written once on dev->mtu, as lockless readers could catch wrong temporary value.

[1]
skbuff: skb_over_panic: text:ffff80000b7a2f38 len:40 put:40 head:ffff000149dcf200 data:ffff000149dcf2b0 tail:0xd8 end:0xc0 dev:ip6gretap0

------------[ cut here ]------------
kernel BUG at net/core/skbuff.c:120
Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP
Modules linked in:
CPU: 1 PID: 10241 Comm: kworker/1:1 Not tainted 6.0.0-rc7-syzkaller-18095-gbbed346d5a96 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/30/2022
Workqueue: mld mld_ifc_work
pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : skb_panic+0x4c/0x50 net/core/skbuff.c:116
lr : skb_panic+0x4c/0x50 net/core/skbuff.c:116

sp : ffff800020dd3b60
x29: ffff800020dd3b70 x28: 0000000000000000 x27: ffff00010df2a800
x26: 00000000000000c0 x25: 00000000000000b0 x24: ffff000149dcf200
x23: 00000000000000c0 x22: 00000000000000d8 x21: ffff80000b7a2f38
x20: ffff00014c2f7800 x19: 0000000000000028 x18: 00000000000001a9
x17: 0000000000000000 x16: ffff80000db49158 x15: ffff000113bf1a80
x14: 0000000000000000 x13: 00000000ffffffff x12: ffff000113bf1a80
x11: ff808000081c0d5c x10: 0000000000000000 x9 : 73f125dc5c63ba00 x8 : 73f125dc5c63ba00 x7 : ffff800008161d1c x6 : 0000000000000000 x5 : 0000000000000080 x4 : 0000000000000001 x3 : 0000000000000000 x2 : ffff0001fefddcd0 x1 : 0000000100000000 x0 : 0000000000000089

Call trace:
skb_panic+0x4c/0x50 net/core/skbuff.c:116
skb_over_panic net/core/skbuff.c:125 [inline]
skb_put+0xd4/0xdc net/core/skbuff.c:2049
ip6_mc_hdr net/ipv6/mcast.c:1714 [inline]
mld_newpack+0x14c/0x270 net/ipv6/mcast.c:1765
add_grhead net/ipv6/mcast.c:1851 [inline]
add_grec+0xa20/0xae0 net/ipv6/mcast.c:1989
mld_send_cr+0x438/0x5a8 net/ipv6/mcast.c:2115
mld_ifc_work+0x38/0x290 net/ipv6/mcast.c:2653
process_one_work+0x2d8/0x504 kernel/workqueue.c:2289
worker_thread+0x340/0x610 kernel/workqueue.c:2436
kthread+0x12c/0x158 kernel/kthread.c:376
ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:860
Code: 91011400 aa0803e1 a90027ea 94373093 (d4210000)

[ta: Backport patch for stable kernels < 5.10.y. Fix conflict in net/ipv6/ip6_tunnel.c, mtu initialized with:
mtu = rt->dst.dev->mtu - t_hlen;]

---
 net/ipv6/ip6_gre.c    |   12 +++++++-----
 net/ipv6/ip6_tunnel.c |   10 ++++++----
 net/ipv6/sit.c        |    8 +++++---
 3 files changed, 18 insertions(+), 12 deletions(-)
net/ipv6/ip6_gre.c +7 -5
@@ -771,14 +771,16 @@ static void ip6gre_tnl_link_config(struc
 					       t_hlen;
 
 			if (set_mtu) {
-				dev->mtu = rt->dst.dev->mtu - t_hlen;
+				int mtu = rt->dst.dev->mtu - t_hlen;
+
 				if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
-					dev->mtu -= 8;
+					mtu -= 8;
 				if (dev->type == ARPHRD_ETHER)
-					dev->mtu -= ETH_HLEN;
+					mtu -= ETH_HLEN;
 
-				if (dev->mtu < IPV6_MIN_MTU)
-					dev->mtu = IPV6_MIN_MTU;
+				if (mtu < IPV6_MIN_MTU)
+					mtu = IPV6_MIN_MTU;
+				WRITE_ONCE(dev->mtu, mtu);
 			}
 		}
 		ip6_rt_put(rt);
net/ipv6/ip6_tunnel.c +6 -4
@@ -1431,6 +1431,7 @@ static void ip6_tnl_link_config(struct i
 	struct __ip6_tnl_parm *p = &t->parms;
 	struct flowi6 *fl6 = &t->fl.u.ip6;
 	int t_hlen;
+	int mtu;
 
 	memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
 	memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
@@ -1473,12 +1474,13 @@ static void ip6_tnl_link_config(struct i
 			dev->hard_header_len = rt->dst.dev->hard_header_len +
 				t_hlen;
 
-			dev->mtu = rt->dst.dev->mtu - t_hlen;
+			mtu = rt->dst.dev->mtu - t_hlen;
 			if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
-				dev->mtu -= 8;
+				mtu -= 8;
 
-			if (dev->mtu < IPV6_MIN_MTU)
-				dev->mtu = IPV6_MIN_MTU;
+			if (mtu < IPV6_MIN_MTU)
+				mtu = IPV6_MIN_MTU;
+			WRITE_ONCE(dev->mtu, mtu);
 		}
 		ip6_rt_put(rt);
 	}
net/ipv6/sit.c +5 -3
@@ -1068,10 +1068,12 @@ static void ipip6_tunnel_bind_dev(struct
 
 	if (tdev && !netif_is_l3_master(tdev)) {
 		int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+		int mtu;
 
-		dev->mtu = tdev->mtu - t_hlen;
-		if (dev->mtu < IPV6_MIN_MTU)
-			dev->mtu = IPV6_MIN_MTU;
+		mtu = tdev->mtu - t_hlen;
+		if (mtu < IPV6_MIN_MTU)
+			mtu = IPV6_MIN_MTU;
+		WRITE_ONCE(dev->mtu, mtu);
 	}
 }
 
author maintainer
#62 lore raw

PATCH 62/62 usb: host: xhci-plat: add wakeup entry at sysfs

In reply to Greg Kroah-Hartman

From: Peter Chen <[email protected]>

commit 4bb4fc0dbfa23acab9b762949b91ffd52106fe4b upstream.

With this change, there will be a wakeup entry at /sys/../power/wakeup, and the user could use this entry to choose whether enable xhci wakeup features (wake up system from suspend) or not.

---
 drivers/usb/host/xhci-plat.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-plat.c +1 -1
@@ -252,7 +252,7 @@ static int xhci_plat_probe(struct platfo
 			*priv = *priv_match;
 	}
 
-	device_wakeup_enable(hcd->self.controller);
+	device_set_wakeup_capable(&pdev->dev, true);
 
 	xhci->clk = clk;
 	xhci->main_hcd = hcd;
#63 lore raw
In reply to Greg Kroah-Hartman
Quoted 8 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.14.305 release. There are 62 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, 05 Feb 2023 10:09:58 +0000. Anything received after that time might be too late.

Build results:

	total: 168 pass: 167 fail: 1
Failed builds:
	ia64:defconfig
Qemu test results:
	total: 425 pass: 425 fail: 0

ia64 build error as reported separately.

Guenter

Tested-by Linux Kernel Functional Testing on the v1 series
#64 lore raw
In reply to Greg Kroah-Hartman
Quoted 10 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 4.14.305 release. There are 62 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, 05 Feb 2023 10:09:58 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

Quoted 8 lines
        https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.305-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

Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.

## Build
* kernel: 4.14.305-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-4.14.y
* git commit: 001d96b34795b15b9037ba2fb3c63dffcfc0566e
* git describe: v4.14.304-63-g001d96b34795
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-4.14.y/build/v4.14.304-63-g001d96b34795

## Test Regressions (compared to v4.14.304)

## Metric Regressions (compared to v4.14.304)

## Test Fixes (compared to v4.14.304)

## Metric Fixes (compared to v4.14.304)

## Test result summary
total: 92228, pass: 79865, fail: 2880, skip: 9186, xfail: 297

## Build Summary
* arc: 10 total, 10 passed, 0 failed
* arm: 311 total, 306 passed, 5 failed
* arm64: 53 total, 50 passed, 3 failed
* i386: 29 total, 28 passed, 1 failed
* mips: 41 total, 41 passed, 0 failed
* parisc: 12 total, 12 passed, 0 failed
* powerpc: 20 total, 19 passed, 1 failed
* s390: 15 total, 11 passed, 4 failed
* sh: 24 total, 24 passed, 0 failed
* sparc: 12 total, 12 passed, 0 failed
* x86_64: 51 total, 50 passed, 1 failed

## Test suites summary
* boot
* fwts
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers-dma-buf
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-firmware
* kselftest-fpu
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-net
* kselftest-net-forwarding
* kselftest-net-mptcp
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* rcutorture
* v4l2-compliance
* vdso

--
Linaro LKFT
https://lkft.linaro.org