Skip to contentSkip to conversation

5.15.87-rc1 review

PATCH In review Greg Kroah-Hartman 12 participants 304 messages Jan 10, 2023 – Jan 12, 2023 Page 1 of 3

Subsystems (4)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 5.15.87-rc1 review

This is the start of the stable review cycle for the 5.15.87 release. There are 290 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Thu, 12 Jan 2023 17:59:42 +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/v5.x/stable-review/patch-5.15.87-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-5.15.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 5.15.87-rc1

Jocelyn Falempe <[email protected]>

    drm/mgag200: Fix PLL setup for G200_SE_A rev >=4

Harshit Mogalapalli <[email protected]>
io_uring: Fix unsigned 'res' comparison with zero in io_fixup_rw_res()

Ard Biesheuvel <[email protected]>
efi: random: combine bootloader provided RNG seed with RNG protocol output

Jan Kara <[email protected]>

    mbcache: Avoid nesting of cache->c_list_lock under bit locks

Jie Wang <[email protected]>
net: hns3: fix return value check bug of rx copybreak

Qu Wenruo <[email protected]>
btrfs: make thaw time super block check to also verify checksum

Muhammad Usama Anjum <[email protected]>
selftests: set the BUILD variable to absolute path

Eric Biggers <[email protected]>
ext4: don't allow journal inode to have encrypt flag

Matthieu Baerts <[email protected]>
mptcp: use proper req destructor for IPv6

Matthieu Baerts <[email protected]>
mptcp: dedicated request sock for subflow in v6

Mario Limonciello <[email protected]>
Revert "ACPI: PM: Add support for upcoming AMD uPEP HID AMDI007"

William Liu <[email protected]>
ksmbd: check nt_len to be at least CIFS_ENCPWD_SIZE in ksmbd_decode_ntlmssp_auth_blob

Namjae Jeon <[email protected]>
ksmbd: fix infinite loop in ksmbd_conn_handler_loop()

Linus Torvalds <[email protected]>
hfs/hfsplus: avoid WARN_ON() for sanity check, use proper error handling

Arnd Bergmann <[email protected]>
hfs/hfsplus: use WARN_ON for sanity check

Zhenyu Wang <[email protected]>
drm/i915/gvt: fix vgpu debugfs clean in remove

Zhenyu Wang <[email protected]>
drm/i915/gvt: fix gvt debugfs destroy

Björn Töpel <[email protected]>
riscv, kprobes: Stricter c.jr/c.jalr decoding

Ben Dooks <[email protected]>
riscv: uaccess: fix type of 0 variable on error in get_user()

Srinivas Pandruvada <[email protected]>

    thermal: int340x: Add missing attribute for data rate base

Pavel Begunkov <[email protected]>
io_uring: fix CQ waiting timeout handling

Jens Axboe <[email protected]>
block: don't allow splitting of a REQ_NOWAIT bio

Paul Menzel <[email protected]>
fbdev: matroxfb: G200eW: Increase max memory from 1 MB to 16 MB

Jeff Layton <[email protected]>
nfsd: fix handling of readdir in v4root vs. mount upcall timeout

Rodrigo Branco <[email protected]>
x86/bugs: Flush IBP in ib_prctl_set()

Takashi Iwai <[email protected]>
x86/kexec: Fix double-free of elf header buffer

Qu Wenruo <[email protected]>
btrfs: check superblock to ensure the fs was not modified at thaw time

Christoph Hellwig <[email protected]>
nvme: also return I/O command effects from nvme_command_effects

Christoph Hellwig <[email protected]>
nvmet: use NVME_CMD_EFFECTS_CSUPP instead of open coding it

Jens Axboe <[email protected]>
io_uring: check for valid register opcode earlier

Yanjun Zhang <[email protected]>
nvme: fix multipath crash caused by flush request when blktrace is enabled

Hans de Goede <[email protected]>
ASoC: Intel: bytcr_rt5640: Add quirk for the Advantech MICA-071 tablet

Jan Kara <[email protected]>
udf: Fix extension of the last extent in the file

Zhengchao Shao <[email protected]>
caif: fix memory leak in cfctrl_linkup_request()

Dan Carpenter <[email protected]>
drm/i915: unpin on error in intel_vgpu_shadow_mm_pin()

Namhyung Kim <[email protected]>
perf stat: Fix handling of --for-each-cgroup with --bpf-counters to match non BPF mode

Szymon Heidrich <[email protected]>
usb: rndis_host: Secure rndis_query check against int overflow

Geetha sowjanya <[email protected]>
octeontx2-pf: Fix lmtst ID used in aura free

Daniil Tatianin <[email protected]>
drivers/net/bonding/bond_3ad: return when there's no aggregator

Tetsuo Handa <[email protected]>
fs/ntfs3: don't hold ni_lock when calling truncate_setsize()

Philipp Zabel <[email protected]>
drm/imx: ipuv3-plane: Fix overlay plane width

Miaoqian Lin <[email protected]>
perf tools: Fix resources leak in perf_data__open_dir()

Jozsef Kadlecsik <[email protected]>
netfilter: ipset: Rework long task execution when adding/deleting entries

Jozsef Kadlecsik <[email protected]>
netfilter: ipset: fix hash:net,port,net hang with /0 subnet

Horatiu Vultur <[email protected]>
net: sparx5: Fix reading of the MAC address

Jamal Hadi Salim <[email protected]>
net: sched: cbq: dont intepret cls results when asked to drop

Jamal Hadi Salim <[email protected]>
net: sched: atm: dont intepret cls results when asked to drop

Miaoqian Lin <[email protected]>
gpio: sifive: Fix refcount leak in sifive_gpio_probe

Xiubo Li <[email protected]>
ceph: switch to vfs_inode_has_locks() to fix file lock bug

Jeff Layton <[email protected]>
filelock: new helper: vfs_inode_has_locks

Carlo Caione <[email protected]>
drm/meson: Reduce the FIFO lines held when AFBC is not used

Maor Gottlieb <[email protected]>
RDMA/mlx5: Fix validation of max_rd_atomic caps for DC

Shay Drory <[email protected]>
RDMA/mlx5: Fix mlx5_ib_get_hw_stats when used for device

Miaoqian Lin <[email protected]>
net: phy: xgmiitorgmii: Fix refcount leak in xgmiitorgmii_probe

David Arinzon <[email protected]>
net: ena: Update NUMA TPH hint register upon NUMA node update

David Arinzon <[email protected]>
net: ena: Set default value for RX interrupt moderation

David Arinzon <[email protected]>
net: ena: Fix rx_copybreak value update

David Arinzon <[email protected]>
net: ena: Use bitmask to indicate packet redirection

David Arinzon <[email protected]>
net: ena: Account for the number of processed bytes in XDP

David Arinzon <[email protected]>
net: ena: Don't register memory info on XDP exchange

David Arinzon <[email protected]>
net: ena: Fix toeplitz initial hash value

Jiguang Xiao <[email protected]>
net: amd-xgbe: add missed tasklet_kill

Adham Faris <[email protected]>
net/mlx5e: Fix hw mtu initializing at XDP SQ allocation

Chris Mi <[email protected]>
net/mlx5e: Always clear dest encap in neigh-update-del

Roi Dayan <[email protected]>
net/mlx5e: TC, Refactor mlx5e_tc_add_flow_mod_hdr() to get flow attr

Dragos Tatulea <[email protected]>
net/mlx5e: IPoIB, Don't allow CQE compression to be turned on by default

Shay Drory <[email protected]>
net/mlx5: Avoid recovery in probe flows

Jiri Pirko <[email protected]>
net/mlx5: Add forgotten cleanup calls into mlx5_init_once() error path

Moshe Shemesh <[email protected]>
net/mlx5: E-Switch, properly handle ingress tagged packets on VST

Stefano Garzarella <[email protected]>
vdpa_sim: fix vringh initialization in vdpasim_queue_ready()

Stefano Garzarella <[email protected]>
vhost: fix range used in translate_desc()

Stefano Garzarella <[email protected]>
vringh: fix range used in iotlb_translate()

Yuan Can <[email protected]>
vhost/vsock: Fix error handling in vhost_vsock_init()

ruanjinjie <[email protected]>
vdpa_sim: fix possible memory leak in vdpasim_net_init() and vdpasim_blk_init()

Miaoqian Lin <[email protected]>
nfc: Fix potential resource leaks

Johnny S. Lee <[email protected]>
net: dsa: mv88e6xxx: depend on PTP conditionally

Daniil Tatianin <[email protected]>

    qlcnic: prevent ->dcb use-after-free on qlcnic_dcb_enable() failure

Hawkins Jiawei <[email protected]>
net: sched: fix memory leak in tcindex_set_parms

Jian Shen <[email protected]>
net: hns3: fix VF promisc mode not update when mac table full

Jian Shen <[email protected]>
net: hns3: fix miss L3E checking for rx packet

Peng Li <[email protected]>
net: hns3: extract macro to simplify ring stats update code

Hao Chen <[email protected]>
net: hns3: refactor hns3_nic_reuse_page()

Jie Wang <[email protected]>
net: hns3: add interrupts re-initialization while doing VF FLR

Jeff Layton <[email protected]>
nfsd: shut down the NFSv4 state objects before the filecache

Shawn Bohrer <[email protected]>
veth: Fix race with AF_XDP exposing old or uninitialized descriptors

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: honor set timeout and garbage collection updates

Ronak Doshi <[email protected]>
vmxnet3: correctly report csum_level for encapsulated packet

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: perform type checking for existing sets

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: add function to create set stateful expressions

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: consolidate set description

Steven Price <[email protected]>
drm/panfrost: Fix GEM handle creation ref-counting

Jakub Kicinski <[email protected]>
bpf: pull before calling skb_postpull_rcsum()

Sasha Levin <[email protected]>
btrfs: fix an error handling path in btrfs_defrag_leaves()

minoura makoto <[email protected]>
SUNRPC: ensure the matching upcall is in-flight upon downcall

Matthew Auld <[email protected]>
drm/i915/migrate: fix length calculation

Matthew Auld <[email protected]>
drm/i915/migrate: fix offset calculation

Matthew Auld <[email protected]>
drm/i915/migrate: don't check the scratch page

Jan Kara <[email protected]>
ext4: fix deadlock due to mbcache entry corruption

Jan Kara <[email protected]>
mbcache: automatically delete entries from cache on freeing

Baokun Li <[email protected]>
ext4: correct inconsistent error msg in nojournal mode

Jason Yan <[email protected]>
ext4: goto right label 'failed_mount3a'

Biju Das <[email protected]>
ravb: Fix "failed to switch device to config mode" message during unbind

Masami Hiramatsu (Google) <[email protected]>
perf probe: Fix to get the DW_AT_decl_file and DW_AT_call_file as unsinged data

Masami Hiramatsu (Google) <[email protected]>
perf probe: Use dwarf_attr_integrate as generic DWARF attr accessor

Smitha T Murthy <[email protected]>
media: s5p-mfc: Fix in register read and write for H264

Smitha T Murthy <[email protected]>
media: s5p-mfc: Clear workbit to handle error condition

Smitha T Murthy <[email protected]>
media: s5p-mfc: Fix to handle reference queue during finishing

Yazen Ghannam <[email protected]>
x86/MCE/AMD: Clear DFR errors found in THR handler

Borislav Petkov <[email protected]>
x86/mce: Get rid of msr_ops

void0red <[email protected]>
btrfs: fix extent map use-after-free when handling missing device in read_one_chunk

Nikolay Borisov <[email protected]>
btrfs: move missing device handling in a dedicate function

Sasha Levin <[email protected]>
btrfs: replace strncpy() with strscpy()

Sasha Levin <[email protected]>
phy: qcom-qmp-combo: fix out-of-bounds clock access

Jens Axboe <[email protected]>
ARM: renumber bits related to _TIF_WORK_MASK

Eric Biggers <[email protected]>
ext4: fix off-by-one errors in fast-commit block filling

Eric Biggers <[email protected]>
ext4: fix unaligned memory access in ext4_fc_reserve_space()

Eric Biggers <[email protected]>
ext4: add missing validation of fast-commit record lengths

Eric Biggers <[email protected]>
ext4: don't set up encryption key during jbd2 transaction

Eric Biggers <[email protected]>
ext4: disable fast-commit of encrypted dir operations

Eric Biggers <[email protected]>
ext4: fix potential out of bound read in ext4_fc_replay_scan()

Eric Biggers <[email protected]>
ext4: factor out ext4_fc_get_tl()

Eric Biggers <[email protected]>
ext4: introduce EXT4_FC_TAG_BASE_LEN helper

Eric Biggers <[email protected]>
ext4: use ext4_debug() instead of jbd_debug()

Eric Biggers <[email protected]>
ext4: remove unused enum EXT4_FC_COMMIT_FAILED

Zheng Yejian <[email protected]>
tracing: Fix issue of missing one synthetic field

Damien Le Moal <[email protected]>
block: mq-deadline: Fix dd_finish_request() for zoned devices

Alex Deucher <[email protected]>
drm/amdgpu: make display pinning more flexible (v2)

Alex Deucher <[email protected]>
drm/amdgpu: handle polaris10/11 overlap asics (v2)

Ye Bin <[email protected]>
ext4: allocate extended attribute value in vmalloc area

Jan Kara <[email protected]>
ext4: avoid unaccounted block allocation when expanding inode

Jan Kara <[email protected]>
ext4: initialize quota before expanding inode in setproject ioctl

Ye Bin <[email protected]>
ext4: fix inode leak in ext4_xattr_inode_create() on an error path

Ye Bin <[email protected]>
ext4: fix kernel BUG in 'ext4_write_inline_data_end()'

Jan Kara <[email protected]>
ext4: avoid BUG_ON when creating xattrs

Luís Henriques <[email protected]>
ext4: fix error code return to user-space in ext4_get_branch()

Baokun Li <[email protected]>
ext4: fix corruption when online resizing a 1K bigalloc fs

Eric Whitney <[email protected]>
ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline

Ye Bin <[email protected]>
ext4: init quota for 'old.inode' in 'ext4_rename'

Ye Bin <[email protected]>
ext4: fix uninititialized value in 'ext4_evict_inode'

Eric Biggers <[email protected]>
ext4: fix leaking uninitialized memory in fast-commit journal

Baokun Li <[email protected]>
ext4: fix bug_on in __es_tree_search caused by bad boot loader inode

Zhang Yi <[email protected]>
ext4: check and assert if marking an no_delete evicting inode dirty

Ye Bin <[email protected]>
ext4: fix reserved cluster accounting in __es_remove_extent()

Baokun Li <[email protected]>
ext4: fix bug_on in __es_tree_search caused by bad quota inode

Baokun Li <[email protected]>
ext4: add helper to check quota inums

Baokun Li <[email protected]>
ext4: add EXT4_IGET_BAD flag to prevent unexpected bad inode

Gaosheng Cui <[email protected]>
ext4: fix undefined behavior in bit shift for ext4_check_flag_values

Baokun Li <[email protected]>
ext4: fix use-after-free in ext4_orphan_cleanup

Alexander Potapenko <[email protected]>
fs: ext4: initialize fsdata in pagecache_write()

Luís Henriques <[email protected]>
ext4: remove trailing newline from ext4_msg() message

Baokun Li <[email protected]>
ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop

Zhang Yi <[email protected]>
ext4: silence the warning when evicting inode with dioread_nolock

Yuan Can <[email protected]>
drm/ingenic: Fix missing platform_driver_unregister() call in ingenic_drm_init()

Mikko Kovanen <[email protected]>
drm/i915/dsi: fix VBT send packet port selection for dual link DSI

Zack Rusin <[email protected]>
drm/vmwgfx: Validate the box size for the snooped cursor

Simon Ser <[email protected]>
drm/connector: send hotplug uevent on connector cleanup

Wang Weiyang <[email protected]>
device_cgroup: Roll back to original exceptions after copy failure

Shang XiaoJing <[email protected]>
parisc: led: Fix potential null-ptr-deref in start_task()

Maria Yu <[email protected]>
remoteproc: core: Do pm_relax when in RPROC_OFFLINE state

Kim Phillips <[email protected]>
iommu/amd: Fix ivrs_acpihid cmdline parsing code

Johan Hovold <[email protected]>

    phy: qcom-qmp-combo: fix sc8180x reset

Isaac J. Manjarres <[email protected]>
driver core: Fix bus_type.match() error handling in __driver_attach()

Mario Limonciello <[email protected]>

    crypto: ccp - Add support for TEE for PCI ID 0x14CA

Corentin Labbe <[email protected]>
crypto: n2 - add missing hash statesize

Sergey Matyukevich <[email protected]>
riscv: mm: notify remote harts about mmu cache updates

Guo Ren <[email protected]>
riscv: stacktrace: Fixup ftrace_graph_ret_addr retp argument

Sascha Hauer <[email protected]>
PCI/sysfs: Fix double free in error path

Michael S. Tsirkin <[email protected]>
PCI: Fix pci_device_is_present() for VFs by checking PF

Dan Carpenter <[email protected]>
ipmi: fix use after free in _ipmi_destroy_user()

Huaxin Lu <[email protected]>
ima: Fix a potential NULL pointer access in ima_restore_measurement_list

Alexander Sverdlin <[email protected]>
mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type()

Zhang Yuchen <[email protected]>
ipmi: fix long wait in unload when IPMI disconnect

Maximilian Luz <[email protected]>
ipu3-imgu: Fix NULL pointer dereference in imgu_subdev_set_selection()

Aidan MacDonald <[email protected]>
ASoC: jz4740-i2s: Handle independent FIFO flush bits

Michael Walle <[email protected]>
wifi: wilc1000: sdio: fix module autoloading

Aditya Garg <[email protected]>
efi: Add iMac Pro 2017 to uefi skip cert quirk

Florian-Ewald Mueller <[email protected]>
md/bitmap: Fix bitmap chunk size overflow issues

Damien Le Moal <[email protected]>
block: mq-deadline: Do not break sequential write streams to zoned HDDs

Ian Abbott <[email protected]>
rtc: ds1347: fix value written to century register

Steve French <[email protected]>
cifs: fix missing display of three mount options

Paulo Alcantara <[email protected]>
cifs: fix confusing debug message

Takashi Iwai <[email protected]>
media: dvb-core: Fix UAF due to refcount races at releasing

Keita Suzuki <[email protected]>
media: dvb-core: Fix double free in dvb_register_device()

Nick Desaulniers <[email protected]>
ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod

Luca Ceresoli <[email protected]>
staging: media: tegra-video: fix device_node use after free

Luca Ceresoli <[email protected]>

    staging: media: tegra-video: fix chan->mipi value on error

Yang Jihong <[email protected]>
tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line

Steven Rostedt (Google) <[email protected]>
tracing/probes: Handle system names with hyphens

Zheng Yejian <[email protected]>
tracing/hist: Fix wrong return value in parse_action_params()

Masami Hiramatsu (Google) <[email protected]>
tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE

Steven Rostedt (Google) <[email protected]>
tracing: Fix race where eprobes can be called before the event

Masami Hiramatsu (Google) <[email protected]>
x86/kprobes: Fix optprobe optimization check with CONFIG_RETHUNK

Masami Hiramatsu (Google) <[email protected]>
x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK

Steven Rostedt (Google) <[email protected]>
ftrace/x86: Add back ftrace_expected for ftrace bug reports

Ashok Raj <[email protected]>
x86/microcode/intel: Do not retry microcode reloading on the APs

Sean Christopherson <[email protected]>
KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1

Sean Christopherson <[email protected]>
KVM: nVMX: Inject #GP, not #UD, if "generic" VMXON CR0/CR4 check fails

Sean Christopherson <[email protected]>
KVM: VMX: Resume guest immediately when injecting #GP on ECREATE

Rob Herring <[email protected]>
of/kexec: Fix reading 32-bit "linux,initrd-{start,end}" values

Namhyung Kim <[email protected]>
perf/core: Call LSM hook after copying perf_event_attr

Zheng Yejian <[email protected]>
tracing/hist: Fix out-of-bound write on 'action_data.var_ref_idx'

Mike Snitzer <[email protected]>
dm cache: set needs_check flag after aborting metadata

Luo Meng <[email protected]>
dm cache: Fix UAF in destroy()

Luo Meng <[email protected]>
dm clone: Fix UAF in clone_dtr()

Luo Meng <[email protected]>
dm integrity: Fix UAF in dm_integrity_dtr()

Luo Meng <[email protected]>
dm thin: Fix UAF in run_timer_softirq()

Luo Meng <[email protected]>
dm thin: resume even if in FAIL mode

Zhihao Cheng <[email protected]>

    dm thin: Use last transaction's pmd->root when commit failed

Zhihao Cheng <[email protected]>
dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata

Mike Snitzer <[email protected]>
dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort

Matthieu Baerts <[email protected]>
mptcp: remove MPTCP 'ifdef' in TCP SYN cookies

Florian Westphal <[email protected]>
mptcp: mark ops structures as ro_after_init

Alexander Aring <[email protected]>
fs: dlm: retry accept() until -EAGAIN or error returns

Alexander Aring <[email protected]>
fs: dlm: fix sock release if listen fails

Chris Chiu <[email protected]>
ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops

Philipp Jungkamp <[email protected]>
ALSA: patch_realtek: Fix Dell Inspiron Plus 16

Yongqiang Liu <[email protected]>
cpufreq: Init completion before kobject_init_and_add()

Kant Fan <[email protected]>
PM/devfreq: governor: Add a private governor_data for governor

Mickaël Salaün <[email protected]>
selftests: Use optional USERCFLAGS and USERLDFLAGS

Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength

Jason A. Donenfeld <[email protected]>
ARM: ux500: do not directly dereference __iomem

Boris Burkov <[email protected]>
btrfs: fix resolving backrefs for inline extent followed by prealloc

Wenchao Chen <[email protected]>
mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K

Krzysztof Kozlowski <[email protected]>
arm64: dts: qcom: sdm845-db845c: correct SPI2 pins drive strength

Alexander Antonov <[email protected]>
perf/x86/intel/uncore: Clear attr_update properly

Alexander Antonov <[email protected]>
perf/x86/intel/uncore: Disable I/O stacks to PMU mapping on ICX-D

Bixuan Cui <[email protected]>
jbd2: use the correct print format

Steven Rostedt <[email protected]>
ktest.pl minconfig: Unset configs instead of just removing them

Steven Rostedt <[email protected]>
kest.pl: Fix grub2 menu handling for rebooting

Manivannan Sadhasivam <[email protected]>
soc: qcom: Select REMAP_MMIO for LLCC driver

Jason A. Donenfeld <[email protected]>
media: stv0288: use explicitly signed char

Eric Dumazet <[email protected]>
net/af_packet: make sure to pull mac header

Hangbin Liu <[email protected]>
net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO

Paul E. McKenney <[email protected]>
rcu-tasks: Simplify trc_read_check_handler() atomic operations

Pierre-Louis Bossart <[email protected]>
ASoC/SoundWire: dai: expand 'stream' concept beyond SoundWire

Pierre-Louis Bossart <[email protected]>
ASoC: Intel/SOF: use set_stream() instead of set_tdm_slots() for HDAudio

Marco Elver <[email protected]>
kcsan: Instrument memcpy/memset/memmove with newer Clang

Chuck Lever <[email protected]>
SUNRPC: Don't leak netobj memory when gss_read_proxy_verf() fails

Hanjun Guo <[email protected]>
tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak

Hanjun Guo <[email protected]>
tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak

Hanjun Guo <[email protected]>
tpm: acpi: Call acpi_put_table() to fix memory leak

Deren Wu <[email protected]>
mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING

Jaegeuk Kim <[email protected]>
f2fs: allow to read node block after shutdown

Pavel Machek <[email protected]>
f2fs: should put a page when checking the summary info

NARIBAYASHI Akira <[email protected]>
mm, compaction: fix fast_isolate_around() to stay within boundaries

Mikulas Patocka <[email protected]>
md: fix a crash in mempool_free

ChiYuan Huang <[email protected]>
mfd: mt6360: Add bounds checking in Regmap read/write call-backs

Christian Brauner <[email protected]>
pnode: terminate at peers of source

Artem Egorkine <[email protected]>
ALSA: line6: fix stack overflow in line6_midi_transmit

Artem Egorkine <[email protected]>
ALSA: line6: correct midi status byte when receiving data from podxt

Zhang Tianci <[email protected]>
ovl: Use ovl mounter's fsuid and fsgid in ovl_link()

Wang Yufen <[email protected]>
binfmt: Fix error return code in load_elf_fdpic_binary()

Aditya Garg <[email protected]>
hfsplus: fix bug causing custom uid and gid being unable to be assigned with mount

Qiujun Huang <[email protected]>
pstore/zone: Use GFP_ATOMIC to allocate zone buffer

Luca Stefani <[email protected]>
pstore: Properly assign mem_type property

Terry Junge <[email protected]>
HID: plantronics: Additional PIDs for double volume key presses quirk

José Expósito <[email protected]>
HID: multitouch: fix Asus ExpertBook P2 P2451FA trackpoint

Nathan Lynch <[email protected]>
powerpc/rtas: avoid scheduling in rtas_os_term()

Nathan Lynch <[email protected]>
powerpc/rtas: avoid device tree lookups in rtas_os_term()

Christophe Leroy <[email protected]>
objtool: Fix SEGFAULT

Yin Xiujiang <[email protected]>
fs/ntfs3: Fix slab-out-of-bounds in r_page

Dan Carpenter <[email protected]>
fs/ntfs3: Delete duplicate condition in ntfs_read_mft()

Tetsuo Handa <[email protected]>
fs/ntfs3: Use __GFP_NOWARN allocation at ntfs_fill_super()

Tetsuo Handa <[email protected]>
fs/ntfs3: Use __GFP_NOWARN allocation at wnd_init()

Edward Lo <[email protected]>
fs/ntfs3: Validate index root when initialize NTFS security

Pierre-Louis Bossart <[email protected]>
soundwire: dmi-quirks: add quirk variant for LAPBC710 NUC15

Hawkins Jiawei <[email protected]>
fs/ntfs3: Fix slab-out-of-bounds read in run_unpack

Edward Lo <[email protected]>
fs/ntfs3: Validate resident attribute name

Edward Lo <[email protected]>
fs/ntfs3: Validate buffer length while parsing index

Edward Lo <[email protected]>
fs/ntfs3: Validate attribute name offset

Edward Lo <[email protected]>
fs/ntfs3: Add null pointer check for inode operations

Shigeru Yoshida <[email protected]>
fs/ntfs3: Fix memory leak on ntfs_fill_super() error path

Edward Lo <[email protected]>
fs/ntfs3: Add null pointer check to attr_load_runs_vcn

Edward Lo <[email protected]>
fs/ntfs3: Validate data run offset

edward lo <[email protected]>
fs/ntfs3: Add overflow check for attribute size

edward lo <[email protected]>
fs/ntfs3: Validate BOOT record_size

Christoph Hellwig <[email protected]>
nvmet: don't defer passthrough commands with trivial effects to the workqueue

Christoph Hellwig <[email protected]>
nvme: fix the NVME_CMD_EFFECTS_CSE_MASK definition

Adam Vodopjan <[email protected]>
ata: ahci: Fix PCS quirk application for suspend

Yu Kuai <[email protected]>
block, bfq: fix uaf for bfqq in bfq_exit_icq_bfqq

Adrian Freund <[email protected]>
ACPI: resource: do IRQ override on Lenovo 14ALC7

Erik Schumacher <[email protected]>
ACPI: resource: do IRQ override on XMG Core 15

Jiri Slaby (SUSE) <[email protected]>
ACPI: resource: do IRQ override on LENOVO IdeaPad

Tamim Khan <[email protected]>
ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA

Keith Busch <[email protected]>
nvme-pci: fix page size checks

Keith Busch <[email protected]>
nvme-pci: fix mempool alloc size

Klaus Jensen <[email protected]>
nvme-pci: fix doorbell buffer value endianness

Sasha Levin <[email protected]>
Revert "selftests/bpf: Add test for unstable CT lookup API"

Paulo Alcantara <[email protected]>
cifs: fix oops during encryption

Miaoqian Lin <[email protected]>
usb: dwc3: qcom: Fix memory leak in dwc3_qcom_interconnect_init

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

Diffstat:

 Makefile                                           |   4 +-
 arch/arm/include/asm/thread_info.h                 |  13 +-
 arch/arm/nwfpe/Makefile                            |   6 +
 arch/arm64/boot/dts/qcom/sdm845-db845c.dts         |   5 +-
 .../boot/dts/qcom/sdm850-lenovo-yoga-c630.dts      |   6 +-
 arch/powerpc/kernel/rtas.c                         |  20 +-
 arch/riscv/include/asm/mmu.h                       |   2 +
 arch/riscv/include/asm/pgtable.h                   |   2 +-
 arch/riscv/include/asm/tlbflush.h                  |  18 ++
 arch/riscv/include/asm/uaccess.h                   |   2 +-
 arch/riscv/kernel/probes/simulate-insn.h           |   4 +-
 arch/riscv/kernel/stacktrace.c                     |   2 +-
 arch/riscv/mm/context.c                            |  10 +
 arch/riscv/mm/tlbflush.c                           |  28 +-
 arch/x86/events/intel/uncore.h                     |   1 +
 arch/x86/events/intel/uncore_snbep.c               |  22 +-
 arch/x86/kernel/cpu/bugs.c                         |   2 +
 arch/x86/kernel/cpu/mce/amd.c                      |  37 +--
 arch/x86/kernel/cpu/mce/core.c                     |  95 +++----
 arch/x86/kernel/cpu/mce/internal.h                 |  12 +-
 arch/x86/kernel/cpu/microcode/intel.c              |   8 +-
 arch/x86/kernel/crash.c                            |   4 +-
 arch/x86/kernel/ftrace.c                           |   2 +
 arch/x86/kernel/kprobes/core.c                     |  10 +-
 arch/x86/kernel/kprobes/opt.c                      |  28 +-
 arch/x86/kvm/vmx/nested.c                          |  47 +++-
 arch/x86/kvm/vmx/sgx.c                             |   4 +-
 block/bfq-iosched.c                                |   2 +-
 block/blk-merge.c                                  |  10 +
 block/mq-deadline.c                                |  84 +++++-
 drivers/acpi/resource.c                            |  78 +++++-
 drivers/acpi/x86/s2idle.c                          |  10 +-
 drivers/ata/ahci.c                                 |  32 ++-
 drivers/base/dd.c                                  |   6 +-
 drivers/char/ipmi/ipmi_msghandler.c                |   4 +-
 drivers/char/ipmi/ipmi_si_intf.c                   |  27 +-
 drivers/char/tpm/eventlog/acpi.c                   |  12 +-
 drivers/char/tpm/tpm_crb.c                         |  29 ++-
 drivers/char/tpm/tpm_tis.c                         |   9 +-
 drivers/cpufreq/cpufreq.c                          |   2 +-
 drivers/crypto/ccp/sp-pci.c                        |  11 +-
 drivers/crypto/n2_core.c                           |   6 +
 drivers/devfreq/devfreq.c                          |   6 +-
 drivers/devfreq/governor_userspace.c               |  12 +-
 drivers/firmware/efi/efi.c                         |   4 +-
 drivers/firmware/efi/libstub/efistub.h             |   2 +
 drivers/firmware/efi/libstub/random.c              |  42 ++-
 drivers/gpio/gpio-sifive.c                         |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c            |  13 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_object.c         |   3 +-
 drivers/gpu/drm/drm_connector.c                    |   3 +
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c       |   4 +-
 drivers/gpu/drm/i915/gt/intel_migrate.c            |   8 +-
 drivers/gpu/drm/i915/gvt/debugfs.c                 |  17 +-
 drivers/gpu/drm/i915/gvt/scheduler.c               |   1 +
 drivers/gpu/drm/imx/ipuv3-plane.c                  |  14 +-
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c          |   6 +-
 drivers/gpu/drm/meson/meson_viu.c                  |   5 +-
 drivers/gpu/drm/mgag200/mgag200_pll.c              |   3 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c            |  27 +-
 drivers/gpu/drm/panfrost/panfrost_gem.c            |  16 +-
 drivers/gpu/drm/panfrost/panfrost_gem.h            |   5 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c                |   3 +-
 drivers/hid/hid-ids.h                              |   3 +
 drivers/hid/hid-multitouch.c                       |   4 +
 drivers/hid/hid-plantronics.c                      |   9 +
 drivers/infiniband/hw/mlx5/counters.c              |   6 +-
 drivers/infiniband/hw/mlx5/qp.c                    |  49 +++-
 drivers/iommu/amd/init.c                           |   7 +
 drivers/md/dm-cache-metadata.c                     |  54 +++-
 drivers/md/dm-cache-target.c                       |  11 +-
 drivers/md/dm-clone-target.c                       |   1 +
 drivers/md/dm-integrity.c                          |   2 +
 drivers/md/dm-thin-metadata.c                      |  60 ++++-
 drivers/md/dm-thin.c                               |  18 +-
 drivers/md/md-bitmap.c                             |  20 +-
 drivers/md/md.c                                    |   9 +-
 drivers/media/dvb-core/dmxdev.c                    |   8 +
 drivers/media/dvb-core/dvbdev.c                    |   1 +
 drivers/media/dvb-frontends/stv0288.c              |   5 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c      |   4 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c       |  12 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c    |  14 +-
 drivers/mfd/mt6360-core.c                          |  14 +-
 drivers/mmc/host/sdhci-sprd.c                      |  16 +-
 drivers/mmc/host/vub300.c                          |   2 +
 drivers/mtd/spi-nor/core.c                         |   2 +
 drivers/net/bonding/bond_3ad.c                     |   1 +
 drivers/net/dsa/mv88e6xxx/Kconfig                  |   4 +-
 drivers/net/ethernet/amazon/ena/ena_com.c          |  29 +--
 drivers/net/ethernet/amazon/ena/ena_ethtool.c      |   6 +-
 drivers/net/ethernet/amazon/ena/ena_netdev.c       |  83 ++++--
 drivers/net/ethernet/amazon/ena/ena_netdev.h       |  17 +-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c           |   3 +
 drivers/net/ethernet/amd/xgbe/xgbe-i2c.c           |   4 +-
 drivers/net/ethernet/amd/xgbe/xgbe-mdio.c          |   4 +-
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.c    | 178 +++++--------
 drivers/net/ethernet/hisilicon/hns3/hns3_enet.h    |   7 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c    |  75 +++---
 .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c  |   3 +-
 .../ethernet/marvell/octeontx2/nic/otx2_common.c   |  30 ++-
 .../ethernet/mellanox/mlx5/core/en/tc_tun_encap.c  |  11 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   2 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    |  12 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h    |   4 +-
 .../mellanox/mlx5/core/esw/acl/egress_lgcy.c       |   7 +-
 .../mellanox/mlx5/core/esw/acl/ingress_lgcy.c      |  33 ++-
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.c  |  30 ++-
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.h  |   6 +
 drivers/net/ethernet/mellanox/mlx5/core/health.c   |   6 +
 .../net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c  |   4 +
 drivers/net/ethernet/mellanox/mlx5/core/main.c     |   2 +
 .../net/ethernet/microchip/sparx5/sparx5_main.c    |   2 +-
 .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c  |   8 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h    |  10 +-
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c   |   8 +-
 drivers/net/ethernet/renesas/ravb_main.c           |   2 +-
 drivers/net/phy/xilinx_gmii2rgmii.c                |   1 +
 drivers/net/usb/rndis_host.c                       |   3 +-
 drivers/net/veth.c                                 |   5 +-
 drivers/net/vmxnet3/vmxnet3_drv.c                  |   8 +
 drivers/net/wireless/microchip/wilc1000/sdio.c     |   1 +
 drivers/nvme/host/core.c                           |  32 ++-
 drivers/nvme/host/nvme.h                           |   2 +-
 drivers/nvme/host/pci.c                            |  37 +--
 drivers/nvme/target/admin-cmd.c                    |  35 +--
 drivers/nvme/target/passthru.c                     |  11 +-
 drivers/of/kexec.c                                 |  10 +-
 drivers/parisc/led.c                               |   3 +
 drivers/pci/pci-sysfs.c                            |  13 +-
 drivers/pci/pci.c                                  |   2 +
 drivers/phy/qualcomm/phy-qcom-qmp.c                |   8 +-
 drivers/remoteproc/remoteproc_core.c               |   9 +-
 drivers/rtc/rtc-ds1347.c                           |   2 +-
 drivers/soc/qcom/Kconfig                           |   1 +
 drivers/soc/ux500/ux500-soc-id.c                   |  10 +-
 drivers/soundwire/dmi-quirks.c                     |   8 +
 drivers/soundwire/intel.c                          |   8 +-
 drivers/soundwire/qcom.c                           |   8 +-
 drivers/soundwire/stream.c                         |   4 +-
 drivers/staging/media/ipu3/ipu3-v4l2.c             |  57 +++--
 drivers/staging/media/tegra-video/csi.c            |   4 +-
 drivers/staging/media/tegra-video/csi.h            |   2 +-
 .../intel/int340x_thermal/processor_thermal_rfim.c |   4 +
 drivers/usb/dwc3/dwc3-qcom.c                       |  13 +-
 drivers/vdpa/vdpa_sim/vdpa_sim.c                   |   3 +-
 drivers/vdpa/vdpa_sim/vdpa_sim_blk.c               |   4 +-
 drivers/vdpa/vdpa_sim/vdpa_sim_net.c               |   4 +-
 drivers/vhost/vhost.c                              |   4 +-
 drivers/vhost/vringh.c                             |   5 +-
 drivers/vhost/vsock.c                              |   9 +-
 drivers/video/fbdev/matrox/matroxfb_base.c         |   4 +-
 fs/binfmt_elf_fdpic.c                              |   5 +-
 fs/btrfs/backref.c                                 |   4 +
 fs/btrfs/disk-io.c                                 |  35 ++-
 fs/btrfs/disk-io.h                                 |   6 +-
 fs/btrfs/ioctl.c                                   |   9 +-
 fs/btrfs/rcu-string.h                              |   6 +-
 fs/btrfs/super.c                                   |  76 ++++++
 fs/btrfs/tree-defrag.c                             |   6 +-
 fs/btrfs/volumes.c                                 |  43 ++--
 fs/ceph/caps.c                                     |   2 +-
 fs/ceph/locks.c                                    |   4 -
 fs/ceph/super.h                                    |   1 -
 fs/cifs/cifsfs.c                                   |   8 +-
 fs/cifs/cifsglob.h                                 |  69 +++++
 fs/cifs/cifsproto.h                                |   4 +-
 fs/cifs/connect.c                                  |   4 +-
 fs/cifs/misc.c                                     |   4 +-
 fs/cifs/smb2ops.c                                  | 143 +++++------
 fs/dlm/lowcomms.c                                  |   9 +-
 fs/ext4/balloc.c                                   |   2 +-
 fs/ext4/ext4.h                                     |   9 +-
 fs/ext4/ext4_jbd2.c                                |   3 +-
 fs/ext4/extents.c                                  |   8 +
 fs/ext4/extents_status.c                           |   3 +-
 fs/ext4/fast_commit.c                              | 285 ++++++++++++---------
 fs/ext4/fast_commit.h                              |   7 +-
 fs/ext4/indirect.c                                 |  13 +-
 fs/ext4/inode.c                                    |  50 +++-
 fs/ext4/ioctl.c                                    |  13 +-
 fs/ext4/namei.c                                    |  47 ++--
 fs/ext4/orphan.c                                   |  26 +-
 fs/ext4/resize.c                                   |   6 +-
 fs/ext4/super.c                                    |  52 +++-
 fs/ext4/verity.c                                   |   2 +-
 fs/ext4/xattr.c                                    |  19 +-
 fs/f2fs/gc.c                                       |   1 +
 fs/f2fs/node.c                                     |   3 +-
 fs/hfs/inode.c                                     |  13 +-
 fs/hfsplus/hfsplus_fs.h                            |   2 +
 fs/hfsplus/inode.c                                 |  16 +-
 fs/hfsplus/options.c                               |   4 +
 fs/ksmbd/auth.c                                    |   3 +-
 fs/ksmbd/connection.c                              |   7 +-
 fs/ksmbd/transport_tcp.c                           |   5 +-
 fs/locks.c                                         |  23 ++
 fs/mbcache.c                                       | 121 ++++-----
 fs/nfsd/nfs4xdr.c                                  |  11 +
 fs/nfsd/nfssvc.c                                   |   2 +-
 fs/ntfs3/attrib.c                                  |  18 ++
 fs/ntfs3/attrlist.c                                |   5 +
 fs/ntfs3/bitmap.c                                  |   2 +-
 fs/ntfs3/file.c                                    |   4 +-
 fs/ntfs3/frecord.c                                 |  14 +
 fs/ntfs3/fslog.c                                   |  35 +--
 fs/ntfs3/fsntfs.c                                  |  10 +-
 fs/ntfs3/index.c                                   |   6 +
 fs/ntfs3/inode.c                                   |   9 +
 fs/ntfs3/record.c                                  |  10 +
 fs/ntfs3/super.c                                   |   9 +-
 fs/overlayfs/dir.c                                 |  46 ++--
 fs/pnode.c                                         |   2 +-
 fs/pstore/ram.c                                    |   2 +-
 fs/pstore/zone.c                                   |   2 +-
 fs/quota/dquot.c                                   |   2 +
 fs/udf/inode.c                                     |   2 +-
 include/linux/devfreq.h                            |   7 +-
 include/linux/efi.h                                |   2 -
 include/linux/fs.h                                 |   6 +
 include/linux/mbcache.h                            |  33 ++-
 include/linux/mlx5/device.h                        |   5 +
 include/linux/mlx5/mlx5_ifc.h                      |   3 +-
 include/linux/netfilter/ipset/ip_set.h             |   2 +-
 include/linux/nvme.h                               |   3 +-
 include/linux/sunrpc/rpc_pipe_fs.h                 |   5 +
 include/net/mptcp.h                                |  12 +-
 include/net/netfilter/nf_tables.h                  |  25 +-
 include/sound/soc-dai.h                            |  32 +--
 include/trace/events/ext4.h                        |   7 +-
 include/trace/events/jbd2.h                        |  44 ++--
 io_uring/io_uring.c                                |  13 +-
 kernel/events/core.c                               |   6 +-
 kernel/kcsan/core.c                                |  50 ++++
 kernel/rcu/tasks.h                                 |  20 +-
 kernel/trace/Kconfig                               |   2 +
 kernel/trace/trace.c                               |  38 ++-
 kernel/trace/trace.h                               |  27 +-
 kernel/trace/trace_eprobe.c                        |   3 +
 kernel/trace/trace_events_hist.c                   |  11 +-
 kernel/trace/trace_events_synth.c                  |   2 +-
 kernel/trace/trace_probe.c                         |   2 +-
 mm/compaction.c                                    |  18 +-
 net/caif/cfctrl.c                                  |   6 +-
 net/core/filter.c                                  |   7 +-
 net/ipv4/syncookies.c                              |   7 +-
 net/mptcp/subflow.c                                |  76 ++++--
 net/netfilter/ipset/ip_set_core.c                  |   7 +-
 net/netfilter/ipset/ip_set_hash_ip.c               |  14 +-
 net/netfilter/ipset/ip_set_hash_ipmark.c           |  13 +-
 net/netfilter/ipset/ip_set_hash_ipport.c           |  13 +-
 net/netfilter/ipset/ip_set_hash_ipportip.c         |  13 +-
 net/netfilter/ipset/ip_set_hash_ipportnet.c        |  13 +-
 net/netfilter/ipset/ip_set_hash_net.c              |  17 +-
 net/netfilter/ipset/ip_set_hash_netiface.c         |  15 +-
 net/netfilter/ipset/ip_set_hash_netnet.c           |  23 +-
 net/netfilter/ipset/ip_set_hash_netport.c          |  19 +-
 net/netfilter/ipset/ip_set_hash_netportnet.c       |  40 +--
 net/netfilter/nf_tables_api.c                      | 261 ++++++++++++-------
 net/nfc/netlink.c                                  |  52 +++-
 net/packet/af_packet.c                             |  20 +-
 net/sched/cls_tcindex.c                            |  12 +-
 net/sched/sch_atm.c                                |   5 +-
 net/sched/sch_cbq.c                                |   4 +-
 net/sunrpc/auth_gss/auth_gss.c                     |  19 +-
 net/sunrpc/auth_gss/svcauth_gss.c                  |   9 +-
 security/device_cgroup.c                           |  33 ++-
 security/integrity/ima/ima_template.c              |   5 +-
 security/integrity/platform_certs/load_uefi.c      |   1 +
 sound/pci/hda/patch_realtek.c                      |  50 ++++
 sound/soc/codecs/hdac_hda.c                        |  22 +-
 sound/soc/codecs/max98373-sdw.c                    |   2 +-
 sound/soc/codecs/rt1308-sdw.c                      |   2 +-
 sound/soc/codecs/rt1316-sdw.c                      |   2 +-
 sound/soc/codecs/rt5682-sdw.c                      |   2 +-
 sound/soc/codecs/rt700.c                           |   2 +-
 sound/soc/codecs/rt711-sdca.c                      |   2 +-
 sound/soc/codecs/rt711.c                           |   2 +-
 sound/soc/codecs/rt715-sdca.c                      |   2 +-
 sound/soc/codecs/rt715.c                           |   2 +-
 sound/soc/codecs/sdw-mockup.c                      |   2 +-
 sound/soc/codecs/wcd938x.c                         |   2 +-
 sound/soc/codecs/wsa881x.c                         |   2 +-
 sound/soc/intel/boards/bytcr_rt5640.c              |  15 ++
 sound/soc/intel/boards/sof_sdw.c                   |   6 +-
 sound/soc/intel/skylake/skl-pcm.c                  |   7 +-
 sound/soc/jz4740/jz4740-i2s.c                      |  39 ++-
 sound/soc/qcom/sdm845.c                            |   4 +-
 sound/soc/qcom/sm8250.c                            |   4 +-
 sound/soc/sof/intel/hda-dai.c                      |   7 +-
 sound/usb/line6/driver.c                           |   3 +-
 sound/usb/line6/midi.c                             |   6 +-
 sound/usb/line6/midibuf.c                          |  25 +-
 sound/usb/line6/midibuf.h                          |   5 +-
 sound/usb/line6/pod.c                              |   3 +-
 tools/objtool/check.c                              |   2 +-
 tools/perf/util/cgroup.c                           |  23 +-
 tools/perf/util/data.c                             |   2 +
 tools/perf/util/dwarf-aux.c                        |  23 +-
 tools/testing/ktest/ktest.pl                       |  23 +-
 tools/testing/selftests/Makefile                   |  26 +-
 tools/testing/selftests/bpf/config                 |   4 -
 tools/testing/selftests/bpf/prog_tests/bpf_nf.c    |  48 ----
 tools/testing/selftests/bpf/progs/test_bpf_nf.c    | 109 --------
 tools/testing/selftests/lib.mk                     |   5 +
 305 files changed, 3239 insertions(+), 1867 deletions(-)
author maintainer
#1 lore raw

PATCH 1/290 usb: dwc3: qcom: Fix memory leak in dwc3_qcom_interconnect_init

From: Miaoqian Lin <[email protected]>

[ Upstream commit 97a48da1619ba6bd42a0e5da0a03aa490a9496b1 ]

of_icc_get() alloc resources for path handle, we should release it when not need anymore. Like the release in dwc3_qcom_interconnect_exit() function. Add icc_put() in error handling to fix this.

Fixes bea46b981515 ("usb: dwc3: qcom: Add interconnect support in dwc3 driver")
Cc stable <[email protected]>
---
 drivers/usb/dwc3/dwc3-qcom.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/usb/dwc3/dwc3-qcom.c +10 -3
index d0352daab012..ec1de6f6c290 100644
@@ -258,7 +258,8 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
 	if (IS_ERR(qcom->icc_path_apps)) {
 		dev_err(dev, "failed to get apps-usb path: %ld\n",
 				PTR_ERR(qcom->icc_path_apps));
-		return PTR_ERR(qcom->icc_path_apps);
+		ret = PTR_ERR(qcom->icc_path_apps);
+		goto put_path_ddr;
 	}
 
 	if (usb_get_maximum_speed(&qcom->dwc3->dev) >= USB_SPEED_SUPER ||
@@ -271,17 +272,23 @@ static int dwc3_qcom_interconnect_init(struct dwc3_qcom *qcom)
 
 	if (ret) {
 		dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret);
-		return ret;
+		goto put_path_apps;
 	}
 
 	ret = icc_set_bw(qcom->icc_path_apps,
 		APPS_USB_AVG_BW, APPS_USB_PEAK_BW);
 	if (ret) {
 		dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret);
-		return ret;
+		goto put_path_apps;
 	}
 
 	return 0;
+
+put_path_apps:
+	icc_put(qcom->icc_path_apps);
+put_path_ddr:
+	icc_put(qcom->icc_path_ddr);
+	return ret;
 }
 
 /**
Signature · 1 line
2.35.1
author maintainer
#2 lore raw

PATCH 2/290 cifs: fix oops during encryption

In reply to Greg Kroah-Hartman

From: Paulo Alcantara <[email protected]>

[ Upstream commit f7f291e14dde32a07b1f0aa06921d28f875a7b54 ]

When running xfstests against Azure the following oops occurred on an arm64 system

  Unable to handle kernel write to read-only memory at virtual address
  ffff0001221cf000
  Mem abort info:
    ESR = 0x9600004f
    EC = 0x25: DABT (current EL), IL = 32 bits
    SET = 0, FnV = 0
    EA = 0, S1PTW = 0
    FSC = 0x0f: level 3 permission fault
  Data abort info:
    ISV = 0, ISS = 0x0000004f
    CM = 0, WnR = 1
  swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000294f3000
  [ffff0001221cf000] pgd=18000001ffff8003, p4d=18000001ffff8003,
  pud=18000001ff82e003, pmd=18000001ff71d003, pte=00600001221cf787
  Internal error: Oops: 9600004f [#1] PREEMPT SMP
  ...
  pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
  pc : __memcpy+0x40/0x230
  lr : scatterwalk_copychunks+0xe0/0x200
  sp : ffff800014e92de0
  x29: ffff800014e92de0 x28: ffff000114f9de80 x27: 0000000000000008
  x26: 0000000000000008 x25: ffff800014e92e78 x24: 0000000000000008
  x23: 0000000000000001 x22: 0000040000000000 x21: ffff000000000000
  x20: 0000000000000001 x19: ffff0001037c4488 x18: 0000000000000014
  x17: 235e1c0d6efa9661 x16: a435f9576b6edd6c x15: 0000000000000058
  x14: 0000000000000001 x13: 0000000000000008 x12: ffff000114f2e590
  x11: ffffffffffffffff x10: 0000040000000000 x9 : ffff8000105c3580
  x8 : 2e9413b10000001a x7 : 534b4410fb86b005 x6 : 534b4410fb86b005
  x5 : ffff0001221cf008 x4 : ffff0001037c4490 x3 : 0000000000000001
  x2 : 0000000000000008 x1 : ffff0001037c4488 x0 : ffff0001221cf000
  Call trace:
   __memcpy+0x40/0x230
   scatterwalk_map_and_copy+0x98/0x100
   crypto_ccm_encrypt+0x150/0x180
   crypto_aead_encrypt+0x2c/0x40
   crypt_message+0x750/0x880
   smb3_init_transform_rq+0x298/0x340
   smb_send_rqst.part.11+0xd8/0x180
   smb_send_rqst+0x3c/0x100
   compound_send_recv+0x534/0xbc0
   smb2_query_info_compound+0x32c/0x440
   smb2_set_ea+0x438/0x4c0
   cifs_xattr_set+0x5d4/0x7c0

This is because in scatterwalk_copychunks(), we attempted to write to a buffer (@sign) that was allocated in the stack (vmalloc area) by crypt_message() and thus accessing its remaining 8 (x2) bytes ended up crossing a page boundary.

To simply fix it, we could just pass @sign kmalloc'd from crypt_message() and then we're done. Luckily, we don't seem to pass any other vmalloc'd buffers in smb_rqst::rq_iov...

Instead, let's map the correct pages and offsets from vmalloc buffers as well in cifs_sg_set_buf() and then avoiding such oopses.

---
 fs/cifs/cifsglob.h  |  69 +++++++++++++++++++++
 fs/cifs/cifsproto.h |   4 +-
 fs/cifs/misc.c      |   4 +-
 fs/cifs/smb2ops.c   | 143 +++++++++++++++++++++-----------------------
 4 files changed, 141 insertions(+), 79 deletions(-)
fs/cifs/cifsglob.h +69 -0
index 1ab72c3d0bff..0f1b9c48838c 100644
@@ -13,6 +13,8 @@
 #include <linux/in6.h>
 #include <linux/inet.h>
 #include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include <linux/mm.h>
 #include <linux/mempool.h>
 #include <linux/workqueue.h>
 #include "cifs_fs_sb.h"
@@ -21,6 +23,7 @@
 #include <linux/scatterlist.h>
 #include <uapi/linux/cifs/cifs_mount.h>
 #include "smb2pdu.h"
+#include "smb2glob.h"
 
 #define CIFS_MAGIC_NUMBER 0xFF534D42      /* the first four bytes of SMB PDUs */
 
@@ -1972,4 +1975,70 @@ static inline bool cifs_is_referral_server(struct cifs_tcon *tcon,
 	return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER));
 }
 
+static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
+					    int num_rqst,
+					    const u8 *sig)
+{
+	unsigned int len, skip;
+	unsigned int nents = 0;
+	unsigned long addr;
+	int i, j;
+
+	/* Assumes the first rqst has a transform header as the first iov.
+	 * I.e.
+	 * rqst[0].rq_iov[0]  is transform header
+	 * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+	 * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+	 */
+	for (i = 0; i < num_rqst; i++) {
+		/*
+		 * The first rqst has a transform header where the
+		 * first 20 bytes are not part of the encrypted blob.
+		 */
+		for (j = 0; j < rqst[i].rq_nvec; j++) {
+			struct kvec *iov = &rqst[i].rq_iov[j];
+
+			skip = (i == 0) && (j == 0) ? 20 : 0;
+			addr = (unsigned long)iov->iov_base + skip;
+			if (unlikely(is_vmalloc_addr((void *)addr))) {
+				len = iov->iov_len - skip;
+				nents += DIV_ROUND_UP(offset_in_page(addr) + len,
+						      PAGE_SIZE);
+			} else {
+				nents++;
+			}
+		}
+		nents += rqst[i].rq_npages;
+	}
+	nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
+	return nents;
+}
+
+/* We can not use the normal sg_set_buf() as we will sometimes pass a
+ * stack object as buf.
+ */
+static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
+						  const void *buf,
+						  unsigned int buflen)
+{
+	unsigned long addr = (unsigned long)buf;
+	unsigned int off = offset_in_page(addr);
+
+	addr &= PAGE_MASK;
+	if (unlikely(is_vmalloc_addr((void *)addr))) {
+		do {
+			unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
+
+			sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);
+
+			off = 0;
+			addr += PAGE_SIZE;
+			buflen -= len;
+		} while (buflen);
+	} else {
+		sg_set_page(sg++, virt_to_page(addr), buflen, off);
+	}
+	return sg;
+}
+
 #endif	/* _CIFS_GLOB_H */
fs/cifs/cifsproto.h +2 -2
index b2697356b5e7..50844d51da5d 100644
@@ -590,8 +590,8 @@ int cifs_alloc_hash(const char *name, struct crypto_shash **shash,
 		    struct sdesc **sdesc);
 void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
 
-extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
-				unsigned int *len, unsigned int *offset);
+void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
+			  unsigned int *len, unsigned int *offset);
 struct cifs_chan *
 cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
 int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
fs/cifs/misc.c +2 -2
index 94143d7f58c7..3a90ee314ed7 100644
@@ -1134,8 +1134,8 @@ cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc)
  * @len: Where to store the length for this page:
  * @offset: Where to store the offset for this page
  */
-void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
-				unsigned int *len, unsigned int *offset)
+void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
+			  unsigned int *len, unsigned int *offset)
 {
 	*len = rqst->rq_pagesz;
 	*offset = (page == 0) ? rqst->rq_offset : 0;
fs/cifs/smb2ops.c +68 -75

197 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#3 lore raw

PATCH 3/290 Revert "selftests/bpf: Add test for unstable CT lookup API"

In reply to Greg Kroah-Hartman

This reverts commit f463a1295c4fa73eac0b16fbfbdfc5726b06445d.

---
 tools/testing/selftests/bpf/config            |   4 -
 .../testing/selftests/bpf/prog_tests/bpf_nf.c |  48 --------
 .../testing/selftests/bpf/progs/test_bpf_nf.c | 109 ------------------
 3 files changed, 161 deletions(-)
 delete mode 100644 tools/testing/selftests/bpf/prog_tests/bpf_nf.c
 delete mode 100644 tools/testing/selftests/bpf/progs/test_bpf_nf.c
tools/testing/selftests/bpf/config +0 -4
index 4a2a47fcd6ef..5192305159ec 100644
@@ -46,7 +46,3 @@ CONFIG_IMA_READ_POLICY=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_FUNCTION_TRACER=y
 CONFIG_DYNAMIC_FTRACE=y
-CONFIG_NETFILTER=y
-CONFIG_NF_DEFRAG_IPV4=y
-CONFIG_NF_DEFRAG_IPV6=y
-CONFIG_NF_CONNTRACK=y
tools/testing/selftests/bpf/prog_tests/bpf_nf.c deleted +0 -48

48 lines not on this page · raw message

tools/testing/selftests/bpf/progs/test_bpf_nf.c deleted +0 -109

109 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#4 lore raw

PATCH 4/290 nvme-pci: fix doorbell buffer value endianness

In reply to Greg Kroah-Hartman

From: Klaus Jensen <[email protected]>

[ Upstream commit b5f96cb719d8ba220b565ddd3ba4ac0d8bcfb130 ]

When using shadow doorbells, the event index and the doorbell values are written to host memory. Prior to this patch, the values written would erroneously be written in host endianness. This causes trouble on big-endian platforms. Fix this by adding missing endian conversions.

This issue was noticed by Guenter while testing various big-endian platforms under QEMU[1]. A similar fix required for hw/nvme in QEMU is up for review as well[2].

[1]: https://lore.kernel.org/qemu-devel/[email protected]/
[2]: https://lore.kernel.org/qemu-devel/[email protected]/

Fixes f9f38e33389c ("nvme: improve performance for virtual NVMe devices")
---
 drivers/nvme/host/pci.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/nvme/host/pci.c +13 -12
index d49df7123677..ab038dbafc06 100644
@@ -142,9 +142,9 @@ struct nvme_dev {
 	mempool_t *iod_mempool;
 
 	/* shadow doorbell buffer support: */
-	u32 *dbbuf_dbs;
+	__le32 *dbbuf_dbs;
 	dma_addr_t dbbuf_dbs_dma_addr;
-	u32 *dbbuf_eis;
+	__le32 *dbbuf_eis;
 	dma_addr_t dbbuf_eis_dma_addr;
 
 	/* host memory buffer support: */
@@ -208,10 +208,10 @@ struct nvme_queue {
 #define NVMEQ_SQ_CMB		1
 #define NVMEQ_DELETE_ERROR	2
 #define NVMEQ_POLLED		3
-	u32 *dbbuf_sq_db;
-	u32 *dbbuf_cq_db;
-	u32 *dbbuf_sq_ei;
-	u32 *dbbuf_cq_ei;
+	__le32 *dbbuf_sq_db;
+	__le32 *dbbuf_cq_db;
+	__le32 *dbbuf_sq_ei;
+	__le32 *dbbuf_cq_ei;
 	struct completion delete_done;
 };
 
@@ -332,11 +332,11 @@ static inline int nvme_dbbuf_need_event(u16 event_idx, u16 new_idx, u16 old)
 }
 
 /* Update dbbuf and return true if an MMIO is required */
-static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
-					      volatile u32 *dbbuf_ei)
+static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
+					      volatile __le32 *dbbuf_ei)
 {
 	if (dbbuf_db) {
-		u16 old_value;
+		u16 old_value, event_idx;
 
 		/*
 		 * Ensure that the queue is written before updating
@@ -344,8 +344,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
 		 */
 		wmb();
 
-		old_value = *dbbuf_db;
-		*dbbuf_db = value;
+		old_value = le32_to_cpu(*dbbuf_db);
+		*dbbuf_db = cpu_to_le32(value);
 
 		/*
 		 * Ensure that the doorbell is updated before reading the event
@@ -355,7 +355,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
 		 */
 		mb();
 
-		if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value))
+		event_idx = le32_to_cpu(*dbbuf_ei);
+		if (!nvme_dbbuf_need_event(event_idx, value, old_value))
 			return false;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#5 lore raw

PATCH 5/290 nvme-pci: fix mempool alloc size

In reply to Greg Kroah-Hartman

From: Keith Busch <[email protected]>

[ Upstream commit c89a529e823d51dd23c7ec0c047c7a454a428541 ]

Convert the max size to bytes to match the units of the divisor that calculates the worst-case number of PRP entries.

The result is used to determine how many PRP Lists are required. The code was previously rounding this to 1 list, but we can require 2 in the worst case. In that scenario, the driver would corrupt memory beyond the size provided by the mempool.

While unlikely to occur (you'd need a 4MB in exactly 127 phys segments on a queue that doesn't support SGLs), this memory corruption has been observed by kfence.

Cc Jens Axboe <[email protected]>
Fixes 943e942e6266f ("nvme-pci: limit max IO size and segments to avoid high order allocations")
---
 drivers/nvme/host/pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/host/pci.c +2 -2
index ab038dbafc06..7a96cbbfdabb 100644
@@ -370,8 +370,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db,
  */
 static int nvme_pci_npages_prp(void)
 {
-	unsigned nprps = DIV_ROUND_UP(NVME_MAX_KB_SZ + NVME_CTRL_PAGE_SIZE,
-				      NVME_CTRL_PAGE_SIZE);
+	unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
+	unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
 	return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
 }
 
Signature · 1 line
2.35.1
author maintainer
#6 lore raw

PATCH 6/290 nvme-pci: fix page size checks

In reply to Greg Kroah-Hartman

From: Keith Busch <[email protected]>

[ Upstream commit 841734234a28fd5cd0889b84bd4d93a0988fa11e ]

The size allocated out of the dma pool is at most NVME_CTRL_PAGE_SIZE, which may be smaller than the PAGE_SIZE.

Fixes c61b82c7b7134 ("nvme-pci: fix PRP pool size")
---
 drivers/nvme/host/pci.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/nvme/host/pci.c +4 -4
index 7a96cbbfdabb..0165e65cf548 100644
@@ -33,7 +33,7 @@
 #define SQ_SIZE(q)	((q)->q_depth << (q)->sqes)
 #define CQ_SIZE(q)	((q)->q_depth * sizeof(struct nvme_completion))
 
-#define SGES_PER_PAGE	(PAGE_SIZE / sizeof(struct nvme_sgl_desc))
+#define SGES_PER_PAGE	(NVME_CTRL_PAGE_SIZE / sizeof(struct nvme_sgl_desc))
 
 /*
  * These can be higher, but we need to ensure that any command doesn't
@@ -372,7 +372,7 @@ static int nvme_pci_npages_prp(void)
 {
 	unsigned max_bytes = (NVME_MAX_KB_SZ * 1024) + NVME_CTRL_PAGE_SIZE;
 	unsigned nprps = DIV_ROUND_UP(max_bytes, NVME_CTRL_PAGE_SIZE);
-	return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
+	return DIV_ROUND_UP(8 * nprps, NVME_CTRL_PAGE_SIZE - 8);
 }
 
 /*
@@ -382,7 +382,7 @@ static int nvme_pci_npages_prp(void)
 static int nvme_pci_npages_sgl(void)
 {
 	return DIV_ROUND_UP(NVME_MAX_SEGS * sizeof(struct nvme_sgl_desc),
-			PAGE_SIZE);
+			NVME_CTRL_PAGE_SIZE);
 }
 
 static size_t nvme_pci_iod_alloc_size(void)
@@ -732,7 +732,7 @@ static void nvme_pci_sgl_set_seg(struct nvme_sgl_desc *sge,
 		sge->length = cpu_to_le32(entries * sizeof(*sge));
 		sge->type = NVME_SGL_FMT_LAST_SEG_DESC << 4;
 	} else {
-		sge->length = cpu_to_le32(PAGE_SIZE);
+		sge->length = cpu_to_le32(NVME_CTRL_PAGE_SIZE);
 		sge->type = NVME_SGL_FMT_SEG_DESC << 4;
 	}
 }
Signature · 1 line
2.35.1
author maintainer
#7 lore raw

PATCH 7/290 ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA

In reply to Greg Kroah-Hartman

From: Tamim Khan <[email protected]>

[ Upstream commit e12dee3736731e24b1e7367f87d66ac0fcd73ce7 ]

In the ACPI DSDT table for Asus VivoBook K3402ZA/K3502ZA IRQ 1 is described as ActiveLow; however, the kernel overrides it to Edge_High. This prevents the internal keyboard from working on these laptops. In order to fix this add these laptops to the skip_override_table so that the kernel does not override IRQ 1 to Edge_High.

Stable-dep-of: f3cb9b740869 ("ACPI: resource: do IRQ override on Lenovo 14ALC7")

---
 drivers/acpi/resource.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/acpi/resource.c +19 -0
index 19358a641610..596ca9fae389 100644
@@ -399,6 +399,24 @@ static const struct dmi_system_id medion_laptop[] = {
 	{ }
 };
 
+static const struct dmi_system_id asus_laptop[] = {
+	{
+		.ident = "Asus Vivobook K3402ZA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"),
+		},
+	},
+	{
+		.ident = "Asus Vivobook K3502ZA",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"),
+		},
+	},
+	{ }
+};
+
 struct irq_override_cmp {
 	const struct dmi_system_id *system;
 	unsigned char irq;
@@ -409,6 +427,7 @@ struct irq_override_cmp {
 
 static const struct irq_override_cmp skip_override_table[] = {
 	{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
+	{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
 };
 
 static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
Signature · 1 line
2.35.1
author maintainer
#8 lore raw

PATCH 8/290 ACPI: resource: do IRQ override on LENOVO IdeaPad

In reply to Greg Kroah-Hartman

From: Jiri Slaby (SUSE) <[email protected]>

[ Upstream commit bfcdf58380b1d9be564a78a9370da722ed1a9965 ]

LENOVO IdeaPad Flex 5 is ryzen-5 based and the commit below removed IRQ overriding for those. This broke touchscreen and trackpad:
i2c_designware AMDI0010:00: controller timed out i2c_designware AMDI0010:03: controller timed out i2c_hid_acpi i2c-MSFT0001:00: failed to reset device: -61 i2c_designware AMDI0010:03: controller timed out
...
i2c_hid_acpi i2c-MSFT0001:00: can't add hid device: -61
i2c_hid_acpi: probe of i2c-MSFT0001:00 failed with error -61

White-list this specific model in the override_table.

For this to work, the ZEN test needs to be put below the table walk.

Fixes 37c81d9f1d1b (ACPI: resource: skip IRQ override on AMD Zen platforms)

Stable-dep-of: f3cb9b740869 ("ACPI: resource: do IRQ override on Lenovo 14ALC7")

---
 drivers/acpi/resource.c | 42 +++++++++++++++++++++++++++--------------
 1 file changed, 28 insertions(+), 14 deletions(-)
drivers/acpi/resource.c +28 -14
index 596ca9fae389..5154c9861ece 100644
@@ -417,17 +417,31 @@ static const struct dmi_system_id asus_laptop[] = {
 	{ }
 };
 
+static const struct dmi_system_id lenovo_82ra[] = {
+	{
+		.ident = "LENOVO IdeaPad Flex 5 16ALC7",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "82RA"),
+		},
+	},
+	{ }
+};
+
 struct irq_override_cmp {
 	const struct dmi_system_id *system;
 	unsigned char irq;
 	unsigned char triggering;
 	unsigned char polarity;
 	unsigned char shareable;
+	bool override;
 };
 
-static const struct irq_override_cmp skip_override_table[] = {
-	{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
-	{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 },
+static const struct irq_override_cmp override_table[] = {
+	{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
+	{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
+	{ lenovo_82ra, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
+	{ lenovo_82ra, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
 };
 
 static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
@@ -435,6 +449,17 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
 {
 	int i;
 
+	for (i = 0; i < ARRAY_SIZE(override_table); i++) {
+		const struct irq_override_cmp *entry = &override_table[i];
+
+		if (dmi_check_system(entry->system) &&
+		    entry->irq == gsi &&
+		    entry->triggering == triggering &&
+		    entry->polarity == polarity &&
+		    entry->shareable == shareable)
+			return entry->override;
+	}
+
 #ifdef CONFIG_X86
 	/*
 	 * IRQ override isn't needed on modern AMD Zen systems and
@@ -445,17 +470,6 @@ static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
 		return false;
 #endif
 
-	for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) {
-		const struct irq_override_cmp *entry = &skip_override_table[i];
-
-		if (dmi_check_system(entry->system) &&
-		    entry->irq == gsi &&
-		    entry->triggering == triggering &&
-		    entry->polarity == polarity &&
-		    entry->shareable == shareable)
-			return false;
-	}
-
 	return true;
 }
 
Signature · 1 line
2.35.1
author maintainer
#9 lore raw

PATCH 9/290 ACPI: resource: do IRQ override on XMG Core 15

In reply to Greg Kroah-Hartman

From: Erik Schumacher <[email protected]>

[ Upstream commit 7592b79ba4a91350b38469e05238308bcfe1019b ]

The Schenker XMG CORE 15 (M22) is Ryzen-6 based and needs IRQ overriding for the keyboard to work. Adding an entry for this laptop to the override_table makes the internal keyboard functional again.

Stable-dep-of: f3cb9b740869 ("ACPI: resource: do IRQ override on Lenovo 14ALC7")

---
 drivers/acpi/resource.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/acpi/resource.c +12 -0
index 5154c9861ece..d0bed7e66a33 100644
@@ -428,6 +428,17 @@ static const struct dmi_system_id lenovo_82ra[] = {
 	{ }
 };
 
+static const struct dmi_system_id schenker_gm_rg[] = {
+	{
+		.ident = "XMG CORE 15 (M22)",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SchenkerTechnologiesGmbH"),
+			DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
+		},
+	},
+	{ }
+};
+
 struct irq_override_cmp {
 	const struct dmi_system_id *system;
 	unsigned char irq;
@@ -442,6 +453,7 @@ static const struct irq_override_cmp override_table[] = {
 	{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
 	{ lenovo_82ra, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
 	{ lenovo_82ra, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
+	{ schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
 };
 
 static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity,
Signature · 1 line
2.35.1
author maintainer
#10 lore raw

PATCH 10/290 ACPI: resource: do IRQ override on Lenovo 14ALC7

In reply to Greg Kroah-Hartman

From: Adrian Freund <[email protected]>

[ Upstream commit f3cb9b740869712d448edf3b9ef5952b847caf8b ]

Commit bfcdf58380b1 ("ACPI: resource: do IRQ override on LENOVO IdeaPad") added an override for Lenovo IdeaPad 5 16ALC7. The 14ALC7 variant also suffers from a broken touchscreen and trackpad.

Fixes 9946e39fe8d0 ("ACPI: resource: skip IRQ override on AMD Zen platforms")
---
 drivers/acpi/resource.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/acpi/resource.c +10 -3
index d0bed7e66a33..33921949bd8f 100644
@@ -417,7 +417,14 @@ static const struct dmi_system_id asus_laptop[] = {
 	{ }
 };
 
-static const struct dmi_system_id lenovo_82ra[] = {
+static const struct dmi_system_id lenovo_laptop[] = {
+	{
+		.ident = "LENOVO IdeaPad Flex 5 14ALC7",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "82R9"),
+		},
+	},
 	{
 		.ident = "LENOVO IdeaPad Flex 5 16ALC7",
 		.matches = {
@@ -451,8 +458,8 @@ struct irq_override_cmp {
 static const struct irq_override_cmp override_table[] = {
 	{ medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
 	{ asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, false },
-	{ lenovo_82ra, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
-	{ lenovo_82ra, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
+	{ lenovo_laptop, 6, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
+	{ lenovo_laptop, 10, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0, true },
 	{ schenker_gm_rg, 1, ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_LOW, 1, true },
 };
 
Signature · 1 line
2.35.1
author maintainer
#11 lore raw

PATCH 11/290 block, bfq: fix uaf for bfqq in bfq_exit_icq_bfqq

In reply to Greg Kroah-Hartman

From: Yu Kuai <[email protected]>

[ Upstream commit 246cf66e300b76099b5dbd3fdd39e9a5dbc53f02 ]

Commit 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'") will access 'bic->bfqq' in bic_set_bfqq(), however, bfq_exit_icq_bfqq() can free bfqq first, and then call bic_set_bfqq(), which will cause uaf.

Fix the problem by moving bfq_exit_bfqq() behind bic_set_bfqq().

Fixes 64dc8c732f5c ("block, bfq: fix possible uaf for 'bfqq->bic'")
---
 block/bfq-iosched.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
block/bfq-iosched.c +1 -1
index b8b6e9eae94b..85120d7b5cf0 100644
@@ -5251,8 +5251,8 @@ static void bfq_exit_icq_bfqq(struct bfq_io_cq *bic, bool is_sync)
 		unsigned long flags;
 
 		spin_lock_irqsave(&bfqd->lock, flags);
-		bfq_exit_bfqq(bfqd, bfqq);
 		bic_set_bfqq(bic, NULL, is_sync);
+		bfq_exit_bfqq(bfqd, bfqq);
 		spin_unlock_irqrestore(&bfqd->lock, flags);
 	}
 }
Signature · 1 line
2.35.1
author maintainer
#12 lore raw

PATCH 12/290 ata: ahci: Fix PCS quirk application for suspend

In reply to Greg Kroah-Hartman

From: Adam Vodopjan <[email protected]>

[ Upstream commit 37e14e4f3715428b809e4df9a9958baa64c77d51 ]

Since kernel 5.3.4 my laptop (ICH8M controller) does not see Kingston SV300S37A60G SSD disk connected into a SATA connector on wake from suspend. The problem was introduced in c312ef176399 ("libata/ahci: Drop PCS quirk for Denverton and beyond"): the quirk is not applied on wake from suspend as it originally was.

It is worth to mention the commit contained another bug: the quirk is not applied at all to controllers which require it. The fix commit 09d6ac8dc51a ("libata/ahci: Fix PCS quirk application") landed in 5.3.8. So testing my patch anywhere between commits c312ef176399 and 09d6ac8dc51a is pointless.

Not all disks trigger the problem. For example nothing bad happens with Western Digital WD5000LPCX HDD.

Test hardware:
- Acer 5920G with ICH8M SATA controller
- sda: some SATA HDD connnected into the DVD drive IDE port with a SATA-IDE caddy. It is a boot disk
- sdb: Kingston SV300S37A60G SSD connected into the only SATA port

Sample "dmesg --notime | grep -E '^(sd |ata)'" output on wake:

sd 0:0:0:0: [sda] Starting disk
sd 2:0:0:0: [sdb] Starting disk
ata4: SATA link down (SStatus 4 SControl 300)
ata3: SATA link down (SStatus 4 SControl 300)
ata1.00: ACPI cmd ef/03:0c:00:00:00:a0 (SET FEATURES) filtered out ata1.00: ACPI cmd ef/03:42:00:00:00:a0 (SET FEATURES) filtered out
ata1: FORCE: cable set to 80c
ata5: SATA link down (SStatus 0 SControl 300)
ata3: SATA link down (SStatus 4 SControl 300)
ata3: SATA link down (SStatus 4 SControl 300)
ata3.00: disabled
sd 2:0:0:0: rejecting I/O to offline device
ata3.00: detaching (SCSI 2:0:0:0)
sd 2:0:0:0: [sdb] Start/Stop Unit failed: Result: hostbyte=DID_NO_CONNECT
driverbyte=DRIVER_OK
sd 2:0:0:0: [sdb] Synchronizing SCSI cache
sd 2:0:0:0: [sdb] Synchronize Cache(10) failed: Result:
hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
sd 2:0:0:0: [sdb] Stopping disk
sd 2:0:0:0: [sdb] Start/Stop Unit failed: Result: hostbyte=DID_BAD_TARGET
driverbyte=DRIVER_OK

Commit c312ef176399 dropped ahci_pci_reset_controller() which internally calls ahci_reset_controller() and applies the PCS quirk if needed after that. It was called each time a reset was required instead of just ahci_reset_controller(). This patch puts the function back in place.

Fixes c312ef176399 ("libata/ahci: Drop PCS quirk for Denverton and beyond")
---
 drivers/ata/ahci.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)
drivers/ata/ahci.c +23 -9
index c1bf7117a9ff..149ee16fd022 100644
@@ -83,6 +83,7 @@ enum board_ids {
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void ahci_remove_one(struct pci_dev *dev);
 static void ahci_shutdown_one(struct pci_dev *dev);
+static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
 				 unsigned long deadline);
 static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -668,6 +669,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
 	ahci_save_initial_config(&pdev->dev, hpriv);
 }
 
+static int ahci_pci_reset_controller(struct ata_host *host)
+{
+	struct pci_dev *pdev = to_pci_dev(host->dev);
+	struct ahci_host_priv *hpriv = host->private_data;
+	int rc;
+
+	rc = ahci_reset_controller(host);
+	if (rc)
+		return rc;
+
+	/*
+	 * If platform firmware failed to enable ports, try to enable
+	 * them here.
+	 */
+	ahci_intel_pcs_quirk(pdev, hpriv);
+
+	return 0;
+}
+
 static void ahci_pci_init_controller(struct ata_host *host)
 {
 	struct ahci_host_priv *hpriv = host->private_data;
@@ -869,7 +889,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
 	struct ata_host *host = pci_get_drvdata(pdev);
 	int rc;
 
-	rc = ahci_reset_controller(host);
+	rc = ahci_pci_reset_controller(host);
 	if (rc)
 		return rc;
 	ahci_pci_init_controller(host);
@@ -904,7 +924,7 @@ static int ahci_pci_device_resume(struct device *dev)
 		ahci_mcp89_apple_enable(pdev);
 
 	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-		rc = ahci_reset_controller(host);
+		rc = ahci_pci_reset_controller(host);
 		if (rc)
 			return rc;
 
@@ -1789,12 +1809,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* save initial config */
 	ahci_pci_save_initial_config(pdev, hpriv);
 
-	/*
-	 * If platform firmware failed to enable ports, try to enable
-	 * them here.
-	 */
-	ahci_intel_pcs_quirk(pdev, hpriv);
-
 	/* prepare host */
 	if (hpriv->cap & HOST_CAP_NCQ) {
 		pi.flags |= ATA_FLAG_NCQ;
@@ -1904,7 +1918,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (rc)
 		return rc;
 
-	rc = ahci_reset_controller(host);
+	rc = ahci_pci_reset_controller(host);
 	if (rc)
 		return rc;
 
Signature · 1 line
2.35.1
author maintainer
#13 lore raw

PATCH 13/290 nvme: fix the NVME_CMD_EFFECTS_CSE_MASK definition

In reply to Greg Kroah-Hartman

From: Christoph Hellwig <[email protected]>

[ Upstream commit 685e6311637e46f3212439ce2789f8a300e5050f ]

3 << 16 does not generate the correct mask for bits 16, 17 and 18. Use the GENMASK macro to generate the correct mask instead.

Fixes 84fef62d135b ("nvme: check admin passthru command effects")
---
 include/linux/nvme.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/nvme.h +2 -1
index 039f59ee8f43..de235916c31c 100644
@@ -7,6 +7,7 @@
 #ifndef _LINUX_NVME_H
 #define _LINUX_NVME_H
 
+#include <linux/bits.h>
 #include <linux/types.h>
 #include <linux/uuid.h>
 
@@ -539,7 +540,7 @@ enum {
 	NVME_CMD_EFFECTS_NCC		= 1 << 2,
 	NVME_CMD_EFFECTS_NIC		= 1 << 3,
 	NVME_CMD_EFFECTS_CCC		= 1 << 4,
-	NVME_CMD_EFFECTS_CSE_MASK	= 3 << 16,
+	NVME_CMD_EFFECTS_CSE_MASK	= GENMASK(18, 16),
 	NVME_CMD_EFFECTS_UUID_SEL	= 1 << 19,
 };
 
Signature · 1 line
2.35.1
author maintainer
#14 lore raw

PATCH 14/290 nvmet: dont defer passthrough commands with trivial effects to the workqueue

In reply to Greg Kroah-Hartman

From: Christoph Hellwig <[email protected]>

[ Upstream commit 2a459f6933e1c459bffb7cc73fd6c900edc714bd ]

Mask out the "Command Supported" and "Logical Block Content Change" bits and only defer execution of commands that have non-trivial effects to the workqueue for synchronous execution. This allows to execute admin commands asynchronously on controllers that provide a Command Supported and Effects log page, and will keep allowing to execute Write commands asynchronously once command effects on I/O commands are taken into account.

Fixes c1fef73f793b ("nvmet: add passthru code to process commands")
---
 drivers/nvme/target/passthru.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/nvme/target/passthru.c +5 -6
index 6220e1dd961a..9b5929754195 100644
@@ -271,14 +271,13 @@ static void nvmet_passthru_execute_cmd(struct nvmet_req *req)
 	}
 
 	/*
-	 * If there are effects for the command we are about to execute, or
-	 * an end_req function we need to use nvme_execute_passthru_rq()
-	 * synchronously in a work item seeing the end_req function and
-	 * nvme_passthru_end() can't be called in the request done callback
-	 * which is typically in interrupt context.
+	 * If a command needs post-execution fixups, or there are any
+	 * non-trivial effects, make sure to execute the command synchronously
+	 * in a workqueue so that nvme_passthru_end gets called.
 	 */
 	effects = nvme_command_effects(ctrl, ns, req->cmd->common.opcode);
-	if (req->p.use_workqueue || effects) {
+	if (req->p.use_workqueue ||
+	    (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))) {
 		INIT_WORK(&req->p.work, nvmet_passthru_execute_cmd_work);
 		req->p.rq = rq;
 		queue_work(nvmet_wq, &req->p.work);
Signature · 1 line
2.35.1
author maintainer
#15 lore raw

PATCH 15/290 fs/ntfs3: Validate BOOT record_size

In reply to Greg Kroah-Hartman

From: edward lo <[email protected]>

[ Upstream commit 0b66046266690454dc04e6307bcff4a5605b42a1 ]

When the NTFS BOOT record_size field < 0, it represents a shift value. However, there is no sanity check on the shift result and the sbi->record_bits calculation through blksize_bits() assumes the size always > 256, which could lead to NPD while mounting a malformed NTFS image.

[  318.675159] BUG: kernel NULL pointer dereference, address: 0000000000000158
[  318.675682] #PF: supervisor read access in kernel mode
[  318.675869] #PF: error_code(0x0000) - not-present page
[  318.676246] PGD 0 P4D 0
[  318.676502] Oops: 0000 [#1] PREEMPT SMP NOPTI
[  318.676934] CPU: 0 PID: 259 Comm: mount Not tainted 5.19.0 #5
[  318.677289] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  318.678136] RIP: 0010:ni_find_attr+0x2d/0x1c0
[  318.678656] Code: 89 ca 4d 89 c7 41 56 41 55 41 54 41 89 cc 55 48 89 fd 53 48 89 d3 48 83 ec 20 65 48 8b 04 25 28 00 00 00 48 89 44 24 180
[  318.679848] RSP: 0018:ffffa6c8c0297bd8 EFLAGS: 00000246
[  318.680104] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000080
[  318.680790] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[  318.681679] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
[  318.682577] R10: 0000000000000000 R11: 0000000000000005 R12: 0000000000000080
[  318.683015] R13: ffff8d5582e68400 R14: 0000000000000100 R15: 0000000000000000
[  318.683618] FS:  00007fd9e1c81e40(0000) GS:ffff8d55fdc00000(0000) knlGS:0000000000000000
[  318.684280] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  318.684651] CR2: 0000000000000158 CR3: 0000000002e1a000 CR4: 00000000000006f0
[  318.685623] Call Trace:
[  318.686607]  <TASK>
[  318.686872]  ? ntfs_alloc_inode+0x1a/0x60
[  318.687235]  attr_load_runs_vcn+0x2b/0xa0
[  318.687468]  mi_read+0xbb/0x250
[  318.687576]  ntfs_iget5+0x114/0xd90
[  318.687750]  ntfs_fill_super+0x588/0x11b0
[  318.687953]  ? put_ntfs+0x130/0x130
[  318.688065]  ? snprintf+0x49/0x70
[  318.688164]  ? put_ntfs+0x130/0x130
[  318.688256]  get_tree_bdev+0x16a/0x260
[  318.688407]  vfs_get_tree+0x20/0xb0
[  318.688519]  path_mount+0x2dc/0x9b0
[  318.688877]  do_mount+0x74/0x90
[  318.689142]  __x64_sys_mount+0x89/0xd0
[  318.689636]  do_syscall_64+0x3b/0x90
[  318.689998]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  318.690318] RIP: 0033:0x7fd9e133c48a
[  318.690687] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[  318.691357] RSP: 002b:00007ffd374406c8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[  318.691632] RAX: ffffffffffffffda RBX: 0000564d0b051080 RCX: 00007fd9e133c48a
[  318.691920] RDX: 0000564d0b051280 RSI: 0000564d0b051300 RDI: 0000564d0b0596a0
[  318.692123] RBP: 0000000000000000 R08: 0000564d0b0512a0 R09: 0000000000000020
[  318.692349] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 0000564d0b0596a0
[  318.692673] R13: 0000564d0b051280 R14: 0000000000000000 R15: 00000000ffffffff
[  318.693007]  </TASK>
[  318.693271] Modules linked in:
[  318.693614] CR2: 0000000000000158
[  318.694446] ---[ end trace 0000000000000000 ]---
[  318.694779] RIP: 0010:ni_find_attr+0x2d/0x1c0
[  318.694952] Code: 89 ca 4d 89 c7 41 56 41 55 41 54 41 89 cc 55 48 89 fd 53 48 89 d3 48 83 ec 20 65 48 8b 04 25 28 00 00 00 48 89 44 24 180
[  318.696042] RSP: 0018:ffffa6c8c0297bd8 EFLAGS: 00000246
[  318.696531] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000080
[  318.698114] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[  318.699286] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
[  318.699795] R10: 0000000000000000 R11: 0000000000000005 R12: 0000000000000080
[  318.700236] R13: ffff8d5582e68400 R14: 0000000000000100 R15: 0000000000000000
[  318.700973] FS:  00007fd9e1c81e40(0000) GS:ffff8d55fdc00000(0000) knlGS:0000000000000000
[  318.701688] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  318.702190] CR2: 0000000000000158 CR3: 0000000002e1a000 CR4: 00000000000006f0
[  318.726510] mount (259) used greatest stack depth: 13320 bytes left

This patch adds a sanity check.

---
 fs/ntfs3/super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ntfs3/super.c +1 -1
index 39b09f32f4db..c321f621464b 100644
@@ -789,7 +789,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size,
 						 : (u32)boot->record_size
 							   << sbi->cluster_bits;
 
-	if (record_size > MAXIMUM_BYTES_PER_MFT)
+	if (record_size > MAXIMUM_BYTES_PER_MFT || record_size < SECTOR_SIZE)
 		goto out;
 
 	sbi->record_bits = blksize_bits(record_size);
Signature · 1 line
2.35.1
author maintainer
#16 lore raw

PATCH 16/290 fs/ntfs3: Add overflow check for attribute size

In reply to Greg Kroah-Hartman

From: edward lo <[email protected]>

[ Upstream commit e19c6277652efba203af4ecd8eed4bd30a0054c9 ]

The offset addition could overflow and pass the used size check given an attribute with very large size (e.g., 0xffffff7f) while parsing MFT attributes. This could lead to out-of-bound memory R/W if we try to access the next attribute derived by Add2Ptr(attr, asize)

[   32.963847] BUG: unable to handle page fault for address: ffff956a83c76067
[   32.964301] #PF: supervisor read access in kernel mode
[   32.964526] #PF: error_code(0x0000) - not-present page
[   32.964893] PGD 4dc01067 P4D 4dc01067 PUD 0
[   32.965316] Oops: 0000 [#1] PREEMPT SMP NOPTI
[   32.965727] CPU: 0 PID: 243 Comm: mount Not tainted 5.19.0+ #6
[   32.966050] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[   32.966628] RIP: 0010:mi_enum_attr+0x44/0x110
[   32.967239] Code: 89 f0 48 29 c8 48 89 c1 39 c7 0f 86 94 00 00 00 8b 56 04 83 fa 17 0f 86 88 00 00 00 89 d0 01 ca 48 01 f0 8d 4a 08 39 f9a
[   32.968101] RSP: 0018:ffffba15c06a7c38 EFLAGS: 00000283
[   32.968364] RAX: ffff956a83c76067 RBX: ffff956983c76050 RCX: 000000000000006f
[   32.968651] RDX: 0000000000000067 RSI: ffff956983c760e8 RDI: 00000000000001c8
[   32.968963] RBP: ffffba15c06a7c38 R08: 0000000000000064 R09: 00000000ffffff7f
[   32.969249] R10: 0000000000000007 R11: ffff956983c760e8 R12: ffff95698225e000
[   32.969870] R13: 0000000000000000 R14: ffffba15c06a7cd8 R15: ffff95698225e170
[   32.970655] FS:  00007fdab8189e40(0000) GS:ffff9569fdc00000(0000) knlGS:0000000000000000
[   32.971098] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   32.971378] CR2: ffff956a83c76067 CR3: 0000000002c58000 CR4: 00000000000006f0
[   32.972098] Call Trace:
[   32.972842]  <TASK>
[   32.973341]  ni_enum_attr_ex+0xda/0xf0
[   32.974087]  ntfs_iget5+0x1db/0xde0
[   32.974386]  ? slab_post_alloc_hook+0x53/0x270
[   32.974778]  ? ntfs_fill_super+0x4c7/0x12a0
[   32.975115]  ntfs_fill_super+0x5d6/0x12a0
[   32.975336]  get_tree_bdev+0x175/0x270
[   32.975709]  ? put_ntfs+0x150/0x150
[   32.975956]  ntfs_fs_get_tree+0x15/0x20
[   32.976191]  vfs_get_tree+0x2a/0xc0
[   32.976374]  ? capable+0x19/0x20
[   32.976572]  path_mount+0x484/0xaa0
[   32.977025]  ? putname+0x57/0x70
[   32.977380]  do_mount+0x80/0xa0
[   32.977555]  __x64_sys_mount+0x8b/0xe0
[   32.978105]  do_syscall_64+0x3b/0x90
[   32.978830]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[   32.979311] RIP: 0033:0x7fdab72e948a
[   32.980015] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[   32.981251] RSP: 002b:00007ffd15b87588 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[   32.981832] RAX: ffffffffffffffda RBX: 0000557de0aaf060 RCX: 00007fdab72e948a
[   32.982234] RDX: 0000557de0aaf260 RSI: 0000557de0aaf2e0 RDI: 0000557de0ab7ce0
[   32.982714] RBP: 0000000000000000 R08: 0000557de0aaf280 R09: 0000000000000020
[   32.983046] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000557de0ab7ce0
[   32.983494] R13: 0000557de0aaf260 R14: 0000000000000000 R15: 00000000ffffffff
[   32.984094]  </TASK>
[   32.984352] Modules linked in:
[   32.984753] CR2: ffff956a83c76067
[   32.985911] ---[ end trace 0000000000000000 ]---
[   32.986555] RIP: 0010:mi_enum_attr+0x44/0x110
[   32.987217] Code: 89 f0 48 29 c8 48 89 c1 39 c7 0f 86 94 00 00 00 8b 56 04 83 fa 17 0f 86 88 00 00 00 89 d0 01 ca 48 01 f0 8d 4a 08 39 f9a
[   32.988232] RSP: 0018:ffffba15c06a7c38 EFLAGS: 00000283
[   32.988532] RAX: ffff956a83c76067 RBX: ffff956983c76050 RCX: 000000000000006f
[   32.988916] RDX: 0000000000000067 RSI: ffff956983c760e8 RDI: 00000000000001c8
[   32.989356] RBP: ffffba15c06a7c38 R08: 0000000000000064 R09: 00000000ffffff7f
[   32.989994] R10: 0000000000000007 R11: ffff956983c760e8 R12: ffff95698225e000
[   32.990415] R13: 0000000000000000 R14: ffffba15c06a7cd8 R15: ffff95698225e170
[   32.991011] FS:  00007fdab8189e40(0000) GS:ffff9569fdc00000(0000) knlGS:0000000000000000
[   32.991524] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   32.991936] CR2: ffff956a83c76067 CR3: 0000000002c58000 CR4: 00000000000006f0

This patch adds an overflow check

---
 fs/ntfs3/record.c | 5 +++++
 1 file changed, 5 insertions(+)
fs/ntfs3/record.c +5 -0
index 861e35791506..30751fd618df 100644
@@ -220,6 +220,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
 			return NULL;
 		}
 
+		if (off + asize < off) {
+			/* overflow check */
+			return NULL;
+		}
+
 		attr = Add2Ptr(attr, asize);
 		off += asize;
 	}
Signature · 1 line
2.35.1
author maintainer
#17 lore raw

PATCH 17/290 fs/ntfs3: Validate data run offset

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit 6db620863f8528ed9a9aa5ad323b26554a17881d ]

This adds sanity checks for data run offset. We should make sure data run offset is legit before trying to unpack them, otherwise we may encounter use-after-free or some unexpected memory access behaviors.

[   82.940342] BUG: KASAN: use-after-free in run_unpack+0x2e3/0x570
[   82.941180] Read of size 1 at addr ffff888008a8487f by task mount/240
[   82.941670]
[   82.942069] CPU: 0 PID: 240 Comm: mount Not tainted 5.19.0+ #15
[   82.942482] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[   82.943720] Call Trace:
[   82.944204]  <TASK>
[   82.944471]  dump_stack_lvl+0x49/0x63
[   82.944908]  print_report.cold+0xf5/0x67b
[   82.945141]  ? __wait_on_bit+0x106/0x120
[   82.945750]  ? run_unpack+0x2e3/0x570
[   82.946626]  kasan_report+0xa7/0x120
[   82.947046]  ? run_unpack+0x2e3/0x570
[   82.947280]  __asan_load1+0x51/0x60
[   82.947483]  run_unpack+0x2e3/0x570
[   82.947709]  ? memcpy+0x4e/0x70
[   82.947927]  ? run_pack+0x7a0/0x7a0
[   82.948158]  run_unpack_ex+0xad/0x3f0
[   82.948399]  ? mi_enum_attr+0x14a/0x200
[   82.948717]  ? run_unpack+0x570/0x570
[   82.949072]  ? ni_enum_attr_ex+0x1b2/0x1c0
[   82.949332]  ? ni_fname_type.part.0+0xd0/0xd0
[   82.949611]  ? mi_read+0x262/0x2c0
[   82.949970]  ? ntfs_cmp_names_cpu+0x125/0x180
[   82.950249]  ntfs_iget5+0x632/0x1870
[   82.950621]  ? ntfs_get_block_bmap+0x70/0x70
[   82.951192]  ? evict+0x223/0x280
[   82.951525]  ? iput.part.0+0x286/0x320
[   82.951969]  ntfs_fill_super+0x1321/0x1e20
[   82.952436]  ? put_ntfs+0x1d0/0x1d0
[   82.952822]  ? vsprintf+0x20/0x20
[   82.953188]  ? mutex_unlock+0x81/0xd0
[   82.953379]  ? set_blocksize+0x95/0x150
[   82.954001]  get_tree_bdev+0x232/0x370
[   82.954438]  ? put_ntfs+0x1d0/0x1d0
[   82.954700]  ntfs_fs_get_tree+0x15/0x20
[   82.955049]  vfs_get_tree+0x4c/0x130
[   82.955292]  path_mount+0x645/0xfd0
[   82.955615]  ? putname+0x80/0xa0
[   82.955955]  ? finish_automount+0x2e0/0x2e0
[   82.956310]  ? kmem_cache_free+0x110/0x390
[   82.956723]  ? putname+0x80/0xa0
[   82.957023]  do_mount+0xd6/0xf0
[   82.957411]  ? path_mount+0xfd0/0xfd0
[   82.957638]  ? __kasan_check_write+0x14/0x20
[   82.957948]  __x64_sys_mount+0xca/0x110
[   82.958310]  do_syscall_64+0x3b/0x90
[   82.958719]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[   82.959341] RIP: 0033:0x7fd0d1ce948a
[   82.960193] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[   82.961532] RSP: 002b:00007ffe59ff69a8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[   82.962527] RAX: ffffffffffffffda RBX: 0000564dcc107060 RCX: 00007fd0d1ce948a
[   82.963266] RDX: 0000564dcc107260 RSI: 0000564dcc1072e0 RDI: 0000564dcc10fce0
[   82.963686] RBP: 0000000000000000 R08: 0000564dcc107280 R09: 0000000000000020
[   82.964272] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 0000564dcc10fce0
[   82.964785] R13: 0000564dcc107260 R14: 0000000000000000 R15: 00000000ffffffff
---
 fs/ntfs3/attrib.c   | 13 +++++++++++++
 fs/ntfs3/attrlist.c |  5 +++++
 fs/ntfs3/frecord.c  | 14 ++++++++++++++
 fs/ntfs3/fslog.c    |  9 +++++++++
 fs/ntfs3/inode.c    |  5 +++++
 5 files changed, 46 insertions(+)
fs/ntfs3/attrib.c +13 -0
index e8c00dda42ad..43e85c493c05 100644
@@ -101,6 +101,10 @@ int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni,
 
 	asize = le32_to_cpu(attr->size);
 	run_off = le16_to_cpu(attr->nres.run_off);
+
+	if (run_off > asize)
+		return -EINVAL;
+
 	err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn,
 			    vcn ? *vcn : svcn, Add2Ptr(attr, run_off),
 			    asize - run_off);
@@ -1157,6 +1161,10 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
 	}
 
 	ro = le16_to_cpu(attr->nres.run_off);
+
+	if (ro > le32_to_cpu(attr->size))
+		return -EINVAL;
+
 	err = run_unpack_ex(run, ni->mi.sbi, ni->mi.rno, svcn, evcn, svcn,
 			    Add2Ptr(attr, ro), le32_to_cpu(attr->size) - ro);
 	if (err < 0)
@@ -1832,6 +1840,11 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes)
 			u16 le_sz;
 			u16 roff = le16_to_cpu(attr->nres.run_off);
 
+			if (roff > le32_to_cpu(attr->size)) {
+				err = -EINVAL;
+				goto out;
+			}
+
 			run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn,
 				      evcn1 - 1, svcn, Add2Ptr(attr, roff),
 				      le32_to_cpu(attr->size) - roff);
fs/ntfs3/attrlist.c +5 -0
index bad6d8a849a2..c0c6bcbc8c05 100644
@@ -68,6 +68,11 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr)
 
 		run_init(&ni->attr_list.run);
 
+		if (run_off > le32_to_cpu(attr->size)) {
+			err = -EINVAL;
+			goto out;
+		}
+
 		err = run_unpack_ex(&ni->attr_list.run, ni->mi.sbi, ni->mi.rno,
 				    0, le64_to_cpu(attr->nres.evcn), 0,
 				    Add2Ptr(attr, run_off),
fs/ntfs3/frecord.c +14 -0
index 18842998c8fa..cdeb0b51f0ba 100644
@@ -567,6 +567,12 @@ static int ni_repack(struct ntfs_inode *ni)
 		}
 
 		roff = le16_to_cpu(attr->nres.run_off);
+
+		if (roff > le32_to_cpu(attr->size)) {
+			err = -EINVAL;
+			break;
+		}
+
 		err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
 				 Add2Ptr(attr, roff),
 				 le32_to_cpu(attr->size) - roff);
@@ -1541,6 +1547,9 @@ int ni_delete_all(struct ntfs_inode *ni)
 		asize = le32_to_cpu(attr->size);
 		roff = le16_to_cpu(attr->nres.run_off);
 
+		if (roff > asize)
+			return -EINVAL;
+
 		/* run==1 means unpack and deallocate. */
 		run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
 			      Add2Ptr(attr, roff), asize - roff);
@@ -2242,6 +2251,11 @@ int ni_decompress_file(struct ntfs_inode *ni)
 		asize = le32_to_cpu(attr->size);
 		roff = le16_to_cpu(attr->nres.run_off);
 
+		if (roff > asize) {
+			err = -EINVAL;
+			goto out;
+		}
+
 		/*run==1  Means unpack and deallocate. */
 		run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
 			      Add2Ptr(attr, roff), asize - roff);
fs/ntfs3/fslog.c +9 -0
index 614513460b8e..bcdddcd7bc79 100644
@@ -2727,6 +2727,9 @@ static inline bool check_attr(const struct MFT_REC *rec,
 			return false;
 		}
 
+		if (run_off > asize)
+			return false;
+
 		if (run_unpack(NULL, sbi, 0, svcn, evcn, svcn,
 			       Add2Ptr(attr, run_off), asize - run_off) < 0) {
 			return false;
@@ -4769,6 +4772,12 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
 		u16 roff = le16_to_cpu(attr->nres.run_off);
 		CLST svcn = le64_to_cpu(attr->nres.svcn);
 
+		if (roff > t32) {
+			kfree(oa->attr);
+			oa->attr = NULL;
+			goto fake_attr;
+		}
+
 		err = run_unpack(&oa->run0, sbi, inode->i_ino, svcn,
 				 le64_to_cpu(attr->nres.evcn), svcn,
 				 Add2Ptr(attr, roff), t32 - roff);
fs/ntfs3/inode.c +5 -0
index 64b4a3c29878..83d4c9f42d9c 100644
@@ -364,6 +364,11 @@ static struct inode *ntfs_read_mft(struct inode *inode,
 attr_unpack_run:
 	roff = le16_to_cpu(attr->nres.run_off);
 
+	if (roff > asize) {
+		err = -EINVAL;
+		goto out;
+	}
+
 	t64 = le64_to_cpu(attr->nres.svcn);
 	err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
 			    t64, Add2Ptr(attr, roff), asize - roff);
Signature · 1 line
2.35.1
author maintainer
#18 lore raw

PATCH 18/290 fs/ntfs3: Add null pointer check to attr_load_runs_vcn

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit 2681631c29739509eec59cc0b34e977bb04c6cf1 ]

Some metadata files are handled before MFT. This adds a null pointer check for some corner cases that could lead to NPD while reading these metadata files for a malformed NTFS image.

[  240.190827] BUG: kernel NULL pointer dereference, address: 0000000000000158
[  240.191583] #PF: supervisor read access in kernel mode
[  240.191956] #PF: error_code(0x0000) - not-present page
[  240.192391] PGD 0 P4D 0
[  240.192897] Oops: 0000 [#1] PREEMPT SMP KASAN NOPTI
[  240.193805] CPU: 0 PID: 242 Comm: mount Tainted: G    B             5.19.0+ #17
[  240.194477] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  240.195152] RIP: 0010:ni_find_attr+0xae/0x300
[  240.195679] Code: c8 48 c7 45 88 c0 4e 5e 86 c7 00 f1 f1 f1 f1 c7 40 04 00 f3 f3 f3 65 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 e8 e2 d9f
[  240.196642] RSP: 0018:ffff88800812f690 EFLAGS: 00000286
[  240.197019] RAX: 0000000000000001 RBX: 0000000000000000 RCX: ffffffff85ef037a
[  240.197523] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffffff88e95f60
[  240.197877] RBP: ffff88800812f738 R08: 0000000000000001 R09: fffffbfff11d2bed
[  240.198292] R10: ffffffff88e95f67 R11: fffffbfff11d2bec R12: 0000000000000000
[  240.198647] R13: 0000000000000080 R14: 0000000000000000 R15: 0000000000000000
[  240.199410] FS:  00007f233c33be40(0000) GS:ffff888058200000(0000) knlGS:0000000000000000
[  240.199895] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  240.200314] CR2: 0000000000000158 CR3: 0000000004d32000 CR4: 00000000000006f0
[  240.200839] Call Trace:
[  240.201104]  <TASK>
[  240.201502]  ? ni_load_mi+0x80/0x80
[  240.202297]  ? ___slab_alloc+0x465/0x830
[  240.202614]  attr_load_runs_vcn+0x8c/0x1a0
[  240.202886]  ? __kasan_slab_alloc+0x32/0x90
[  240.203157]  ? attr_data_write_resident+0x250/0x250
[  240.203543]  mi_read+0x133/0x2c0
[  240.203785]  mi_get+0x70/0x140
[  240.204012]  ni_load_mi_ex+0xfa/0x190
[  240.204346]  ? ni_std5+0x90/0x90
[  240.204588]  ? __kasan_kmalloc+0x88/0xb0
[  240.204859]  ni_enum_attr_ex+0xf1/0x1c0
[  240.205107]  ? ni_fname_type.part.0+0xd0/0xd0
[  240.205600]  ? ntfs_load_attr_list+0xbe/0x300
[  240.205864]  ? ntfs_cmp_names_cpu+0x125/0x180
[  240.206157]  ntfs_iget5+0x56c/0x1870
[  240.206510]  ? ntfs_get_block_bmap+0x70/0x70
[  240.206776]  ? __kasan_kmalloc+0x88/0xb0
[  240.207030]  ? set_blocksize+0x95/0x150
[  240.207545]  ntfs_fill_super+0xb8f/0x1e20
[  240.207839]  ? put_ntfs+0x1d0/0x1d0
[  240.208069]  ? vsprintf+0x20/0x20
[  240.208467]  ? mutex_unlock+0x81/0xd0
[  240.208846]  ? set_blocksize+0x95/0x150
[  240.209221]  get_tree_bdev+0x232/0x370
[  240.209804]  ? put_ntfs+0x1d0/0x1d0
[  240.210519]  ntfs_fs_get_tree+0x15/0x20
[  240.210991]  vfs_get_tree+0x4c/0x130
[  240.211455]  path_mount+0x645/0xfd0
[  240.211806]  ? putname+0x80/0xa0
[  240.212112]  ? finish_automount+0x2e0/0x2e0
[  240.212559]  ? kmem_cache_free+0x110/0x390
[  240.212906]  ? putname+0x80/0xa0
[  240.213329]  do_mount+0xd6/0xf0
[  240.213829]  ? path_mount+0xfd0/0xfd0
[  240.214246]  ? __kasan_check_write+0x14/0x20
[  240.214774]  __x64_sys_mount+0xca/0x110
[  240.215080]  do_syscall_64+0x3b/0x90
[  240.215442]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  240.215811] RIP: 0033:0x7f233b4e948a
[  240.216104] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[  240.217615] RSP: 002b:00007fff02211ec8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[  240.218718] RAX: ffffffffffffffda RBX: 0000561cdc35b060 RCX: 00007f233b4e948a
[  240.219556] RDX: 0000561cdc35b260 RSI: 0000561cdc35b2e0 RDI: 0000561cdc363af0
[  240.219975] RBP: 0000000000000000 R08: 0000561cdc35b280 R09: 0000000000000020
[  240.220403] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 0000561cdc363af0
[  240.220803] R13: 0000561cdc35b260 R14: 0000000000000000 R15: 00000000ffffffff
[  240.221256]  </TASK>
[  240.221567] Modules linked in:
[  240.222028] CR2: 0000000000000158
[  240.223291] ---[ end trace 0000000000000000 ]---
[  240.223669] RIP: 0010:ni_find_attr+0xae/0x300
[  240.224058] Code: c8 48 c7 45 88 c0 4e 5e 86 c7 00 f1 f1 f1 f1 c7 40 04 00 f3 f3 f3 65 48 8b 04 25 28 00 00 00 48 89 45 d0 31 c0 e8 e2 d9f
[  240.225033] RSP: 0018:ffff88800812f690 EFLAGS: 00000286
[  240.225968] RAX: 0000000000000001 RBX: 0000000000000000 RCX: ffffffff85ef037a
[  240.226624] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffffff88e95f60
[  240.227307] RBP: ffff88800812f738 R08: 0000000000000001 R09: fffffbfff11d2bed
[  240.227816] R10: ffffffff88e95f67 R11: fffffbfff11d2bec R12: 0000000000000000
[  240.228330] R13: 0000000000000080 R14: 0000000000000000 R15: 0000000000000000
[  240.228729] FS:  00007f233c33be40(0000) GS:ffff888058200000(0000) knlGS:0000000000000000
[  240.229281] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  240.230298] CR2: 0000000000000158 CR3: 0000000004d32000 CR4: 00000000000006f0
---
 fs/ntfs3/attrib.c | 5 +++++
 1 file changed, 5 insertions(+)
fs/ntfs3/attrib.c +5 -0
index 43e85c493c05..42af83bcaf13 100644
@@ -1146,6 +1146,11 @@ int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type,
 	CLST svcn, evcn;
 	u16 ro;
 
+	if (!ni) {
+		/* Is record corrupted? */
+		return -ENOENT;
+	}
+
 	attr = ni_find_attr(ni, NULL, NULL, type, name, name_len, &vcn, NULL);
 	if (!attr) {
 		/* Is record corrupted? */
Signature · 1 line
2.35.1
author maintainer
#19 lore raw

PATCH 19/290 fs/ntfs3: Fix memory leak on ntfs_fill_super() error path

In reply to Greg Kroah-Hartman

From: Shigeru Yoshida <[email protected]>

[ Upstream commit 51e76a232f8c037f1d9e9922edc25b003d5f3414 ]

syzbot reported kmemleak as below:

BUG: memory leak
unreferenced object 0xffff8880122f1540 (size 32):
  comm "a.out", pid 6664, jiffies 4294939771 (age 25.500s)
  hex dump (first 32 bytes):
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    00 00 00 00 00 00 00 00 ed ff ed ff 00 00 00 00  ................
  backtrace:
    [<ffffffff81b16052>] ntfs_init_fs_context+0x22/0x1c0
    [<ffffffff8164aaa7>] alloc_fs_context+0x217/0x430
    [<ffffffff81626dd4>] path_mount+0x704/0x1080
    [<ffffffff81627e7c>] __x64_sys_mount+0x18c/0x1d0
    [<ffffffff84593e14>] do_syscall_64+0x34/0xb0
    [<ffffffff84600087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd

This patch fixes this issue by freeing mount options on error path of ntfs_fill_super().

---
 fs/ntfs3/super.c | 1 +
 1 file changed, 1 insertion(+)
fs/ntfs3/super.c +1 -0
index c321f621464b..4ff0d2c9507c 100644
@@ -1276,6 +1276,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
 	 * Free resources here.
 	 * ntfs_fs_free will be called with fc->s_fs_info = NULL
 	 */
+	put_mount_options(sbi->options);
 	put_ntfs(sbi);
 	sb->s_fs_info = NULL;
 
Signature · 1 line
2.35.1
author maintainer
#20 lore raw

PATCH 20/290 fs/ntfs3: Add null pointer check for inode operations

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit c1ca8ef0262b25493631ecbd9cb8c9893e1481a1 ]

This adds a sanity check for the i_op pointer of the inode which is returned after reading Root directory MFT record. We should check the i_op is valid before trying to create the root dentry, otherwise we may encounter a NPD while mounting a image with a funny Root directory MFT record.

[  114.484325] BUG: kernel NULL pointer dereference, address: 0000000000000008
[  114.484811] #PF: supervisor read access in kernel mode
[  114.485084] #PF: error_code(0x0000) - not-present page
[  114.485606] PGD 0 P4D 0
[  114.485975] Oops: 0000 [#1] PREEMPT SMP KASAN NOPTI
[  114.486570] CPU: 0 PID: 237 Comm: mount Tainted: G    B              6.0.0-rc4 #28
[  114.486977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  114.488169] RIP: 0010:d_flags_for_inode+0xe0/0x110
[  114.488816] Code: 24 f7 ff 49 83 3e 00 74 41 41 83 cd 02 66 44 89 6b 02 eb 92 48 8d 7b 20 e8 6d 24 f7 ff 4c 8b 73 20 49 8d 7e 08 e8 60 241
[  114.490326] RSP: 0018:ffff8880065e7aa8 EFLAGS: 00000296
[  114.490695] RAX: 0000000000000001 RBX: ffff888008ccd750 RCX: ffffffff84af2aea
[  114.490986] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffffff87abd020
[  114.491364] RBP: ffff8880065e7ac8 R08: 0000000000000001 R09: fffffbfff0f57a05
[  114.491675] R10: ffffffff87abd027 R11: fffffbfff0f57a04 R12: 0000000000000000
[  114.491954] R13: 0000000000000008 R14: 0000000000000000 R15: ffff888008ccd750
[  114.492397] FS:  00007fdc8a627e40(0000) GS:ffff888058200000(0000) knlGS:0000000000000000
[  114.492797] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  114.493150] CR2: 0000000000000008 CR3: 00000000013ba000 CR4: 00000000000006f0
[  114.493671] Call Trace:
[  114.493890]  <TASK>
[  114.494075]  __d_instantiate+0x24/0x1c0
[  114.494505]  d_instantiate.part.0+0x35/0x50
[  114.494754]  d_make_root+0x53/0x80
[  114.494998]  ntfs_fill_super+0x1232/0x1b50
[  114.495260]  ? put_ntfs+0x1d0/0x1d0
[  114.495499]  ? vsprintf+0x20/0x20
[  114.495723]  ? set_blocksize+0x95/0x150
[  114.495964]  get_tree_bdev+0x232/0x370
[  114.496272]  ? put_ntfs+0x1d0/0x1d0
[  114.496502]  ntfs_fs_get_tree+0x15/0x20
[  114.496859]  vfs_get_tree+0x4c/0x130
[  114.497099]  path_mount+0x654/0xfe0
[  114.497507]  ? putname+0x80/0xa0
[  114.497933]  ? finish_automount+0x2e0/0x2e0
[  114.498362]  ? putname+0x80/0xa0
[  114.498571]  ? kmem_cache_free+0x1c4/0x440
[  114.498819]  ? putname+0x80/0xa0
[  114.499069]  do_mount+0xd6/0xf0
[  114.499343]  ? path_mount+0xfe0/0xfe0
[  114.499683]  ? __kasan_check_write+0x14/0x20
[  114.500133]  __x64_sys_mount+0xca/0x110
[  114.500592]  do_syscall_64+0x3b/0x90
[  114.500930]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  114.501294] RIP: 0033:0x7fdc898e948a
[  114.501542] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[  114.502716] RSP: 002b:00007ffd793e58f8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[  114.503175] RAX: ffffffffffffffda RBX: 0000564b2228f060 RCX: 00007fdc898e948a
[  114.503588] RDX: 0000564b2228f260 RSI: 0000564b2228f2e0 RDI: 0000564b22297ce0
[  114.504925] RBP: 0000000000000000 R08: 0000564b2228f280 R09: 0000000000000020
[  114.505484] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 0000564b22297ce0
[  114.505823] R13: 0000564b2228f260 R14: 0000000000000000 R15: 00000000ffffffff
[  114.506562]  </TASK>
[  114.506887] Modules linked in:
[  114.507648] CR2: 0000000000000008
[  114.508884] ---[ end trace 0000000000000000 ]---
[  114.509675] RIP: 0010:d_flags_for_inode+0xe0/0x110
[  114.510140] Code: 24 f7 ff 49 83 3e 00 74 41 41 83 cd 02 66 44 89 6b 02 eb 92 48 8d 7b 20 e8 6d 24 f7 ff 4c 8b 73 20 49 8d 7e 08 e8 60 241
[  114.511762] RSP: 0018:ffff8880065e7aa8 EFLAGS: 00000296
[  114.512401] RAX: 0000000000000001 RBX: ffff888008ccd750 RCX: ffffffff84af2aea
[  114.513103] RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffffff87abd020
[  114.513512] RBP: ffff8880065e7ac8 R08: 0000000000000001 R09: fffffbfff0f57a05
[  114.513831] R10: ffffffff87abd027 R11: fffffbfff0f57a04 R12: 0000000000000000
[  114.514757] R13: 0000000000000008 R14: 0000000000000000 R15: ffff888008ccd750
[  114.515411] FS:  00007fdc8a627e40(0000) GS:ffff888058200000(0000) knlGS:0000000000000000
[  114.515794] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  114.516208] CR2: 0000000000000008 CR3: 00000000013ba000 CR4: 00000000000006f0
---
 fs/ntfs3/super.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/ntfs3/super.c +2 -2
index 4ff0d2c9507c..a18fb431abbe 100644
@@ -1255,9 +1255,9 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
 	ref.low = cpu_to_le32(MFT_REC_ROOT);
 	ref.seq = cpu_to_le16(MFT_REC_ROOT);
 	inode = ntfs_iget5(sb, &ref, &NAME_ROOT);
-	if (IS_ERR(inode)) {
+	if (IS_ERR(inode) || !inode->i_op) {
 		ntfs_err(sb, "Failed to load root.");
-		err = PTR_ERR(inode);
+		err = IS_ERR(inode) ? PTR_ERR(inode) : -EINVAL;
 		goto out;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#21 lore raw

PATCH 21/290 fs/ntfs3: Validate attribute name offset

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit 4f1dc7d9756e66f3f876839ea174df2e656b7f79 ]

Although the attribute name length is checked before comparing it to some common names (e.g., $I30), the offset isn't. This adds a sanity check for the attribute name offset, guarantee the validity and prevent possible out-of-bound memory accesses.

[  191.720056] BUG: unable to handle page fault for address: ffffebde00000008
[  191.721060] #PF: supervisor read access in kernel mode
[  191.721586] #PF: error_code(0x0000) - not-present page
[  191.722079] PGD 0 P4D 0
[  191.722571] Oops: 0000 [#1] PREEMPT SMP KASAN NOPTI
[  191.723179] CPU: 0 PID: 244 Comm: mount Not tainted 6.0.0-rc4 #28
[  191.723749] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  191.724832] RIP: 0010:kfree+0x56/0x3b0
[  191.725870] Code: 80 48 01 d8 0f 82 65 03 00 00 48 c7 c2 00 00 00 80 48 2b 15 2c 06 dd 01 48 01 d0 48 c1 e8 0c 48 c1 e0 06 48 03 05 0a 069
[  191.727375] RSP: 0018:ffff8880076f7878 EFLAGS: 00000286
[  191.727897] RAX: ffffebde00000000 RBX: 0000000000000040 RCX: ffffffff8528d5b9
[  191.728531] RDX: 0000777f80000000 RSI: ffffffff8522d49c RDI: 0000000000000040
[  191.729183] RBP: ffff8880076f78a0 R08: 0000000000000000 R09: 0000000000000000
[  191.729628] R10: ffff888008949fd8 R11: ffffed10011293fd R12: 0000000000000040
[  191.730158] R13: ffff888008949f98 R14: ffff888008949ec0 R15: ffff888008949fb0
[  191.730645] FS:  00007f3520cd7e40(0000) GS:ffff88805ba00000(0000) knlGS:0000000000000000
[  191.731328] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  191.731667] CR2: ffffebde00000008 CR3: 0000000009704000 CR4: 00000000000006f0
[  191.732568] Call Trace:
[  191.733231]  <TASK>
[  191.733860]  kvfree+0x2c/0x40
[  191.734632]  ni_clear+0x180/0x290
[  191.735085]  ntfs_evict_inode+0x45/0x70
[  191.735495]  evict+0x199/0x280
[  191.735996]  iput.part.0+0x286/0x320
[  191.736438]  iput+0x32/0x50
[  191.736811]  iget_failed+0x23/0x30
[  191.737270]  ntfs_iget5+0x337/0x1890
[  191.737629]  ? ntfs_clear_mft_tail+0x20/0x260
[  191.738201]  ? ntfs_get_block_bmap+0x70/0x70
[  191.738482]  ? ntfs_objid_init+0xf6/0x140
[  191.738779]  ? ntfs_reparse_init+0x140/0x140
[  191.739266]  ntfs_fill_super+0x121b/0x1b50
[  191.739623]  ? put_ntfs+0x1d0/0x1d0
[  191.739984]  ? asm_sysvec_apic_timer_interrupt+0x1b/0x20
[  191.740466]  ? put_ntfs+0x1d0/0x1d0
[  191.740787]  ? sb_set_blocksize+0x6a/0x80
[  191.741272]  get_tree_bdev+0x232/0x370
[  191.741829]  ? put_ntfs+0x1d0/0x1d0
[  191.742669]  ntfs_fs_get_tree+0x15/0x20
[  191.743132]  vfs_get_tree+0x4c/0x130
[  191.743457]  path_mount+0x654/0xfe0
[  191.743938]  ? putname+0x80/0xa0
[  191.744271]  ? finish_automount+0x2e0/0x2e0
[  191.744582]  ? putname+0x80/0xa0
[  191.745053]  ? kmem_cache_free+0x1c4/0x440
[  191.745403]  ? putname+0x80/0xa0
[  191.745616]  do_mount+0xd6/0xf0
[  191.745887]  ? path_mount+0xfe0/0xfe0
[  191.746287]  ? __kasan_check_write+0x14/0x20
[  191.746582]  __x64_sys_mount+0xca/0x110
[  191.746850]  do_syscall_64+0x3b/0x90
[  191.747122]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  191.747517] RIP: 0033:0x7f351fee948a
[  191.748332] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[  191.749341] RSP: 002b:00007ffd51cf3af8 EFLAGS: 00000202 ORIG_RAX: 00000000000000a5
[  191.749960] RAX: ffffffffffffffda RBX: 000055b903733060 RCX: 00007f351fee948a
[  191.750589] RDX: 000055b903733260 RSI: 000055b9037332e0 RDI: 000055b90373bce0
[  191.751115] RBP: 0000000000000000 R08: 000055b903733280 R09: 0000000000000020
[  191.751537] R10: 00000000c0ed0000 R11: 0000000000000202 R12: 000055b90373bce0
[  191.751946] R13: 000055b903733260 R14: 0000000000000000 R15: 00000000ffffffff
[  191.752519]  </TASK>
[  191.752782] Modules linked in:
[  191.753785] CR2: ffffebde00000008
[  191.754937] ---[ end trace 0000000000000000 ]---
[  191.755429] RIP: 0010:kfree+0x56/0x3b0
[  191.755725] Code: 80 48 01 d8 0f 82 65 03 00 00 48 c7 c2 00 00 00 80 48 2b 15 2c 06 dd 01 48 01 d0 48 c1 e8 0c 48 c1 e0 06 48 03 05 0a 069
[  191.756744] RSP: 0018:ffff8880076f7878 EFLAGS: 00000286
[  191.757218] RAX: ffffebde00000000 RBX: 0000000000000040 RCX: ffffffff8528d5b9
[  191.757580] RDX: 0000777f80000000 RSI: ffffffff8522d49c RDI: 0000000000000040
[  191.758016] RBP: ffff8880076f78a0 R08: 0000000000000000 R09: 0000000000000000
[  191.758570] R10: ffff888008949fd8 R11: ffffed10011293fd R12: 0000000000000040
[  191.758957] R13: ffff888008949f98 R14: ffff888008949ec0 R15: ffff888008949fb0
[  191.759317] FS:  00007f3520cd7e40(0000) GS:ffff88805ba00000(0000) knlGS:0000000000000000
[  191.759711] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  191.760118] CR2: ffffebde00000008 CR3: 0000000009704000 CR4: 00000000000006f0
---
 fs/ntfs3/inode.c | 3 +++
 1 file changed, 3 insertions(+)
fs/ntfs3/inode.c +3 -0
index 83d4c9f42d9c..66afa3db753a 100644
@@ -129,6 +129,9 @@ static struct inode *ntfs_read_mft(struct inode *inode,
 	rsize = attr->non_res ? 0 : le32_to_cpu(attr->res.data_size);
 	asize = le32_to_cpu(attr->size);
 
+	if (le16_to_cpu(attr->name_off) + attr->name_len > asize)
+		goto out;
+
 	switch (attr->type) {
 	case ATTR_STD:
 		if (attr->non_res ||
Signature · 1 line
2.35.1
author maintainer
#22 lore raw

PATCH 22/290 fs/ntfs3: Validate buffer length while parsing index

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit 4d42ecda239cc13738d6fd84d098a32e67b368b9 ]

indx_read is called when we have some NTFS directory operations that need more information from the index buffers. This adds a sanity check to make sure the returned index buffer length is legit, or we may have some out-of-bound memory accesses.

[  560.897595] BUG: KASAN: slab-out-of-bounds in hdr_find_e.isra.0+0x10c/0x320
[  560.898321] Read of size 2 at addr ffff888009497238 by task exp/245
[  560.898760]
[  560.899129] CPU: 0 PID: 245 Comm: exp Not tainted 6.0.0-rc6 #37
[  560.899505] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  560.900170] Call Trace:
[  560.900407]  <TASK>
[  560.900732]  dump_stack_lvl+0x49/0x63
[  560.901108]  print_report.cold+0xf5/0x689
[  560.901395]  ? hdr_find_e.isra.0+0x10c/0x320
[  560.901716]  kasan_report+0xa7/0x130
[  560.901950]  ? hdr_find_e.isra.0+0x10c/0x320
[  560.902208]  __asan_load2+0x68/0x90
[  560.902427]  hdr_find_e.isra.0+0x10c/0x320
[  560.902846]  ? cmp_uints+0xe0/0xe0
[  560.903363]  ? cmp_sdh+0x90/0x90
[  560.903883]  ? ntfs_bread_run+0x190/0x190
[  560.904196]  ? rwsem_down_read_slowpath+0x750/0x750
[  560.904969]  ? ntfs_fix_post_read+0xe0/0x130
[  560.905259]  ? __kasan_check_write+0x14/0x20
[  560.905599]  ? up_read+0x1a/0x90
[  560.905853]  ? indx_read+0x22c/0x380
[  560.906096]  indx_find+0x2ef/0x470
[  560.906352]  ? indx_find_buffer+0x2d0/0x2d0
[  560.906692]  ? __kasan_kmalloc+0x88/0xb0
[  560.906977]  dir_search_u+0x196/0x2f0
[  560.907220]  ? ntfs_nls_to_utf16+0x450/0x450
[  560.907464]  ? __kasan_check_write+0x14/0x20
[  560.907747]  ? mutex_lock+0x8f/0xe0
[  560.907970]  ? __mutex_lock_slowpath+0x20/0x20
[  560.908214]  ? kmem_cache_alloc+0x143/0x4b0
[  560.908459]  ntfs_lookup+0xe0/0x100
[  560.908788]  __lookup_slow+0x116/0x220
[  560.909050]  ? lookup_fast+0x1b0/0x1b0
[  560.909309]  ? lookup_fast+0x13f/0x1b0
[  560.909601]  walk_component+0x187/0x230
[  560.909944]  link_path_walk.part.0+0x3f0/0x660
[  560.910285]  ? handle_lookup_down+0x90/0x90
[  560.910618]  ? path_init+0x642/0x6e0
[  560.911084]  ? percpu_counter_add_batch+0x6e/0xf0
[  560.912559]  ? __alloc_file+0x114/0x170
[  560.913008]  path_openat+0x19c/0x1d10
[  560.913419]  ? getname_flags+0x73/0x2b0
[  560.913815]  ? kasan_save_stack+0x3a/0x50
[  560.914125]  ? kasan_save_stack+0x26/0x50
[  560.914542]  ? __kasan_slab_alloc+0x6d/0x90
[  560.914924]  ? kmem_cache_alloc+0x143/0x4b0
[  560.915339]  ? getname_flags+0x73/0x2b0
[  560.915647]  ? getname+0x12/0x20
[  560.916114]  ? __x64_sys_open+0x4c/0x60
[  560.916460]  ? path_lookupat.isra.0+0x230/0x230
[  560.916867]  ? __isolate_free_page+0x2e0/0x2e0
[  560.917194]  do_filp_open+0x15c/0x1f0
[  560.917448]  ? may_open_dev+0x60/0x60
[  560.917696]  ? expand_files+0xa4/0x3a0
[  560.917923]  ? __kasan_check_write+0x14/0x20
[  560.918185]  ? _raw_spin_lock+0x88/0xdb
[  560.918409]  ? _raw_spin_lock_irqsave+0x100/0x100
[  560.918783]  ? _find_next_bit+0x4a/0x130
[  560.919026]  ? _raw_spin_unlock+0x19/0x40
[  560.919276]  ? alloc_fd+0x14b/0x2d0
[  560.919635]  do_sys_openat2+0x32a/0x4b0
[  560.920035]  ? file_open_root+0x230/0x230
[  560.920336]  ? __rcu_read_unlock+0x5b/0x280
[  560.920813]  do_sys_open+0x99/0xf0
[  560.921208]  ? filp_open+0x60/0x60
[  560.921482]  ? exit_to_user_mode_prepare+0x49/0x180
[  560.921867]  __x64_sys_open+0x4c/0x60
[  560.922128]  do_syscall_64+0x3b/0x90
[  560.922369]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  560.923030] RIP: 0033:0x7f7dff2e4469
[  560.923681] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 088
[  560.924451] RSP: 002b:00007ffd41a210b8 EFLAGS: 00000206 ORIG_RAX: 0000000000000002
[  560.925168] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7dff2e4469
[  560.925655] RDX: 0000000000000000 RSI: 0000000000000002 RDI: 00007ffd41a211f0
[  560.926085] RBP: 00007ffd41a252a0 R08: 00007f7dff60fba0 R09: 00007ffd41a25388
[  560.926405] R10: 0000000000400b80 R11: 0000000000000206 R12: 00000000004004e0
[  560.926867] R13: 00007ffd41a25380 R14: 0000000000000000 R15: 0000000000000000
[  560.927241]  </TASK>
[  560.927491]
[  560.927755] Allocated by task 245:
[  560.928409]  kasan_save_stack+0x26/0x50
[  560.929271]  __kasan_kmalloc+0x88/0xb0
[  560.929778]  __kmalloc+0x192/0x320
[  560.930023]  indx_read+0x249/0x380
[  560.930224]  indx_find+0x2a2/0x470
[  560.930695]  dir_search_u+0x196/0x2f0
[  560.930892]  ntfs_lookup+0xe0/0x100
[  560.931115]  __lookup_slow+0x116/0x220
[  560.931323]  walk_component+0x187/0x230
[  560.931570]  link_path_walk.part.0+0x3f0/0x660
[  560.931791]  path_openat+0x19c/0x1d10
[  560.932008]  do_filp_open+0x15c/0x1f0
[  560.932226]  do_sys_openat2+0x32a/0x4b0
[  560.932413]  do_sys_open+0x99/0xf0
[  560.932709]  __x64_sys_open+0x4c/0x60
[  560.933417]  do_syscall_64+0x3b/0x90
[  560.933776]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  560.934235]
[  560.934486] The buggy address belongs to the object at ffff888009497000
[  560.934486]  which belongs to the cache kmalloc-512 of size 512
[  560.935239] The buggy address is located 56 bytes to the right of
[  560.935239]  512-byte region [ffff888009497000, ffff888009497200)
[  560.936153]
[  560.937326] The buggy address belongs to the physical page:
[  560.938228] page:0000000062a3dfae refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x9496
[  560.939616] head:0000000062a3dfae order:1 compound_mapcount:0 compound_pincount:0
[  560.940219] flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
[  560.942702] raw: 000fffffc0010200 ffffea0000164f80 dead000000000005 ffff888001041c80
[  560.943932] raw: 0000000000000000 0000000080080008 00000001ffffffff 0000000000000000
[  560.944568] page dumped because: kasan: bad access detected
[  560.945735]
[  560.946112] Memory state around the buggy address:
[  560.946870]  ffff888009497100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  560.947242]  ffff888009497180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  560.947611] >ffff888009497200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  560.947915]                                         ^
[  560.948249]  ffff888009497280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  560.948687]  ffff888009497300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
---
 fs/ntfs3/index.c | 6 ++++++
 1 file changed, 6 insertions(+)
fs/ntfs3/index.c +6 -0
index 76ebea253fa2..99f8a57e9f7a 100644
@@ -1017,6 +1017,12 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn,
 		err = 0;
 	}
 
+	/* check for index header length */
+	if (offsetof(struct INDEX_BUFFER, ihdr) + ib->ihdr.used > bytes) {
+		err = -EINVAL;
+		goto out;
+	}
+
 	in->index = ib;
 	*node = in;
 
Signature · 1 line
2.35.1
author maintainer
#23 lore raw

PATCH 23/290 fs/ntfs3: Validate resident attribute name

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit 54e45702b648b7c0000e90b3e9b890e367e16ea8 ]

Though we already have some sanity checks while enumerating attributes, resident attribute names aren't included. This patch checks the resident attribute names are in the valid ranges.

[  259.209031] BUG: KASAN: slab-out-of-bounds in ni_create_attr_list+0x1e1/0x850
[  259.210770] Write of size 426 at addr ffff88800632f2b2 by task exp/255
[  259.211551]
[  259.212035] CPU: 0 PID: 255 Comm: exp Not tainted 6.0.0-rc6 #37
[  259.212955] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  259.214387] Call Trace:
[  259.214640]  <TASK>
[  259.214895]  dump_stack_lvl+0x49/0x63
[  259.215284]  print_report.cold+0xf5/0x689
[  259.215565]  ? kasan_poison+0x3c/0x50
[  259.215778]  ? kasan_unpoison+0x28/0x60
[  259.215991]  ? ni_create_attr_list+0x1e1/0x850
[  259.216270]  kasan_report+0xa7/0x130
[  259.216481]  ? ni_create_attr_list+0x1e1/0x850
[  259.216719]  kasan_check_range+0x15a/0x1d0
[  259.216939]  memcpy+0x3c/0x70
[  259.217136]  ni_create_attr_list+0x1e1/0x850
[  259.217945]  ? __rcu_read_unlock+0x5b/0x280
[  259.218384]  ? ni_remove_attr+0x2e0/0x2e0
[  259.218712]  ? kernel_text_address+0xcf/0xe0
[  259.219064]  ? __kernel_text_address+0x12/0x40
[  259.219434]  ? arch_stack_walk+0x9e/0xf0
[  259.219668]  ? __this_cpu_preempt_check+0x13/0x20
[  259.219904]  ? sysvec_apic_timer_interrupt+0x57/0xc0
[  259.220140]  ? asm_sysvec_apic_timer_interrupt+0x1b/0x20
[  259.220561]  ni_ins_attr_ext+0x52c/0x5c0
[  259.220984]  ? ni_create_attr_list+0x850/0x850
[  259.221532]  ? run_deallocate+0x120/0x120
[  259.221972]  ? vfs_setxattr+0x128/0x300
[  259.222688]  ? setxattr+0x126/0x140
[  259.222921]  ? path_setxattr+0x164/0x180
[  259.223431]  ? __x64_sys_setxattr+0x6d/0x80
[  259.223828]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  259.224417]  ? mi_find_attr+0x3c/0xf0
[  259.224772]  ni_insert_attr+0x1ba/0x420
[  259.225216]  ? ni_ins_attr_ext+0x5c0/0x5c0
[  259.225504]  ? ntfs_read_ea+0x119/0x450
[  259.225775]  ni_insert_resident+0xc0/0x1c0
[  259.226316]  ? ni_insert_nonresident+0x400/0x400
[  259.227001]  ? __kasan_kmalloc+0x88/0xb0
[  259.227468]  ? __kmalloc+0x192/0x320
[  259.227773]  ntfs_set_ea+0x6bf/0xb30
[  259.228216]  ? ftrace_graph_ret_addr+0x2a/0xb0
[  259.228494]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  259.228838]  ? ntfs_read_ea+0x450/0x450
[  259.229098]  ? is_bpf_text_address+0x24/0x40
[  259.229418]  ? kernel_text_address+0xcf/0xe0
[  259.229681]  ? __kernel_text_address+0x12/0x40
[  259.229948]  ? unwind_get_return_address+0x3a/0x60
[  259.230271]  ? write_profile+0x270/0x270
[  259.230537]  ? arch_stack_walk+0x9e/0xf0
[  259.230836]  ntfs_setxattr+0x114/0x5c0
[  259.231099]  ? ntfs_set_acl_ex+0x2e0/0x2e0
[  259.231529]  ? evm_protected_xattr_common+0x6d/0x100
[  259.231817]  ? posix_xattr_acl+0x13/0x80
[  259.232073]  ? evm_protect_xattr+0x1f7/0x440
[  259.232351]  __vfs_setxattr+0xda/0x120
[  259.232635]  ? xattr_resolve_name+0x180/0x180
[  259.232912]  __vfs_setxattr_noperm+0x93/0x300
[  259.233219]  __vfs_setxattr_locked+0x141/0x160
[  259.233492]  ? kasan_poison+0x3c/0x50
[  259.233744]  vfs_setxattr+0x128/0x300
[  259.234002]  ? __vfs_setxattr_locked+0x160/0x160
[  259.234837]  do_setxattr+0xb8/0x170
[  259.235567]  ? vmemdup_user+0x53/0x90
[  259.236212]  setxattr+0x126/0x140
[  259.236491]  ? do_setxattr+0x170/0x170
[  259.236791]  ? debug_smp_processor_id+0x17/0x20
[  259.237232]  ? kasan_quarantine_put+0x57/0x180
[  259.237605]  ? putname+0x80/0xa0
[  259.237870]  ? __kasan_slab_free+0x11c/0x1b0
[  259.238234]  ? putname+0x80/0xa0
[  259.238500]  ? preempt_count_sub+0x18/0xc0
[  259.238775]  ? __mnt_want_write+0xaa/0x100
[  259.238990]  ? mnt_want_write+0x8b/0x150
[  259.239290]  path_setxattr+0x164/0x180
[  259.239605]  ? setxattr+0x140/0x140
[  259.239849]  ? debug_smp_processor_id+0x17/0x20
[  259.240174]  ? fpregs_assert_state_consistent+0x67/0x80
[  259.240411]  __x64_sys_setxattr+0x6d/0x80
[  259.240715]  do_syscall_64+0x3b/0x90
[  259.240934]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  259.241697] RIP: 0033:0x7fc6b26e4469
[  259.242647] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 088
[  259.244512] RSP: 002b:00007ffc3c7841f8 EFLAGS: 00000217 ORIG_RAX: 00000000000000bc
[  259.245086] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fc6b26e4469
[  259.246025] RDX: 00007ffc3c784380 RSI: 00007ffc3c7842e0 RDI: 00007ffc3c784238
[  259.246961] RBP: 00007ffc3c788410 R08: 0000000000000001 R09: 00007ffc3c7884f8
[  259.247775] R10: 000000000000007f R11: 0000000000000217 R12: 00000000004004e0
[  259.248534] R13: 00007ffc3c7884f0 R14: 0000000000000000 R15: 0000000000000000
[  259.249368]  </TASK>
[  259.249644]
[  259.249888] Allocated by task 255:
[  259.250283]  kasan_save_stack+0x26/0x50
[  259.250957]  __kasan_kmalloc+0x88/0xb0
[  259.251826]  __kmalloc+0x192/0x320
[  259.252745]  ni_create_attr_list+0x11e/0x850
[  259.253298]  ni_ins_attr_ext+0x52c/0x5c0
[  259.253685]  ni_insert_attr+0x1ba/0x420
[  259.253974]  ni_insert_resident+0xc0/0x1c0
[  259.254311]  ntfs_set_ea+0x6bf/0xb30
[  259.254629]  ntfs_setxattr+0x114/0x5c0
[  259.254859]  __vfs_setxattr+0xda/0x120
[  259.255155]  __vfs_setxattr_noperm+0x93/0x300
[  259.255445]  __vfs_setxattr_locked+0x141/0x160
[  259.255862]  vfs_setxattr+0x128/0x300
[  259.256251]  do_setxattr+0xb8/0x170
[  259.256522]  setxattr+0x126/0x140
[  259.256911]  path_setxattr+0x164/0x180
[  259.257308]  __x64_sys_setxattr+0x6d/0x80
[  259.257637]  do_syscall_64+0x3b/0x90
[  259.257970]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  259.258550]
[  259.258772] The buggy address belongs to the object at ffff88800632f000
[  259.258772]  which belongs to the cache kmalloc-1k of size 1024
[  259.260190] The buggy address is located 690 bytes inside of
[  259.260190]  1024-byte region [ffff88800632f000, ffff88800632f400)
[  259.261412]
[  259.261743] The buggy address belongs to the physical page:
[  259.262354] page:0000000081e8cac9 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x632c
[  259.263722] head:0000000081e8cac9 order:2 compound_mapcount:0 compound_pincount:0
[  259.264284] flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
[  259.265312] raw: 000fffffc0010200 ffffea0000060d00 dead000000000004 ffff888001041dc0
[  259.265772] raw: 0000000000000000 0000000080080008 00000001ffffffff 0000000000000000
[  259.266305] page dumped because: kasan: bad access detected
[  259.266588]
[  259.266728] Memory state around the buggy address:
[  259.267225]  ffff88800632f300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  259.267841]  ffff88800632f380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  259.269111] >ffff88800632f400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  259.269626]                    ^
[  259.270162]  ffff88800632f480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  259.270810]  ffff88800632f500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
---
 fs/ntfs3/record.c | 5 +++++
 1 file changed, 5 insertions(+)
fs/ntfs3/record.c +5 -0
index 30751fd618df..fd342da398be 100644
@@ -265,6 +265,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
 		if (t16 + t32 > asize)
 			return NULL;
 
+		if (attr->name_len &&
+		    le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len > t16) {
+			return NULL;
+		}
+
 		return attr;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#24 lore raw

PATCH 24/290 fs/ntfs3: Fix slab-out-of-bounds read in run_unpack

In reply to Greg Kroah-Hartman

From: Hawkins Jiawei <[email protected]>

[ Upstream commit 887bfc546097fbe8071dac13b2fef73b77920899 ]

Syzkaller reports slab-out-of-bounds bug as follows:
==================================================================

BUG: KASAN: slab-out-of-bounds in run_unpack+0x8b7/0x970 fs/ntfs3/run.c:944
Read of size 1 at addr ffff88801bbdff02 by task syz-executor131/3611

[...]

Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
 print_address_description mm/kasan/report.c:317 [inline]
 print_report.cold+0x2ba/0x719 mm/kasan/report.c:433
 kasan_report+0xb1/0x1e0 mm/kasan/report.c:495
 run_unpack+0x8b7/0x970 fs/ntfs3/run.c:944
 run_unpack_ex+0xb0/0x7c0 fs/ntfs3/run.c:1057
 ntfs_read_mft fs/ntfs3/inode.c:368 [inline]
 ntfs_iget5+0xc20/0x3280 fs/ntfs3/inode.c:501
 ntfs_loadlog_and_replay+0x124/0x5d0 fs/ntfs3/fsntfs.c:272
 ntfs_fill_super+0x1eff/0x37f0 fs/ntfs3/super.c:1018
 get_tree_bdev+0x440/0x760 fs/super.c:1323
 vfs_get_tree+0x89/0x2f0 fs/super.c:1530
 do_new_mount fs/namespace.c:3040 [inline]
 path_mount+0x1326/0x1e20 fs/namespace.c:3370
 do_mount fs/namespace.c:3383 [inline]
 __do_sys_mount fs/namespace.c:3591 [inline]
 __se_sys_mount fs/namespace.c:3568 [inline]
 __x64_sys_mount+0x27f/0x300 fs/namespace.c:3568
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
 [...]
 </TASK>

The buggy address belongs to the physical page:
page:ffffea00006ef600 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1bbd8
head:ffffea00006ef600 order:3 compound_mapcount:0 compound_pincount:0
flags: 0xfff00000010200(slab|head|node=0|zone=1|lastcpupid=0x7ff)
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88801bbdfe00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff88801bbdfe80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff88801bbdff00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
                   ^
 ffff88801bbdff80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff88801bbe0000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

Kernel will tries to read record and parse MFT from disk in ntfs_read_mft().

Yet the problem is that during enumerating attributes in record, kernel doesn't check whether run_off field loading from the disk is a valid value.

To be more specific, if attr->nres.run_off is larger than attr->size, kernel will passes an invalid argument run_buf_size in run_unpack_ex(), which having an integer overflow. Then this invalid argument will triggers the slab-out-of-bounds Read bug as above.

This patch solves it by adding the sanity check between the offset to packed runs and attribute size.

---
 fs/ntfs3/inode.c | 7 +++++++
 1 file changed, 7 insertions(+)
fs/ntfs3/inode.c +7 -0
index 66afa3db753a..00fd368e7b4a 100644
@@ -373,6 +373,13 @@ static struct inode *ntfs_read_mft(struct inode *inode,
 	}
 
 	t64 = le64_to_cpu(attr->nres.svcn);
+
+	/* offset to packed runs is out-of-bounds */
+	if (roff > asize) {
+		err = -EINVAL;
+		goto out;
+	}
+
 	err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
 			    t64, Add2Ptr(attr, roff), asize - roff);
 	if (err < 0)
Signature · 1 line
2.35.1
author maintainer
#25 lore raw

PATCH 25/290 soundwire: dmi-quirks: add quirk variant for LAPBC710 NUC15

In reply to Greg Kroah-Hartman

From: Pierre-Louis Bossart <[email protected]>

[ Upstream commit f74495761df10c25a98256d16ea7465191b6e2cd ]

Some NUC15 LAPBC710 devices don't expose the same DMI information as the Intel reference, add additional entry in the match table.

---
 drivers/soundwire/dmi-quirks.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/soundwire/dmi-quirks.c +8 -0
index 747983743a14..2bf534632f64 100644
@@ -71,6 +71,14 @@ static const struct dmi_system_id adr_remap_quirk_table[] = {
 		},
 		.driver_data = (void *)intel_tgl_bios,
 	},
+	{
+		/* quirk used for NUC15 LAPBC710 skew */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
+		},
+		.driver_data = (void *)intel_tgl_bios,
+	},
 	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
Signature · 1 line
2.35.1
author maintainer
#26 lore raw

PATCH 26/290 fs/ntfs3: Validate index root when initialize NTFS security

In reply to Greg Kroah-Hartman

From: Edward Lo <[email protected]>

[ Upstream commit bfcdbae0523bd95eb75a739ffb6221a37109881e ]

This enhances the sanity check for $SDH and $SII while initializing NTFS security, guarantees these index root are legit.

[  162.459513] BUG: KASAN: use-after-free in hdr_find_e.isra.0+0x10c/0x320
[  162.460176] Read of size 2 at addr ffff8880037bca99 by task mount/243
[  162.460851]
[  162.461252] CPU: 0 PID: 243 Comm: mount Not tainted 6.0.0-rc7 #42
[  162.461744] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[  162.462609] Call Trace:
[  162.462954]  <TASK>
[  162.463276]  dump_stack_lvl+0x49/0x63
[  162.463822]  print_report.cold+0xf5/0x689
[  162.464608]  ? unwind_get_return_address+0x3a/0x60
[  162.465766]  ? hdr_find_e.isra.0+0x10c/0x320
[  162.466975]  kasan_report+0xa7/0x130
[  162.467506]  ? _raw_spin_lock_irq+0xc0/0xf0
[  162.467998]  ? hdr_find_e.isra.0+0x10c/0x320
[  162.468536]  __asan_load2+0x68/0x90
[  162.468923]  hdr_find_e.isra.0+0x10c/0x320
[  162.469282]  ? cmp_uints+0xe0/0xe0
[  162.469557]  ? cmp_sdh+0x90/0x90
[  162.469864]  ? ni_find_attr+0x214/0x300
[  162.470217]  ? ni_load_mi+0x80/0x80
[  162.470479]  ? entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  162.470931]  ? ntfs_bread_run+0x190/0x190
[  162.471307]  ? indx_get_root+0xe4/0x190
[  162.471556]  ? indx_get_root+0x140/0x190
[  162.471833]  ? indx_init+0x1e0/0x1e0
[  162.472069]  ? fnd_clear+0x115/0x140
[  162.472363]  ? _raw_spin_lock_irqsave+0x100/0x100
[  162.472731]  indx_find+0x184/0x470
[  162.473461]  ? sysvec_apic_timer_interrupt+0x57/0xc0
[  162.474429]  ? indx_find_buffer+0x2d0/0x2d0
[  162.474704]  ? do_syscall_64+0x3b/0x90
[  162.474962]  dir_search_u+0x196/0x2f0
[  162.475381]  ? ntfs_nls_to_utf16+0x450/0x450
[  162.475661]  ? ntfs_security_init+0x3d6/0x440
[  162.475906]  ? is_sd_valid+0x180/0x180
[  162.476191]  ntfs_extend_init+0x13f/0x2c0
[  162.476496]  ? ntfs_fix_post_read+0x130/0x130
[  162.476861]  ? iput.part.0+0x286/0x320
[  162.477325]  ntfs_fill_super+0x11e0/0x1b50
[  162.477709]  ? put_ntfs+0x1d0/0x1d0
[  162.477970]  ? vsprintf+0x20/0x20
[  162.478258]  ? set_blocksize+0x95/0x150
[  162.478538]  get_tree_bdev+0x232/0x370
[  162.478789]  ? put_ntfs+0x1d0/0x1d0
[  162.479038]  ntfs_fs_get_tree+0x15/0x20
[  162.479374]  vfs_get_tree+0x4c/0x130
[  162.479729]  path_mount+0x654/0xfe0
[  162.480124]  ? putname+0x80/0xa0
[  162.480484]  ? finish_automount+0x2e0/0x2e0
[  162.480894]  ? putname+0x80/0xa0
[  162.481467]  ? kmem_cache_free+0x1c4/0x440
[  162.482280]  ? putname+0x80/0xa0
[  162.482714]  do_mount+0xd6/0xf0
[  162.483264]  ? path_mount+0xfe0/0xfe0
[  162.484782]  ? __kasan_check_write+0x14/0x20
[  162.485593]  __x64_sys_mount+0xca/0x110
[  162.486024]  do_syscall_64+0x3b/0x90
[  162.486543]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  162.487141] RIP: 0033:0x7f9d374e948a
[  162.488324] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 008
[  162.489728] RSP: 002b:00007ffe30e73d18 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[  162.490971] RAX: ffffffffffffffda RBX: 0000561cdb43a060 RCX: 00007f9d374e948a
[  162.491669] RDX: 0000561cdb43a260 RSI: 0000561cdb43a2e0 RDI: 0000561cdb442af0
[  162.492050] RBP: 0000000000000000 R08: 0000561cdb43a280 R09: 0000000000000020
[  162.492459] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 0000561cdb442af0
[  162.493183] R13: 0000561cdb43a260 R14: 0000000000000000 R15: 00000000ffffffff
[  162.493644]  </TASK>
[  162.493908]
[  162.494214] The buggy address belongs to the physical page:
[  162.494761] page:000000003e38a3d5 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x37bc
[  162.496064] flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
[  162.497278] raw: 000fffffc0000000 ffffea00000df1c8 ffffea00000df008 0000000000000000
[  162.498928] raw: 0000000000000000 0000000000240000 00000000ffffffff 0000000000000000
[  162.500542] page dumped because: kasan: bad access detected
[  162.501057]
[  162.501242] Memory state around the buggy address:
[  162.502230]  ffff8880037bc980: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[  162.502977]  ffff8880037bca00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[  162.503522] >ffff8880037bca80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[  162.503963]                             ^
[  162.504370]  ffff8880037bcb00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[  162.504766]  ffff8880037bcb80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
---
 fs/ntfs3/fsntfs.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
fs/ntfs3/fsntfs.c +6 -4
index 24b57c3cc625..4a97a28cb8f2 100644
@@ -1878,9 +1878,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
 		goto out;
 	}
 
-	root_sdh = resident_data(attr);
+	root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
 	if (root_sdh->type != ATTR_ZERO ||
-	    root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH) {
+	    root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH ||
+	    offsetof(struct INDEX_ROOT, ihdr) + root_sdh->ihdr.used > attr->res.data_size) {
 		err = -EINVAL;
 		goto out;
 	}
@@ -1896,9 +1897,10 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
 		goto out;
 	}
 
-	root_sii = resident_data(attr);
+	root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
 	if (root_sii->type != ATTR_ZERO ||
-	    root_sii->rule != NTFS_COLLATION_TYPE_UINT) {
+	    root_sii->rule != NTFS_COLLATION_TYPE_UINT ||
+	    offsetof(struct INDEX_ROOT, ihdr) + root_sii->ihdr.used > attr->res.data_size) {
 		err = -EINVAL;
 		goto out;
 	}
Signature · 1 line
2.35.1
author maintainer
#27 lore raw

PATCH 27/290 fs/ntfs3: Use __GFP_NOWARN allocation at wnd_init()

In reply to Greg Kroah-Hartman

From: Tetsuo Handa <[email protected]>

[ Upstream commit 0d0f659bf713662fabed973f9996b8f23c59ca51 ]

syzbot is reporting too large allocation at wnd_init() [1], for a crafted filesystem can become wnd->nwnd close to UINT_MAX. Add __GFP_NOWARN in order to avoid too large allocation warning, than exhausting memory by using kvcalloc().

---
 fs/ntfs3/bitmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ntfs3/bitmap.c +1 -1
index 7f2055b7427a..2a63793f522d 100644
@@ -666,7 +666,7 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits)
 	if (!wnd->bits_last)
 		wnd->bits_last = wbits;
 
-	wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS);
+	wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
 	if (!wnd->free_bits)
 		return -ENOMEM;
 
Signature · 1 line
2.35.1
author maintainer
#28 lore raw

PATCH 28/290 fs/ntfs3: Use __GFP_NOWARN allocation at ntfs_fill_super()

In reply to Greg Kroah-Hartman

From: Tetsuo Handa <[email protected]>

[ Upstream commit 59bfd7a483da36bd202532a3d9ea1f14f3bf3aaf ]

syzbot is reporting too large allocation at ntfs_fill_super() [1], for a crafted filesystem can contain bogus inode->i_size. Add __GFP_NOWARN in order to avoid too large allocation warning, than exhausting memory by using kvmalloc().

---
 fs/ntfs3/super.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/ntfs3/super.c +1 -1
index a18fb431abbe..33b1833ad525 100644
@@ -1136,7 +1136,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc)
 		goto put_inode_out;
 	}
 	bytes = inode->i_size;
-	sbi->def_table = t = kmalloc(bytes, GFP_NOFS);
+	sbi->def_table = t = kmalloc(bytes, GFP_NOFS | __GFP_NOWARN);
 	if (!t) {
 		err = -ENOMEM;
 		goto put_inode_out;
Signature · 1 line
2.35.1
author maintainer
#29 lore raw

PATCH 29/290 fs/ntfs3: Delete duplicate condition in ntfs_read_mft()

In reply to Greg Kroah-Hartman

From: Dan Carpenter <[email protected]>

[ Upstream commit 658015167a8432b88f5d032e9d85d8fd50e5bf2c ]

There were two patches which addressed the same bug and added the same condition:

commit 6db620863f85 ("fs/ntfs3: Validate data run offset") commit 887bfc546097 ("fs/ntfs3: Fix slab-out-of-bounds read in run_unpack")

Delete one condition.

---
 fs/ntfs3/inode.c | 6 ------
 1 file changed, 6 deletions(-)
fs/ntfs3/inode.c +0 -6
index 00fd368e7b4a..ed640e4e3fac 100644
@@ -374,12 +374,6 @@ static struct inode *ntfs_read_mft(struct inode *inode,
 
 	t64 = le64_to_cpu(attr->nres.svcn);
 
-	/* offset to packed runs is out-of-bounds */
-	if (roff > asize) {
-		err = -EINVAL;
-		goto out;
-	}
-
 	err = run_unpack_ex(run, sbi, ino, t64, le64_to_cpu(attr->nres.evcn),
 			    t64, Add2Ptr(attr, roff), asize - roff);
 	if (err < 0)
Signature · 1 line
2.35.1
author maintainer
#30 lore raw

PATCH 30/290 fs/ntfs3: Fix slab-out-of-bounds in r_page

In reply to Greg Kroah-Hartman

From: Yin Xiujiang <[email protected]>

[ Upstream commit ecfbd57cf9c5ca225184ae266ce44ae473792132 ]

When PAGE_SIZE is 64K, if read_log_page is called by log_read_rst for the first time, the size of *buffer would be equal to DefaultLogPageSize(4K).But for *buffer operations like memcpy, if the memory area size(n) which being assigned to buffer is larger than 4K (log->page_size(64K) or bytes(64K-page_off)), it will cause an out of boundary error.

 Call trace:
  [...]
  kasan_report+0x44/0x130
  check_memory_region+0xf8/0x1a0
  memcpy+0xc8/0x100
  ntfs_read_run_nb+0x20c/0x460
  read_log_page+0xd0/0x1f4
  log_read_rst+0x110/0x75c
  log_replay+0x1e8/0x4aa0
  ntfs_loadlog_and_replay+0x290/0x2d0
  ntfs_fill_super+0x508/0xec0
  get_tree_bdev+0x1fc/0x34c
  [...]

Fix this by setting variable r_page to NULL in log_read_rst.

---
 fs/ntfs3/fslog.c | 26 ++------------------------
 1 file changed, 2 insertions(+), 24 deletions(-)
fs/ntfs3/fslog.c +2 -24
index bcdddcd7bc79..20abdb268286 100644
@@ -1132,7 +1132,7 @@ static int read_log_page(struct ntfs_log *log, u32 vbo,
 		return -EINVAL;
 
 	if (!*buffer) {
-		to_free = kmalloc(bytes, GFP_NOFS);
+		to_free = kmalloc(log->page_size, GFP_NOFS);
 		if (!to_free)
 			return -ENOMEM;
 		*buffer = to_free;
@@ -1180,10 +1180,7 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
 			struct restart_info *info)
 {
 	u32 skip, vbo;
-	struct RESTART_HDR *r_page = kmalloc(DefaultLogPageSize, GFP_NOFS);
-
-	if (!r_page)
-		return -ENOMEM;
+	struct RESTART_HDR *r_page = NULL;
 
 	/* Determine which restart area we are looking for. */
 	if (first) {
@@ -1197,7 +1194,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
 	/* Loop continuously until we succeed. */
 	for (; vbo < l_size; vbo = 2 * vbo + skip, skip = 0) {
 		bool usa_error;
-		u32 sys_page_size;
 		bool brst, bchk;
 		struct RESTART_AREA *ra;
 
@@ -1251,24 +1247,6 @@ static int log_read_rst(struct ntfs_log *log, u32 l_size, bool first,
 			goto check_result;
 		}
 
-		/* Read the entire restart area. */
-		sys_page_size = le32_to_cpu(r_page->sys_page_size);
-		if (DefaultLogPageSize != sys_page_size) {
-			kfree(r_page);
-			r_page = kzalloc(sys_page_size, GFP_NOFS);
-			if (!r_page)
-				return -ENOMEM;
-
-			if (read_log_page(log, vbo,
-					  (struct RECORD_PAGE_HDR **)&r_page,
-					  &usa_error)) {
-				/* Ignore any errors. */
-				kfree(r_page);
-				r_page = NULL;
-				continue;
-			}
-		}
-
 		if (is_client_area_valid(r_page, usa_error)) {
 			info->valid_page = true;
 			ra = Add2Ptr(r_page, le16_to_cpu(r_page->ra_off));
Signature · 1 line
2.35.1
author maintainer
#31 lore raw

PATCH 31/290 objtool: Fix SEGFAULT

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

[ Upstream commit efb11fdb3e1a9f694fa12b70b21e69e55ec59c36 ]

find_insn() will return NULL in case of failure. Check insn in order to avoid a kernel Oops for NULL pointer dereference.

---
 tools/objtool/check.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/objtool/check.c +1 -1
index edac5aaa2802..308c8806ad94 100644
@@ -197,7 +197,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func,
 		return false;
 
 	insn = find_insn(file, func->sec, func->offset);
-	if (!insn->func)
+	if (!insn || !insn->func)
 		return false;
 
 	func_for_each_insn(file, func, insn) {
Signature · 1 line
2.35.1
author maintainer
#32 lore raw

PATCH 32/290 powerpc/rtas: avoid device tree lookups in rtas_os_term()

In reply to Greg Kroah-Hartman

From: Nathan Lynch <[email protected]>

[ Upstream commit ed2213bfb192ab51f09f12e9b49b5d482c6493f3 ]

rtas_os_term() is called during panic. Its behavior depends on a couple of conditions in the /rtas node of the device tree, the traversal of which entails locking and local IRQ state changes. If the kernel panics while devtree_lock is held, rtas_os_term() as currently written could hang.

Instead of discovering the relevant characteristics at panic time, cache them in file-static variables at boot. Note the lookup for "ibm,extended-os-term" is converted to of_property_read_bool() since it is a boolean property, not an RTAS function token.

---
 arch/powerpc/kernel/rtas.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
arch/powerpc/kernel/rtas.c +10 -3
index 7834ce3aa7f1..4d8de49c9d4b 100644
@@ -788,6 +788,7 @@ void __noreturn rtas_halt(void)
 
 /* Must be in the RMO region, so we place it here */
 static char rtas_os_term_buf[2048];
+static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE;
 
 void rtas_os_term(char *str)
 {
@@ -799,14 +800,13 @@ void rtas_os_term(char *str)
 	 * this property may terminate the partition which we want to avoid
 	 * since it interferes with panic_timeout.
 	 */
-	if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") ||
-	    RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term"))
+	if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE)
 		return;
 
 	snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
 
 	do {
-		status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
+		status = rtas_call(ibm_os_term_token, 1, 1, NULL,
 				   __pa(rtas_os_term_buf));
 	} while (rtas_busy_delay(status));
 
@@ -1167,6 +1167,13 @@ void __init rtas_initialize(void)
 	no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry);
 	rtas.entry = no_entry ? rtas.base : entry;
 
+	/*
+	 * Discover these now to avoid device tree lookups in the
+	 * panic path.
+	 */
+	if (of_property_read_bool(rtas.dev, "ibm,extended-os-term"))
+		ibm_os_term_token = rtas_token("ibm,os-term");
+
 	/* If RTAS was found, allocate the RMO buffer for it and look for
 	 * the stop-self token if any
 	 */
Signature · 1 line
2.35.1
author maintainer
#33 lore raw

PATCH 33/290 powerpc/rtas: avoid scheduling in rtas_os_term()

In reply to Greg Kroah-Hartman

From: Nathan Lynch <[email protected]>

[ Upstream commit 6c606e57eecc37d6b36d732b1ff7e55b7dc32dd4 ]

It's unsafe to use rtas_busy_delay() to handle a busy status from the ibm,os-term RTAS function in rtas_os_term():

Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
BUG: sleeping function called from invalid context at arch/powerpc/kernel/rtas.c:618
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 1, name: swapper/0
preempt_count: 2, expected: 0
CPU: 7 PID: 1 Comm: swapper/0 Tainted: G      D            6.0.0-rc5-02182-gf8553a572277-dirty #9
Call Trace:
[c000000007b8f000] [c000000001337110] dump_stack_lvl+0xb4/0x110 (unreliable)
[c000000007b8f040] [c0000000002440e4] __might_resched+0x394/0x3c0
[c000000007b8f0e0] [c00000000004f680] rtas_busy_delay+0x120/0x1b0
[c000000007b8f100] [c000000000052d04] rtas_os_term+0xb8/0xf4
[c000000007b8f180] [c0000000001150fc] pseries_panic+0x50/0x68
[c000000007b8f1f0] [c000000000036354] ppc_panic_platform_handler+0x34/0x50
[c000000007b8f210] [c0000000002303c4] notifier_call_chain+0xd4/0x1c0
[c000000007b8f2b0] [c0000000002306cc] atomic_notifier_call_chain+0xac/0x1c0
[c000000007b8f2f0] [c0000000001d62b8] panic+0x228/0x4d0
[c000000007b8f390] [c0000000001e573c] do_exit+0x140c/0x1420
[c000000007b8f480] [c0000000001e586c] make_task_dead+0xdc/0x200

Use rtas_busy_delay_time() instead, which signals without side effects whether to attempt the ibm,os-term RTAS call again.

---
 arch/powerpc/kernel/rtas.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
arch/powerpc/kernel/rtas.c +6 -1
index 4d8de49c9d4b..2dae702e7a5a 100644
@@ -805,10 +805,15 @@ void rtas_os_term(char *str)
 
 	snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
 
+	/*
+	 * Keep calling as long as RTAS returns a "try again" status,
+	 * but don't use rtas_busy_delay(), which potentially
+	 * schedules.
+	 */
 	do {
 		status = rtas_call(ibm_os_term_token, 1, 1, NULL,
 				   __pa(rtas_os_term_buf));
-	} while (rtas_busy_delay(status));
+	} while (rtas_busy_delay_time(status));
 
 	if (status != 0)
 		printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
Signature · 1 line
2.35.1
author maintainer
#34 lore raw

PATCH 34/290 HID: multitouch: fix Asus ExpertBook P2 P2451FA trackpoint

In reply to Greg Kroah-Hartman

From: José Expósito <[email protected]>

[ Upstream commit 4eab1c2fe06c98a4dff258dd64800b6986c101e9 ]

The HID descriptor of this device contains two mouse collections, one for mouse emulation and the other for the trackpoint.

Both collections get merged and, because the first one defines X and Y, the movemenent events reported by the trackpoint collection are ignored.

Set the MT_CLS_WIN_8_FORCE_MULTI_INPUT class for this device to be able to receive its reports.

This fix is similar to/based on commit 40d5bb87377a ("HID: multitouch:
enable multi-input as a quirk for some devices").

---
 drivers/hid/hid-multitouch.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/hid/hid-multitouch.c +4 -0
index 08462ac72b89..6b86d368d5e7 100644
@@ -1965,6 +1965,10 @@ static const struct hid_device_id mt_devices[] = {
 		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
 			USB_VENDOR_ID_ELAN, 0x313a) },
 
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
+		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_ELAN, 0x3148) },
+
 	/* Elitegroup panel */
 	{ .driver_data = MT_CLS_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
Signature · 1 line
2.35.1
author maintainer
#35 lore raw

PATCH 35/290 HID: plantronics: Additional PIDs for double volume key presses quirk

In reply to Greg Kroah-Hartman

From: Terry Junge <[email protected]>

[ Upstream commit 3d57f36c89d8ba32b2c312f397a37fd1a2dc7cfc ]

I no longer work for Plantronics (aka Poly, aka HP) and do not have access to the headsets in order to test. However, as noted by Maxim, the other 32xx models that share the same base code set as the 3220 would need the same quirk. This patch adds the PIDs for the rest of the Blackwire 32XX product family that require the quirk.

Plantronics Blackwire 3210 Series (047f:c055)
Plantronics Blackwire 3215 Series (047f:c057)
Plantronics Blackwire 3225 Series (047f:c058)

Quote from previous patch by Maxim Mikityanskiy Plantronics Blackwire 3220 Series (047f:c056) sends HID reports twice for each volume key press. This patch adds a quirk to hid-plantronics for this product ID, which will ignore the second volume key press if it happens within 5 ms from the last one that was handled.

The patch was tested on the mentioned model only, it shouldn't affect other models, however, this quirk might be needed for them too. Auto-repeat (when a key is held pressed) is not affected, because the rate is about 3 times per second, which is far less frequent than once in 5 ms.
End quote

---
 drivers/hid/hid-ids.h         | 3 +++
 drivers/hid/hid-plantronics.c | 9 +++++++++
 2 files changed, 12 insertions(+)
drivers/hid/hid-ids.h +3 -0
index 78b55f845d2d..8698d49edaa3 100644
@@ -966,7 +966,10 @@
 #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S	0x8003
 
 #define USB_VENDOR_ID_PLANTRONICS	0x047f
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES	0xc055
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES	0xc056
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES	0xc057
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES	0xc058
 
 #define USB_VENDOR_ID_PANASONIC		0x04da
 #define USB_DEVICE_ID_PANABOARD_UBT780	0x1044
drivers/hid/hid-plantronics.c +9 -0
index e81b7cec2d12..3d414ae194ac 100644
@@ -198,9 +198,18 @@ static int plantronics_probe(struct hid_device *hdev,
 }
 
 static const struct hid_device_id plantronics_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
+		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
 					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
 		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
+		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
+		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
 	{ }
 };
Signature · 1 line
2.35.1
author maintainer
#36 lore raw

PATCH 36/290 pstore: Properly assign mem_type property

In reply to Greg Kroah-Hartman

From: Luca Stefani <[email protected]>

commit beca3e311a49cd3c55a056096531737d7afa4361 upstream.

If mem-type is specified in the device tree it would end up overriding the record_size field instead of populating mem_type.

As record_size is currently parsed after the improper assignment with default size 0 it continued to work as expected regardless of the value found in the device tree.

Simply changing the target field of the struct is enough to get mem-type working as expected.

Fixes 9d843e8fafc7 ("pstore: Add mem_type property DT parsing support")
---
 fs/pstore/ram.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/pstore/ram.c +1 -1
@@ -670,7 +670,7 @@ static int ramoops_parse_dt(struct platf
 		field = value;						\
 	}
 
-	parse_u32("mem-type", pdata->record_size, pdata->mem_type);
+	parse_u32("mem-type", pdata->mem_type, pdata->mem_type);
 	parse_u32("record-size", pdata->record_size, 0);
 	parse_u32("console-size", pdata->console_size, 0);
 	parse_u32("ftrace-size", pdata->ftrace_size, 0);
author maintainer
#37 lore raw

PATCH 37/290 pstore/zone: Use GFP_ATOMIC to allocate zone buffer

In reply to Greg Kroah-Hartman

From: Qiujun Huang <[email protected]>

commit 99b3b837855b987563bcfb397cf9ddd88262814b upstream.

There is a case found when triggering a panic_on_oom, pstore fails to dump kmsg. Because psz_kmsg_write_record can't get the new buffer.

Handle this by using GFP_ATOMIC to allocate a buffer at lower watermark.

---
 fs/pstore/zone.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/pstore/zone.c +1 -1
@@ -761,7 +761,7 @@ static inline int notrace psz_kmsg_write
 		/* avoid destroying old data, allocate a new one */
 		len = zone->buffer_size + sizeof(*zone->buffer);
 		zone->oldbuf = zone->buffer;
-		zone->buffer = kzalloc(len, GFP_KERNEL);
+		zone->buffer = kzalloc(len, GFP_ATOMIC);
 		if (!zone->buffer) {
 			zone->buffer = zone->oldbuf;
 			return -ENOMEM;
author maintainer
#38 lore raw

PATCH 38/290 hfsplus: fix bug causing custom uid and gid being unable to be assigned with mount

In reply to Greg Kroah-Hartman

From: Aditya Garg <[email protected]>

commit 9f2b5debc07073e6dfdd774e3594d0224b991927 upstream.

Despite specifying UID and GID in mount command, the specified UID and GID were not being assigned. This patch fixes this issue.

---
 fs/hfsplus/hfsplus_fs.h |    2 ++
 fs/hfsplus/inode.c      |    4 ++--
 fs/hfsplus/options.c    |    4 ++++
 3 files changed, 8 insertions(+), 2 deletions(-)
fs/hfsplus/hfsplus_fs.h +2 -0
@@ -198,6 +198,8 @@ struct hfsplus_sb_info {
 #define HFSPLUS_SB_HFSX		3
 #define HFSPLUS_SB_CASEFOLD	4
 #define HFSPLUS_SB_NOBARRIER	5
+#define HFSPLUS_SB_UID		6
+#define HFSPLUS_SB_GID		7
 
 static inline struct hfsplus_sb_info *HFSPLUS_SB(struct super_block *sb)
 {
fs/hfsplus/inode.c +2 -2
@@ -190,11 +190,11 @@ static void hfsplus_get_perms(struct ino
 	mode = be16_to_cpu(perms->mode);
 
 	i_uid_write(inode, be32_to_cpu(perms->owner));
-	if (!i_uid_read(inode) && !mode)
+	if ((test_bit(HFSPLUS_SB_UID, &sbi->flags)) || (!i_uid_read(inode) && !mode))
 		inode->i_uid = sbi->uid;
 
 	i_gid_write(inode, be32_to_cpu(perms->group));
-	if (!i_gid_read(inode) && !mode)
+	if ((test_bit(HFSPLUS_SB_GID, &sbi->flags)) || (!i_gid_read(inode) && !mode))
 		inode->i_gid = sbi->gid;
 
 	if (dir) {
fs/hfsplus/options.c +4 -0
@@ -140,6 +140,8 @@ int hfsplus_parse_options(char *input, s
 			if (!uid_valid(sbi->uid)) {
 				pr_err("invalid uid specified\n");
 				return 0;
+			} else {
+				set_bit(HFSPLUS_SB_UID, &sbi->flags);
 			}
 			break;
 		case opt_gid:
@@ -151,6 +153,8 @@ int hfsplus_parse_options(char *input, s
 			if (!gid_valid(sbi->gid)) {
 				pr_err("invalid gid specified\n");
 				return 0;
+			} else {
+				set_bit(HFSPLUS_SB_GID, &sbi->flags);
 			}
 			break;
 		case opt_part:
author maintainer
#39 lore raw

PATCH 39/290 binfmt: Fix error return code in load_elf_fdpic_binary()

In reply to Greg Kroah-Hartman

From: Wang Yufen <[email protected]>

commit e7f703ff2507f4e9f496da96cd4b78fd3026120c upstream.

Fix to return a negative error code from create_elf_fdpic_tables() instead of 0.

---
 fs/binfmt_elf_fdpic.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
fs/binfmt_elf_fdpic.c +3 -2
@@ -434,8 +434,9 @@ static int load_elf_fdpic_binary(struct
 	current->mm->start_stack = current->mm->start_brk + stack_size;
 #endif
 
-	if (create_elf_fdpic_tables(bprm, current->mm,
-				    &exec_params, &interp_params) < 0)
+	retval = create_elf_fdpic_tables(bprm, current->mm, &exec_params,
+					 &interp_params);
+	if (retval < 0)
 		goto error;
 
 	kdebug("- start_code  %lx", current->mm->start_code);
author maintainer
#40 lore raw

PATCH 40/290 ovl: Use ovl mounters fsuid and fsgid in ovl_link()

In reply to Greg Kroah-Hartman

From: Zhang Tianci <[email protected]>

commit 5b0db51215e895a361bc63132caa7cca36a53d6a upstream.

There is a wrong case of link() on overlay:

  $ mkdir /lower /fuse /merge
  $ mount -t fuse /fuse
  $ mkdir /fuse/upper /fuse/work
  $ mount -t overlay /merge -o lowerdir=/lower,upperdir=/fuse/upper,\
    workdir=work
  $ touch /merge/file
  $ chown bin.bin /merge/file // the file's caller becomes "bin"
  $ ln /merge/file /merge/lnkfile

Then we will get an error(EACCES) because fuse daemon checks the link()'s caller is "bin", it denied this request.

In the changing history of ovl_link(), there are two key commits:

The first is commit bb0d2b8ad296 ("ovl: fix sgid on directory") which overrides the cred's fsuid/fsgid using the new inode. The new inode's owner is initialized by inode_init_owner(), and inode->fsuid is assigned to the current user. So the override fsuid becomes the current user. We know link() is actually modifying the directory, so the caller must have the MAY_WRITE permission on the directory. The current caller may should have this permission. This is acceptable to use the caller's fsuid.

The second is commit 51f7e52dc943 ("ovl: share inode for hard link") which removed the inode creation in ovl_link(). This commit move inode_init_owner() into ovl_create_object(), so the ovl_link() just give the old inode to ovl_create_or_link(). Then the override fsuid becomes the old inode's fsuid, neither the caller nor the overlay's mounter! So this is incorrect.

Fix this bug by using ovl mounter's fsuid/fsgid to do underlying fs's link().

---
 fs/overlayfs/dir.c |   46 ++++++++++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 16 deletions(-)
fs/overlayfs/dir.c +30 -16
@@ -589,28 +589,42 @@ static int ovl_create_or_link(struct den
 			goto out_revert_creds;
 	}
 
-	err = -ENOMEM;
-	override_cred = prepare_creds();
-	if (override_cred) {
+	if (!attr->hardlink) {
+		err = -ENOMEM;
+		override_cred = prepare_creds();
+		if (!override_cred)
+			goto out_revert_creds;
+		/*
+		 * In the creation cases(create, mkdir, mknod, symlink),
+		 * ovl should transfer current's fs{u,g}id to underlying
+		 * fs. Because underlying fs want to initialize its new
+		 * inode owner using current's fs{u,g}id. And in this
+		 * case, the @inode is a new inode that is initialized
+		 * in inode_init_owner() to current's fs{u,g}id. So use
+		 * the inode's i_{u,g}id to override the cred's fs{u,g}id.
+		 *
+		 * But in the other hardlink case, ovl_link() does not
+		 * create a new inode, so just use the ovl mounter's
+		 * fs{u,g}id.
+		 */
 		override_cred->fsuid = inode->i_uid;
 		override_cred->fsgid = inode->i_gid;
-		if (!attr->hardlink) {
-			err = security_dentry_create_files_as(dentry,
-					attr->mode, &dentry->d_name, old_cred,
-					override_cred);
-			if (err) {
-				put_cred(override_cred);
-				goto out_revert_creds;
-			}
+		err = security_dentry_create_files_as(dentry,
+				attr->mode, &dentry->d_name, old_cred,
+				override_cred);
+		if (err) {
+			put_cred(override_cred);
+			goto out_revert_creds;
 		}
 		put_cred(override_creds(override_cred));
 		put_cred(override_cred);
-
-		if (!ovl_dentry_is_whiteout(dentry))
-			err = ovl_create_upper(dentry, inode, attr);
-		else
-			err = ovl_create_over_whiteout(dentry, inode, attr);
 	}
+
+	if (!ovl_dentry_is_whiteout(dentry))
+		err = ovl_create_upper(dentry, inode, attr);
+	else
+		err = ovl_create_over_whiteout(dentry, inode, attr);
+
 out_revert_creds:
 	revert_creds(old_cred);
 	return err;
author maintainer
#41 lore raw

PATCH 41/290 ALSA: line6: correct midi status byte when receiving data from podxt

In reply to Greg Kroah-Hartman

From: Artem Egorkine <[email protected]>

commit 8508fa2e7472f673edbeedf1b1d2b7a6bb898ecc upstream.

A PODxt device sends 0xb2, 0xc2 or 0xf2 as a status byte for MIDI messages over USB that should otherwise have a 0xb0, 0xc0 or 0xf0 status byte. This is usually corrected by the driver on other OSes.

This fixes MIDI sysex messages sent by PODxt.

[ tiwai: fixed white spaces ]

---
 sound/usb/line6/driver.c  |    3 ++-
 sound/usb/line6/midi.c    |    3 ++-
 sound/usb/line6/midibuf.c |   25 +++++++++++++++++--------
 sound/usb/line6/midibuf.h |    5 ++++-
 sound/usb/line6/pod.c     |    3 ++-
 5 files changed, 27 insertions(+), 12 deletions(-)
sound/usb/line6/driver.c +2 -1
@@ -304,7 +304,8 @@ static void line6_data_received(struct u
 		for (;;) {
 			done =
 				line6_midibuf_read(mb, line6->buffer_message,
-						LINE6_MIDI_MESSAGE_MAXLEN);
+						   LINE6_MIDI_MESSAGE_MAXLEN,
+						   LINE6_MIDIBUF_READ_RX);
 
 			if (done <= 0)
 				break;
sound/usb/line6/midi.c +2 -1
@@ -56,7 +56,8 @@ static void line6_midi_transmit(struct s
 
 	for (;;) {
 		done = line6_midibuf_read(mb, chunk,
-					  LINE6_FALLBACK_MAXPACKETSIZE);
+					  LINE6_FALLBACK_MAXPACKETSIZE,
+					  LINE6_MIDIBUF_READ_TX);
 
 		if (done == 0)
 			break;
sound/usb/line6/midibuf.c +17 -8
@@ -9,6 +9,7 @@
 
 #include "midibuf.h"
 
+
 static int midibuf_message_length(unsigned char code)
 {
 	int message_length;
@@ -20,12 +21,7 @@ static int midibuf_message_length(unsign
 
 		message_length = length[(code >> 4) - 8];
 	} else {
-		/*
-		   Note that according to the MIDI specification 0xf2 is
-		   the "Song Position Pointer", but this is used by Line 6
-		   to send sysex messages to the host.
-		 */
-		static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
+		static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
 			1, 1, 1, -1, 1, 1
 		};
 		message_length = length[code & 0x0f];
@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buff
 }
 
 int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
-		       int length)
+		       int length, int read_type)
 {
 	int bytes_used;
 	int length1, length2;
@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffe
 
 	length1 = this->size - this->pos_read;
 
-	/* check MIDI command length */
 	command = this->buf[this->pos_read];
+	/*
+	   PODxt always has status byte lower nibble set to 0010,
+	   when it means to send 0000, so we correct if here so
+	   that control/program changes come on channel 1 and
+	   sysex message status byte is correct
+	 */
+	if (read_type == LINE6_MIDIBUF_READ_RX) {
+		if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
+			unsigned char fixed = command & 0xf0;
+			this->buf[this->pos_read] = fixed;
+			command = fixed;
+		}
+	}
 
+	/* check MIDI command length */
 	if (command & 0x80) {
 		midi_length = midibuf_message_length(command);
 		this->command_prev = command;
sound/usb/line6/midibuf.h +4 -1
@@ -8,6 +8,9 @@
 #ifndef MIDIBUF_H
 #define MIDIBUF_H
 
+#define LINE6_MIDIBUF_READ_TX 0
+#define LINE6_MIDIBUF_READ_RX 1
+
 struct midi_buffer {
 	unsigned char *buf;
 	int size;
@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct
 extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
 extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
 extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
-			      int length);
+			      int length, int read_type);
 extern void line6_midibuf_reset(struct midi_buffer *mb);
 extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
 			       int length);
sound/usb/line6/pod.c +2 -1
@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_p
 	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
 };
 
+
 static const char pod_version_header[] = {
-	0xf2, 0x7e, 0x7f, 0x06, 0x02
+	0xf0, 0x7e, 0x7f, 0x06, 0x02
 };
 
 static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,
author maintainer
#42 lore raw

PATCH 42/290 ALSA: line6: fix stack overflow in line6_midi_transmit

In reply to Greg Kroah-Hartman

From: Artem Egorkine <[email protected]>

commit b8800d324abb50160560c636bfafe2c81001b66c upstream.

Correctly calculate available space including the size of the chunk buffer. This fixes a buffer overflow when multiple MIDI sysex messages are sent to a PODxt device.

---
 sound/usb/line6/midi.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/usb/line6/midi.c +2 -1
@@ -44,7 +44,8 @@ static void line6_midi_transmit(struct s
 	int req, done;
 
 	for (;;) {
-		req = min(line6_midibuf_bytes_free(mb), line6->max_packet_size);
+		req = min3(line6_midibuf_bytes_free(mb), line6->max_packet_size,
+			   LINE6_FALLBACK_MAXPACKETSIZE);
 		done = snd_rawmidi_transmit_peek(substream, chunk, req);
 
 		if (done == 0)
author maintainer
#43 lore raw

PATCH 43/290 pnode: terminate at peers of source

In reply to Greg Kroah-Hartman

From: Christian Brauner <[email protected]>

commit 11933cf1d91d57da9e5c53822a540bbdc2656c16 upstream.

The propagate_mnt() function handles mount propagation when creating mounts and propagates the source mount tree @source_mnt to all applicable nodes of the destination propagation mount tree headed by @dest_mnt.

Unfortunately it contains a bug where it fails to terminate at peers of @source_mnt when looking up copies of the source mount that become masters for copies of the source mount tree mounted on top of slaves in the destination propagation tree causing a NULL dereference.

Once the mechanics of the bug are understood it's easy to trigger. Because of unprivileged user namespaces it is available to unprivileged users.

While fixing this bug we've gotten confused multiple times due to unclear terminology or missing concepts. So let's start this with some clarifications:

* The terms "master" or "peer" denote a shared mount. A shared mount belongs to a peer group.

* A peer group is a set of shared mounts that propagate to each other. They are identified by a peer group id. The peer group id is available in @shared_mnt->mnt_group_id.
Shared mounts within the same peer group have the same peer group id. The peers in a peer group can be reached via @shared_mnt->mnt_share.

* The terms "slave mount" or "dependent mount" denote a mount that receives propagation from a peer in a peer group. IOW, shared mounts may have slave mounts and slave mounts have shared mounts as their master. Slave mounts of a given peer in a peer group are listed on that peers slave list available at @shared_mnt->mnt_slave_list.

* The term "master mount" denotes a mount in a peer group. IOW, it denotes a shared mount or a peer mount in a peer group. The term "master mount" - or "master" for short - is mostly used when talking in the context of slave mounts that receive propagation from a master mount. A master mount of a slave identifies the closest peer group a slave mount receives propagation from. The master mount of a slave can be identified via @slave_mount->mnt_master. Different slaves may point to different masters in the same peer group.

* Multiple peers in a peer group can have non-empty ->mnt_slave_lists. Non-empty ->mnt_slave_lists of peers don't intersect. Consequently, to ensure all slave mounts of a peer group are visited the ->mnt_slave_lists of all peers in a peer group have to be walked.

* Slave mounts point to a peer in the closest peer group they receive propagation from via @slave_mnt->mnt_master (see above). Together with these peers they form a propagation group (see below). The closest peer group can thus be identified through the peer group id @slave_mnt->mnt_master->mnt_group_id of the peer/master that a slave mount receives propagation from.

* A shared-slave mount is a slave mount to a peer group pg1 while also a peer in another peer group pg2. IOW, a peer group may receive propagation from another peer group.

If a peer group pg1 is a slave to another peer group pg2 then all peers in peer group pg1 point to the same peer in peer group pg2 via ->mnt_master. IOW, all peers in peer group pg1 appear on the same ->mnt_slave_list. IOW, they cannot be slaves to different peer groups.

* A pure slave mount is a slave mount that is a slave to a peer group but is not a peer in another peer group.

* A propagation group denotes the set of mounts consisting of a single peer group pg1 and all slave mounts and shared-slave mounts that point to a peer in that peer group via ->mnt_master. IOW, all slave mounts such that @slave_mnt->mnt_master->mnt_group_id is equal to @shared_mnt->mnt_group_id.

The concept of a propagation group makes it easier to talk about a single propagation level in a propagation tree.

For example, in propagate_mnt() the immediate peers of @dest_mnt and all slaves of @dest_mnt's peer group form a propagation group propg1. So a shared-slave mount that is a slave in propg1 and that is a peer in another peer group pg2 forms another propagation group propg2 together with all slaves that point to that shared-slave mount in their ->mnt_master.

* A propagation tree refers to all mounts that receive propagation starting from a specific shared mount.

For example, for propagate_mnt() @dest_mnt is the start of a propagation tree. The propagation tree ecompasses all mounts that receive propagation from @dest_mnt's peer group down to the leafs.

With that out of the way let's get to the actual algorithm.

We know that @dest_mnt is guaranteed to be a pure shared mount or a shared-slave mount. This is guaranteed by a check in attach_recursive_mnt(). So propagate_mnt() will first propagate the source mount tree to all peers in @dest_mnt's peer group:

for (n = next_peer(dest_mnt); n != dest_mnt; n = next_peer(n)) {
        ret = propagate_one(n);
        if (ret)
               goto out;
}

Notice, that the peer propagation loop of propagate_mnt() doesn't propagate @dest_mnt itself. @dest_mnt is mounted directly in attach_recursive_mnt() after we propagated to the destination propagation tree.

The mount that will be mounted on top of @dest_mnt is @source_mnt. This copy was created earlier even before we entered attach_recursive_mnt() and doesn't concern us a lot here.

It's just important to notice that when propagate_mnt() is called @source_mnt will not yet have been mounted on top of @dest_mnt. Thus, @source_mnt->mnt_parent will either still point to @source_mnt or - in the case @source_mnt is moved and thus already attached - still to its former parent.

For each peer @m in @dest_mnt's peer group propagate_one() will create a new copy of the source mount tree and mount that copy @child on @m such that @child->mnt_parent points to @m after propagate_one() returns.

propagate_one() will stash the last destination propagation node @m in @last_dest and the last copy it created for the source mount tree in @last_source.

Hence, if we call into propagate_one() again for the next destination propagation node @m, @last_dest will point to the previous destination propagation node and @last_source will point to the previous copy of the source mount tree and mounted on @last_dest.

Each new copy of the source mount tree is created from the previous copy of the source mount tree. This will become important later.

The peer loop in propagate_mnt() is straightforward. We iterate through the peers copying and updating @last_source and @last_dest as we go through them and mount each copy of the source mount tree @child on a peer @m in @dest_mnt's peer group.

After propagate_mnt() handled the peers in @dest_mnt's peer group propagate_mnt() will propagate the source mount tree down the propagation tree that @dest_mnt's peer group propagates to:

for (m = next_group(dest_mnt, dest_mnt); m;
                m = next_group(m, dest_mnt)) {
        /* everything in that slave group */
        n = m;
        do {
                ret = propagate_one(n);
                if (ret)
                        goto out;
                n = next_peer(n);
        } while (n != m);
}

The next_group() helper will recursively walk the destination propagation tree, descending into each propagation group of the propagation tree.

The important part is that it takes care to propagate the source mount tree to all peers in the peer group of a propagation group before it propagates to the slaves to those peers in the propagation group. IOW, it creates and mounts copies of the source mount tree that become masters before it creates and mounts copies of the source mount tree that become slaves to these masters.

It is important to remember that propagating the source mount tree to each mount @m in the destination propagation tree simply means that we create and mount new copies @child of the source mount tree on @m such that @child->mnt_parent points to @m.

Since we know that each node @m in the destination propagation tree headed by @dest_mnt's peer group will be overmounted with a copy of the source mount tree and since we know that the propagation properties of each copy of the source mount tree we create and mount at @m will mostly mirror the propagation properties of @m. We can use that information to create and mount the copies of the source mount tree that become masters before their slaves.

The easy case is always when @m and @last_dest are peers in a peer group of a given propagation group. In that case we know that we can simply copy @last_source without having to figure out what the master for the new copy @child of the source mount tree needs to be as we've done that in a previous call to propagate_one().

The hard case is when we're dealing with a slave mount or a shared-slave mount @m in a destination propagation group that we need to create and mount a copy of the source mount tree on.

For each propagation group in the destination propagation tree we propagate the source mount tree to we want to make sure that the copies @child of the source mount tree we create and mount on slaves @m pick an ealier copy of the source mount tree that we mounted on a master @m of the destination propagation group as their master. This is a mouthful but as far as we can tell that's the core of it all.

But, if we keep track of the masters in the destination propagation tree @m we can use the information to find the correct master for each copy of the source mount tree we create and mount at the slaves in the destination propagation tree @m.

Let's walk through the base case as that's still fairly easy to grasp.

If we're dealing with the first slave in the propagation group that @dest_mnt is in then we don't yet have marked any masters in the destination propagation tree.

We know the master for the first slave to @dest_mnt's peer group is simple @dest_mnt. So we expect this algorithm to yield a copy of the source mount tree that was mounted on a peer in @dest_mnt's peer group as the master for the copy of the source mount tree we want to mount at the first slave @m:

for (n = m; ; n = p) {
        p = n->mnt_master;
        if (p == dest_master || IS_MNT_MARKED(p))
                break;
}

For the first slave we walk the destination propagation tree all the way up to a peer in @dest_mnt's peer group. IOW, the propagation hierarchy can be walked by walking up the @mnt->mnt_master hierarchy of the destination propagation tree @m. We will ultimately find a peer in @dest_mnt's peer group and thus ultimately @dest_mnt->mnt_master.

Btw, here the assumption we listed at the beginning becomes important. Namely, that peers in a peer group pg1 that are slaves in another peer group pg2 appear on the same ->mnt_slave_list. IOW, all slaves who are peers in peer group pg1 point to the same peer in peer group pg2 via their ->mnt_master. Otherwise the termination condition in the code above would be wrong and next_group() would be broken too.

So the first iteration sets:

n = m;
p = n->mnt_master;

such that @p now points to a peer or @dest_mnt itself. We walk up one more level since we don't have any marked mounts. So we end up with:

n = dest_mnt;
p = dest_mnt->mnt_master;

If @dest_mnt's peer group is not slave to another peer group then @p is now NULL. If @dest_mnt's peer group is a slave to another peer group then @p now points to @dest_mnt->mnt_master points which is a master outside the propagation tree we're dealing with.

Now we need to figure out the master for the copy of the source mount tree we're about to create and mount on the first slave of @dest_mnt's peer group:

do {
        struct mount *parent = last_source->mnt_parent;
        if (last_source == first_source)
                break;
        done = parent->mnt_master == p;
        if (done && peers(n, parent))
                break;
        last_source = last_source->mnt_master;
} while (!done);

We know that @last_source->mnt_parent points to @last_dest and @last_dest is the last peer in @dest_mnt's peer group we propagated to in the peer loop in propagate_mnt().

Consequently, @last_source is the last copy we created and mount on that last peer in @dest_mnt's peer group. So @last_source is the master we want to pick.

We know that @last_source->mnt_parent->mnt_master points to @last_dest->mnt_master. We also know that @last_dest->mnt_master is either NULL or points to a master outside of the destination propagation tree and so does @p. Hence:

done = parent->mnt_master == p;

is trivially true in the base condition.

We also know that for the first slave mount of @dest_mnt's peer group that @last_dest either points @dest_mnt itself because it was initialized to:

last_dest = dest_mnt;

at the beginning of propagate_mnt() or it will point to a peer of @dest_mnt in its peer group. In both cases it is guaranteed that on the first iteration @n and @parent are peers (Please note the check for peers here as that's important.):

if (done && peers(n, parent))

        break;

So, as we expected, we select @last_source, which referes to the last copy of the source mount tree we mounted on the last peer in @dest_mnt's peer group, as the master of the first slave in @dest_mnt's peer group. The rest is taken care of by clone_mnt(last_source, ...). We'll skip over that part otherwise this becomes a blogpost.

At the end of propagate_mnt() we now mark @m->mnt_master as the first master in the destination propagation tree that is distinct from @dest_mnt->mnt_master. IOW, we mark @dest_mnt itself as a master.

By marking @dest_mnt or one of it's peers we are able to easily find it again when we later lookup masters for other copies of the source mount tree we mount copies of the source mount tree on slaves @m to @dest_mnt's peer group. This, in turn allows us to find the master we selected for the copies of the source mount tree we mounted on master in the destination propagation tree again.

The important part is to realize that the code makes use of the fact that the last copy of the source mount tree stashed in @last_source was mounted on top of the previous destination propagation node @last_dest. What this means is that @last_source allows us to walk the destination propagation hierarchy the same way each destination propagation node @m does.

If we take @last_source, which is the copy of @source_mnt we have mounted on @last_dest in the previous iteration of propagate_one(), then we know @last_source->mnt_parent points to @last_dest but we also know that as we walk through the destination propagation tree that @last_source->mnt_master will point to an earlier copy of the source mount tree we mounted one an earlier destination propagation node @m.

IOW, @last_source->mnt_parent will be our hook into the destination propagation tree and each consecutive @last_source->mnt_master will lead us to an earlier propagation node @m via @last_source->mnt_master->mnt_parent.

Hence, by walking up @last_source->mnt_master, each of which is mounted on a node that is a master @m in the destination propagation tree we can also walk up the destination propagation hierarchy.

So, for each new destination propagation node @m we use the previous copy of @last_source and the fact it's mounted on the previous propagation node @last_dest via @last_source->mnt_master->mnt_parent to determine what the master of the new copy of @last_source needs to be.

The goal is to find the _closest_ master that the new copy of the source mount tree we are about to create and mount on a slave @m in the destination propagation tree needs to pick. IOW, we want to find a suitable master in the propagation group.

As the propagation structure of the source mount propagation tree we create mirrors the propagation structure of the destination propagation tree we can find @m's closest master - i.e., a marked master - which is a peer in the closest peer group that @m receives propagation from. We store that closest master of @m in @p as before and record the slave to that master in @n

We then search for this master @p via @last_source by walking up the master hierarchy starting from the last copy of the source mount tree stored in @last_source that we created and mounted on the previous destination propagation node @m.

We will try to find the master by walking @last_source->mnt_master and by comparing @last_source->mnt_master->mnt_parent->mnt_master to @p. If we find @p then we can figure out what earlier copy of the source mount tree needs to be the master for the new copy of the source mount tree we're about to create and mount at the current destination propagation node @m.

If @last_source->mnt_master->mnt_parent and @n are peers then we know that the closest master they receive propagation from is @last_source->mnt_master->mnt_parent->mnt_master. If not then the closest immediate peer group that they receive propagation from must be one level higher up.

This builds on the earlier clarification at the beginning that all peers in a peer group which are slaves of other peer groups all point to the same ->mnt_master, i.e., appear on the same ->mnt_slave_list, of the closest peer group that they receive propagation from.

However, terminating the walk has corner cases.

If the closest marked master for a given destination node @m cannot be found by walking up the master hierarchy via @last_source->mnt_master then we need to terminate the walk when we encounter @source_mnt again.

This isn't an arbitrary termination. It simply means that the new copy of the source mount tree we're about to create has a copy of the source mount tree we created and mounted on a peer in @dest_mnt's peer group as its master. IOW, @source_mnt is the peer in the closest peer group that the new copy of the source mount tree receives propagation from.

We absolutely have to stop @source_mnt because @last_source->mnt_master either points outside the propagation hierarchy we're dealing with or it is NULL because @source_mnt isn't a shared-slave.

So continuing the walk past @source_mnt would cause a NULL dereference via @last_source->mnt_master->mnt_parent. And so we have to stop the walk when we encounter @source_mnt again.

One scenario where this can happen is when we first handled a series of slaves of @dest_mnt's peer group and then encounter peers in a new peer group that is a slave to @dest_mnt's peer group. We handle them and then we encounter another slave mount to @dest_mnt that is a pure slave to @dest_mnt's peer group. That pure slave will have a peer in @dest_mnt's peer group as its master. Consequently, the new copy of the source mount tree will need to have @source_mnt as it's master. So we walk the propagation hierarchy all the way up to @source_mnt based on @last_source->mnt_master.

So terminate on @source_mnt, easy peasy. Except, that the check misses something that the rest of the algorithm already handles.

If @dest_mnt has peers in it's peer group the peer loop in propagate_mnt():

for (n = next_peer(dest_mnt); n != dest_mnt; n = next_peer(n)) {
        ret = propagate_one(n);
        if (ret)
                goto out;
}

will consecutively update @last_source with each previous copy of the source mount tree we created and mounted at the previous peer in @dest_mnt's peer group. So after that loop terminates @last_source will point to whatever copy of the source mount tree was created and mounted on the last peer in @dest_mnt's peer group.

Furthermore, if there is even a single additional peer in @dest_mnt's peer group then @last_source will __not__ point to @source_mnt anymore. Because, as we mentioned above, @dest_mnt isn't even handled in this loop but directly in attach_recursive_mnt(). So it can't even accidently come last in that peer loop.

So the first time we handle a slave mount @m of @dest_mnt's peer group the copy of the source mount tree we create will make the __last copy of the source mount tree we created and mounted on the last peer in @dest_mnt's peer group the master of the new copy of the source mount tree we create and mount on the first slave of @dest_mnt's peer group__.

But this means that the termination condition that checks for @source_mnt is wrong. The @source_mnt cannot be found anymore by propagate_one(). Instead it will find the last copy of the source mount tree we created and mounted for the last peer of @dest_mnt's peer group again. And that is a peer of @source_mnt not @source_mnt itself.

IOW, we fail to terminate the loop correctly and ultimately dereference @last_source->mnt_master->mnt_parent. When @source_mnt's peer group isn't slave to another peer group then @last_source->mnt_master is NULL causing the splat below.

For example, assume @dest_mnt is a pure shared mount and has three peers in its peer group:

===================================================================================
mount-id mount-parent-id peer-group-id
===================================================================================
(@dest_mnt) mnt_master[216] 309 297 shared:216

    \
     (@source_mnt) mnt_master[218]:      609        609               shared:218

(1) mnt_master[216]: 607 605 shared:216

    \
     (P1) mnt_master[218]:               624        607               shared:218

(2) mnt_master[216]: 576 574 shared:216

    \
     (P2) mnt_master[218]:               625        576               shared:218

(3) mnt_master[216]: 545 543 shared:216

    \
     (P3) mnt_master[218]:               626        545               shared:218

After this sequence has been processed @last_source will point to (P3), the copy generated for the third peer in @dest_mnt's peer group we handled. So the copy of the source mount tree (P4) we create and mount on the first slave of @dest_mnt's peer group:

===================================================================================
mount-id mount-parent-id peer-group-id
===================================================================================
mnt_master[216] 309 297 shared:216
/
/
(S0) mnt_slave 483 481 master:216
\
\ (P3) mnt_master[218] 626 545 shared:218

    \  /
     \/
    (P4) mnt_slave                       627        483               master:218

will pick the last copy of the source mount tree (P3) as master, not (S0).

When walking the propagation hierarchy via @last_source's master hierarchy we encounter (P3) but not (S0), i.e., @source_mnt.

We can fix this in multiple ways:

(1) By setting @last_source to @source_mnt after we processed the peers in @dest_mnt's peer group right after the peer loop in propagate_mnt().

(2) By changing the termination condition that relies on finding exactly @source_mnt to finding a peer of @source_mnt.

(3) By only moving @last_source when we actually venture into a new peer group or some clever variant thereof.

The first two options are minimally invasive and what we want as a fix. The third option is more intrusive but something we'd like to explore in the near future.

This passes all LTP tests and specifically the mount propagation testsuite part of it. It also holds up against all known reproducers of this issues.

Final words.
First, this is a clever but __worringly__ underdocumented algorithm. There isn't a single detailed comment to be found in next_group(), propagate_one() or anywhere else in that file for that matter. This has been a giant pain to understand and work through and a bug like this is insanely difficult to fix without a detailed understanding of what's happening. Let's not talk about the amount of time that was sunk into fixing this.

Second, all the cool kids with access to
unshare --mount --user --map-root --propagation=unchanged are going to have a lot of fun. IOW, triggerable by unprivileged users while namespace_lock() lock is held.

[  115.848393] BUG: kernel NULL pointer dereference, address: 0000000000000010
[  115.848967] #PF: supervisor read access in kernel mode
[  115.849386] #PF: error_code(0x0000) - not-present page
[  115.849803] PGD 0 P4D 0
[  115.850012] Oops: 0000 [#1] PREEMPT SMP PTI
[  115.850354] CPU: 0 PID: 15591 Comm: mount Not tainted 6.1.0-rc7 #3
[  115.850851] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS
VirtualBox 12/01/2006
[  115.851510] RIP: 0010:propagate_one.part.0+0x7f/0x1a0
[  115.851924] Code: 75 eb 4c 8b 05 c2 25 37 02 4c 89 ca 48 8b 4a 10
49 39 d0 74 1e 48 3b 81 e0 00 00 00 74 26 48 8b 92 e0 00 00 00 be 01
00 00 00 <48> 8b 4a 10 49 39 d0 75 e2 40 84 f6 74 38 4c 89 05 84 25 37
02 4d
[  115.853441] RSP: 0018:ffffb8d5443d7d50 EFLAGS: 00010282
[  115.853865] RAX: ffff8e4d87c41c80 RBX: ffff8e4d88ded780 RCX: ffff8e4da4333a00
[  115.854458] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8e4d88ded780
[  115.855044] RBP: ffff8e4d88ded780 R08: ffff8e4da4338000 R09: ffff8e4da43388c0
[  115.855693] R10: 0000000000000002 R11: ffffb8d540158000 R12: ffffb8d5443d7da8
[  115.856304] R13: ffff8e4d88ded780 R14: 0000000000000000 R15: 0000000000000000
[  115.856859] FS:  00007f92c90c9800(0000) GS:ffff8e4dfdc00000(0000)
knlGS:0000000000000000
[  115.857531] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  115.858006] CR2: 0000000000000010 CR3: 0000000022f4c002 CR4: 00000000000706f0
[  115.858598] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  115.859393] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[  115.860099] Call Trace:
[  115.860358]  <TASK>
[  115.860535]  propagate_mnt+0x14d/0x190
[  115.860848]  attach_recursive_mnt+0x274/0x3e0
[  115.861212]  path_mount+0x8c8/0xa60
[  115.861503]  __x64_sys_mount+0xf6/0x140
[  115.861819]  do_syscall_64+0x5b/0x80
[  115.862117]  ? do_faccessat+0x123/0x250
[  115.862435]  ? syscall_exit_to_user_mode+0x17/0x40
[  115.862826]  ? do_syscall_64+0x67/0x80
[  115.863133]  ? syscall_exit_to_user_mode+0x17/0x40
[  115.863527]  ? do_syscall_64+0x67/0x80
[  115.863835]  ? do_syscall_64+0x67/0x80
[  115.864144]  ? do_syscall_64+0x67/0x80
[  115.864452]  ? exc_page_fault+0x70/0x170
[  115.864775]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
[  115.865187] RIP: 0033:0x7f92c92b0ebe
[  115.865480] Code: 48 8b 0d 75 4f 0c 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 49 89 ca b8 a5 00 00
00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 42 4f 0c 00 f7 d8 64 89
01 48
[  115.866984] RSP: 002b:00007fff000aa728 EFLAGS: 00000246 ORIG_RAX:
00000000000000a5
[  115.867607] RAX: ffffffffffffffda RBX: 000055a77888d6b0 RCX: 00007f92c92b0ebe
[  115.868240] RDX: 000055a77888d8e0 RSI: 000055a77888e6e0 RDI: 000055a77888e620
[  115.868823] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000001
[  115.869403] R10: 0000000000001000 R11: 0000000000000246 R12: 000055a77888e620
[  115.869994] R13: 000055a77888d8e0 R14: 00000000ffffffff R15: 00007f92c93e4076
[  115.870581]  </TASK>
[  115.870763] Modules linked in: nft_fib_inet nft_fib_ipv4

nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set rfkill nf_tables nfnetlink qrtr snd_intel8x0 sunrpc snd_ac97_codec ac97_bus snd_pcm snd_timer intel_rapl_msr intel_rapl_common snd vboxguest intel_powerclamp video rapl joydev soundcore i2c_piix4 wmi fuse zram xfs vmwgfx crct10dif_pclmul crc32_pclmul crc32c_intel polyval_clmulni polyval_generic drm_ttm_helper ttm e1000 ghash_clmulni_intel serio_raw ata_generic pata_acpi scsi_dh_rdac scsi_dh_emc scsi_dh_alua dm_multipath

[  115.875288] CR2: 0000000000000010
[  115.875641] ---[ end trace 0000000000000000 ]---
[  115.876135] RIP: 0010:propagate_one.part.0+0x7f/0x1a0
[  115.876551] Code: 75 eb 4c 8b 05 c2 25 37 02 4c 89 ca 48 8b 4a 10
49 39 d0 74 1e 48 3b 81 e0 00 00 00 74 26 48 8b 92 e0 00 00 00 be 01
00 00 00 <48> 8b 4a 10 49 39 d0 75 e2 40 84 f6 74 38 4c 89 05 84 25 37
02 4d
[  115.878086] RSP: 0018:ffffb8d5443d7d50 EFLAGS: 00010282
[  115.878511] RAX: ffff8e4d87c41c80 RBX: ffff8e4d88ded780 RCX: ffff8e4da4333a00
[  115.879128] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8e4d88ded780
[  115.879715] RBP: ffff8e4d88ded780 R08: ffff8e4da4338000 R09: ffff8e4da43388c0
[  115.880359] R10: 0000000000000002 R11: ffffb8d540158000 R12: ffffb8d5443d7da8
[  115.880962] R13: ffff8e4d88ded780 R14: 0000000000000000 R15: 0000000000000000
[  115.881548] FS:  00007f92c90c9800(0000) GS:ffff8e4dfdc00000(0000)
knlGS:0000000000000000
[  115.882234] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  115.882713] CR2: 0000000000000010 CR3: 0000000022f4c002 CR4: 00000000000706f0
[  115.883314] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  115.883966] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Fixes f2ebb3a921c1 ("smarter propagate_mnt()")
Fixes 5ec0811d3037 ("propogate_mnt: Handle the first propogated copy being a slave")

---
If there are no big objections I'll get this to Linus rather sooner than later.

---
 fs/pnode.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/pnode.c +1 -1
@@ -244,7 +244,7 @@ static int propagate_one(struct mount *m
 		}
 		do {
 			struct mount *parent = last_source->mnt_parent;
-			if (last_source == first_source)
+			if (peers(last_source, first_source))
 				break;
 			done = parent->mnt_master == p;
 			if (done && peers(n, parent))
author maintainer
#44 lore raw

PATCH 44/290 mfd: mt6360: Add bounds checking in Regmap read/write call-backs

In reply to Greg Kroah-Hartman

From: ChiYuan Huang <[email protected]>

commit 5f4f94e9f26cca6514474b307b59348b8485e711 upstream.

Fix the potential risk of OOB read if bank index is over the maximum.

Refer to the discussion list for the experiment result on mt6370.
https://lore.kernel.org/all/[email protected]/
If not to check the bound, there is the same issue on mt6360.

Fixes 3b0850440a06c (mfd: mt6360: Merge different sub-devices I2C read/write)
---
 drivers/mfd/mt6360-core.c |   14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/mfd/mt6360-core.c +12 -2
@@ -402,7 +402,7 @@ static int mt6360_regmap_read(void *cont
 	struct mt6360_ddata *ddata = context;
 	u8 bank = *(u8 *)reg;
 	u8 reg_addr = *(u8 *)(reg + 1);
-	struct i2c_client *i2c = ddata->i2c[bank];
+	struct i2c_client *i2c;
 	bool crc_needed = false;
 	u8 *buf;
 	int buf_len = MT6360_ALLOC_READ_SIZE(val_size);
@@ -410,6 +410,11 @@ static int mt6360_regmap_read(void *cont
 	u8 crc;
 	int ret;
 
+	if (bank >= MT6360_SLAVE_MAX)
+		return -EINVAL;
+
+	i2c = ddata->i2c[bank];
+
 	if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
 		crc_needed = true;
 		ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size);
@@ -453,13 +458,18 @@ static int mt6360_regmap_write(void *con
 	struct mt6360_ddata *ddata = context;
 	u8 bank = *(u8 *)val;
 	u8 reg_addr = *(u8 *)(val + 1);
-	struct i2c_client *i2c = ddata->i2c[bank];
+	struct i2c_client *i2c;
 	bool crc_needed = false;
 	u8 *buf;
 	int buf_len = MT6360_ALLOC_WRITE_SIZE(val_size);
 	int write_size = val_size - MT6360_REGMAP_REG_BYTE_SIZE;
 	int ret;
 
+	if (bank >= MT6360_SLAVE_MAX)
+		return -EINVAL;
+
+	i2c = ddata->i2c[bank];
+
 	if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) {
 		crc_needed = true;
 		ret = mt6360_xlate_pmicldo_addr(&reg_addr, val_size - MT6360_REGMAP_REG_BYTE_SIZE);
author maintainer
#45 lore raw

PATCH 45/290 md: fix a crash in mempool_free

In reply to Greg Kroah-Hartman

From: Mikulas Patocka <[email protected]>

commit 341097ee53573e06ab9fc675d96a052385b851fa upstream.

There's a crash in mempool_free when running the lvm test shell/lvchange-rebuild-raid.sh.

The reason for the crash is this:
* super_written calls atomic_dec_and_test(&mddev->pending_writes) and wake_up(&mddev->sb_wait). Then it calls rdev_dec_pending(rdev, mddev) and bio_put(bio).
* so, the process that waited on sb_wait and that is woken up is racing with bio_put(bio).
* if the process wins the race, it calls bioset_exit before bio_put(bio) is executed.
* bio_put(bio) attempts to free a bio into a destroyed bio set - causing a crash in mempool_free.

We fix this bug by moving bio_put before atomic_dec_and_test.

We also move rdev_dec_pending before atomic_dec_and_test as suggested by Neil Brown.

The function md_end_flush has a similar bug - we must call bio_put before we decrement the number of in-progress bios.

 BUG: kernel NULL pointer dereference, address: 0000000000000000
 #PF: supervisor write access in kernel mode
 #PF: error_code(0x0002) - not-present page
 PGD 11557f0067 P4D 11557f0067 PUD 0
 Oops: 0002 [#1] PREEMPT SMP
 CPU: 0 PID: 73 Comm: kworker/0:1 Not tainted 6.1.0-rc3 #5
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
 Workqueue: kdelayd flush_expired_bios [dm_delay]
 RIP: 0010:mempool_free+0x47/0x80
 Code: 48 89 ef 5b 5d ff e0 f3 c3 48 89 f7 e8 32 45 3f 00 48 63 53 08 48 89 c6 3b 53 04 7d 2d 48 8b 43 10 8d 4a 01 48 89 df 89 4b 08 <48> 89 2c d0 e8 b0 45 3f 00 48 8d 7b 30 5b 5d 31 c9 ba 01 00 00 00
 RSP: 0018:ffff88910036bda8 EFLAGS: 00010093
 RAX: 0000000000000000 RBX: ffff8891037b65d8 RCX: 0000000000000001
 RDX: 0000000000000000 RSI: 0000000000000202 RDI: ffff8891037b65d8
 RBP: ffff8891447ba240 R08: 0000000000012908 R09: 00000000003d0900
 R10: 0000000000000000 R11: 0000000000173544 R12: ffff889101a14000
 R13: ffff8891562ac300 R14: ffff889102b41440 R15: ffffe8ffffa00d05
 FS:  0000000000000000(0000) GS:ffff88942fa00000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 0000000000000000 CR3: 0000001102e99000 CR4: 00000000000006b0
 Call Trace:
  <TASK>
  clone_endio+0xf4/0x1c0 [dm_mod]
  clone_endio+0xf4/0x1c0 [dm_mod]
  __submit_bio+0x76/0x120
  submit_bio_noacct_nocheck+0xb6/0x2a0
  flush_expired_bios+0x28/0x2f [dm_delay]
  process_one_work+0x1b4/0x300
  worker_thread+0x45/0x3e0
  ? rescuer_thread+0x380/0x380
  kthread+0xc2/0x100
  ? kthread_complete_and_exit+0x20/0x20
  ret_from_fork+0x1f/0x30
  </TASK>
 Modules linked in: brd dm_delay dm_raid dm_mod af_packet uvesafb cfbfillrect cfbimgblt cn cfbcopyarea fb font fbdev tun autofs4 binfmt_misc configfs ipv6 virtio_rng virtio_balloon rng_core virtio_net pcspkr net_failover failover qemu_fw_cfg button mousedev raid10 raid456 libcrc32c async_raid6_recov async_memcpy async_pq raid6_pq async_xor xor async_tx raid1 raid0 md_mod sd_mod t10_pi crc64_rocksoft crc64 virtio_scsi scsi_mod evdev psmouse bsg scsi_common [last unloaded: brd]
 CR2: 0000000000000000
 ---[ end trace 0000000000000000 ]---
---
 drivers/md/md.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/md/md.c +6 -3
@@ -526,13 +526,14 @@ static void md_end_flush(struct bio *bio
 	struct md_rdev *rdev = bio->bi_private;
 	struct mddev *mddev = rdev->mddev;
 
+	bio_put(bio);
+
 	rdev_dec_pending(rdev, mddev);
 
 	if (atomic_dec_and_test(&mddev->flush_pending)) {
 		/* The pre-request flush has finished */
 		queue_work(md_wq, &mddev->flush_work);
 	}
-	bio_put(bio);
 }
 
 static void md_submit_flush_data(struct work_struct *ws);
@@ -935,10 +936,12 @@ static void super_written(struct bio *bi
 	} else
 		clear_bit(LastDev, &rdev->flags);
 
+	bio_put(bio);
+
+	rdev_dec_pending(rdev, mddev);
+
 	if (atomic_dec_and_test(&mddev->pending_writes))
 		wake_up(&mddev->sb_wait);
-	rdev_dec_pending(rdev, mddev);
-	bio_put(bio);
 }
 
 void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
author maintainer
#46 lore raw

PATCH 46/290 mm, compaction: fix fast_isolate_around() to stay within boundaries

In reply to Greg Kroah-Hartman

From: NARIBAYASHI Akira <[email protected]>

commit be21b32afe470c5ae98e27e49201158a47032942 upstream.

Depending on the memory configuration, isolate_freepages_block() may scan pages out of the target range and causes panic.

Panic can occur on systems with multiple zones in a single pageblock.

The reason it is rare is that it only happens in special configurations. Depending on how many similar systems there are, it may be a good idea to fix this problem for older kernels as well.

The problem is that pfn as argument of fast_isolate_around() could be out of the target range. Therefore we should consider the case where pfn < start_pfn, and also the case where end_pfn < pfn.

This problem should have been addressd by the commit 6e2b7044c199 ("mm,
compaction: make fast_isolate_freepages() stay within zone") but there was an oversight.

Case1: pfn < start_pfn

<at memory compaction for node Y>

  |  node X's zone  | node Y's zone
  +-----------------+------------------------------...
   pageblock    ^   ^     ^
  +-----------+-----------+-----------+-----------+...
                ^   ^     ^
                ^   ^      end_pfn
                ^    start_pfn = cc->zone->zone_start_pfn
                 pfn
                <---------> scanned range by "Scan After"

Case2: end_pfn < pfn

<at memory compaction for node X>

  |  node X's zone  | node Y's zone
  +-----------------+------------------------------...
   pageblock  ^     ^   ^
  +-----------+-----------+-----------+-----------+...
              ^     ^   ^
              ^     ^    pfn
              ^      end_pfn
               start_pfn
              <---------> scanned range by "Scan Before"

It seems that there is no good reason to skip nr_isolated pages just after given pfn. So let perform simple scan from start to end instead of dividing the scan into "Before" and "After".

Fixes 6e2b7044c199 ("mm, compaction: make fast_isolate_freepages() stay within zone").
Cc David Rientjes <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Vlastimil Babka <[email protected]>
---
 mm/compaction.c |   18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)
mm/compaction.c +5 -13
@@ -1350,7 +1350,7 @@ move_freelist_tail(struct list_head *fre
 }
 
 static void
-fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsigned long nr_isolated)
+fast_isolate_around(struct compact_control *cc, unsigned long pfn)
 {
 	unsigned long start_pfn, end_pfn;
 	struct page *page;
@@ -1371,21 +1371,13 @@ fast_isolate_around(struct compact_contr
 	if (!page)
 		return;
 
-	/* Scan before */
-	if (start_pfn != pfn) {
-		isolate_freepages_block(cc, &start_pfn, pfn, &cc->freepages, 1, false);
-		if (cc->nr_freepages >= cc->nr_migratepages)
-			return;
-	}
-
-	/* Scan after */
-	start_pfn = pfn + nr_isolated;
-	if (start_pfn < end_pfn)
-		isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
+	isolate_freepages_block(cc, &start_pfn, end_pfn, &cc->freepages, 1, false);
 
 	/* Skip this pageblock in the future as it's full or nearly full */
 	if (cc->nr_freepages < cc->nr_migratepages)
 		set_pageblock_skip(page);
+
+	return;
 }
 
 /* Search orders in round-robin fashion */
@@ -1561,7 +1553,7 @@ fast_isolate_freepages(struct compact_co
 		return cc->free_pfn;
 
 	low_pfn = page_to_pfn(page);
-	fast_isolate_around(cc, low_pfn, nr_isolated);
+	fast_isolate_around(cc, low_pfn);
 	return low_pfn;
 }
 
author maintainer
#47 lore raw

PATCH 47/290 f2fs: should put a page when checking the summary info

In reply to Greg Kroah-Hartman

From: Pavel Machek <[email protected]>

commit c3db3c2fd9992c08f49aa93752d3c103c3a4f6aa upstream.

The commit introduces another bug.

Fixes c6ad7fd16657e ("f2fs: fix to do sanity check on summary info")
---
 fs/f2fs/gc.c |    1 +
 1 file changed, 1 insertion(+)
fs/f2fs/gc.c +1 -0
@@ -1033,6 +1033,7 @@ static bool is_alive(struct f2fs_sb_info
 	if (ofs_in_node >= max_addrs) {
 		f2fs_err(sbi, "Inconsistent ofs_in_node:%u in summary, ino:%u, nid:%u, max:%u",
 			ofs_in_node, dni->ino, dni->nid, max_addrs);
+		f2fs_put_page(node_page, 1);
 		return false;
 	}
 
author maintainer
#48 lore raw

PATCH 48/290 f2fs: allow to read node block after shutdown

In reply to Greg Kroah-Hartman

From: Jaegeuk Kim <[email protected]>

commit e6ecb142429183cef4835f31d4134050ae660032 upstream.

If block address is still alive, we should give a valid node block even after shutdown. Otherwise, we can see zero data when reading out a file.

Fixes 83a3bfdb5a8a ("f2fs: indicate shutdown f2fs to allow unmount successfully")
---
 fs/f2fs/node.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
fs/f2fs/node.c +1 -2
@@ -1357,8 +1357,7 @@ static int read_node_page(struct page *p
 		return err;
 
 	/* NEW_ADDR can be seen, after cp_error drops some dirty node pages */
-	if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR) ||
-			is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)) {
+	if (unlikely(ni.blk_addr == NULL_ADDR || ni.blk_addr == NEW_ADDR)) {
 		ClearPageUptodate(page);
 		return -ENOENT;
 	}
author maintainer
#49 lore raw

PATCH 49/290 mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING

In reply to Greg Kroah-Hartman

From: Deren Wu <[email protected]>

commit 4a44cd249604e29e7b90ae796d7692f5773dd348 upstream.

vub300_enable_sdio_irq() works with mutex and need TASK_RUNNING here. Ensure that we mark current as TASK_RUNNING for sleepable context.

[   77.554641] do not call blocking ops when !TASK_RUNNING; state=1 set at [<ffffffff92a72c1d>] sdio_irq_thread+0x17d/0x5b0
[   77.554652] WARNING: CPU: 2 PID: 1983 at kernel/sched/core.c:9813 __might_sleep+0x116/0x160
[   77.554905] CPU: 2 PID: 1983 Comm: ksdioirqd/mmc1 Tainted: G           OE      6.1.0-rc5 #1
[   77.554910] Hardware name: Intel(R) Client Systems NUC8i7BEH/NUC8BEB, BIOS BECFL357.86A.0081.2020.0504.1834 05/04/2020
[   77.554912] RIP: 0010:__might_sleep+0x116/0x160
[   77.554920] RSP: 0018:ffff888107b7fdb8 EFLAGS: 00010282
[   77.554923] RAX: 0000000000000000 RBX: ffff888118c1b740 RCX: 0000000000000000
[   77.554926] RDX: 0000000000000001 RSI: 0000000000000004 RDI: ffffed1020f6ffa9
[   77.554928] RBP: ffff888107b7fde0 R08: 0000000000000001 R09: ffffed1043ea60ba
[   77.554930] R10: ffff88821f5305cb R11: ffffed1043ea60b9 R12: ffffffff93aa3a60
[   77.554932] R13: 000000000000011b R14: 7fffffffffffffff R15: ffffffffc0558660
[   77.554934] FS:  0000000000000000(0000) GS:ffff88821f500000(0000) knlGS:0000000000000000
[   77.554937] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.554939] CR2: 00007f8a44010d68 CR3: 000000024421a003 CR4: 00000000003706e0
[   77.554942] Call Trace:
[   77.554944]  <TASK>
[   77.554952]  mutex_lock+0x78/0xf0
[   77.554973]  vub300_enable_sdio_irq+0x103/0x3c0 [vub300]
[   77.554981]  sdio_irq_thread+0x25c/0x5b0
[   77.555006]  kthread+0x2b8/0x370
[   77.555017]  ret_from_fork+0x1f/0x30
[   77.555023]  </TASK>
[   77.555025] ---[ end trace 0000000000000000 ]---
---
 drivers/mmc/host/vub300.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/mmc/host/vub300.c +2 -0
@@ -2049,6 +2049,7 @@ static void vub300_enable_sdio_irq(struc
 		return;
 	kref_get(&vub300->kref);
 	if (enable) {
+		set_current_state(TASK_RUNNING);
 		mutex_lock(&vub300->irq_mutex);
 		if (vub300->irqs_queued) {
 			vub300->irqs_queued -= 1;
@@ -2064,6 +2065,7 @@ static void vub300_enable_sdio_irq(struc
 			vub300_queue_poll_work(vub300, 0);
 		}
 		mutex_unlock(&vub300->irq_mutex);
+		set_current_state(TASK_INTERRUPTIBLE);
 	} else {
 		vub300->irq_enabled = 0;
 	}
author maintainer
#50 lore raw

PATCH 50/290 tpm: acpi: Call acpi_put_table() to fix memory leak

In reply to Greg Kroah-Hartman

From: Hanjun Guo <[email protected]>

commit 8740a12ca2e2959531ad253bac99ada338b33d80 upstream.

The start and length of the event log area are obtained from TPM2 or TCPA table, so we call acpi_get_table() to get the ACPI information, but the acpi_get_table() should be coupled with acpi_put_table() to release the ACPI memory, add the acpi_put_table() properly to fix the memory leak.

While we are at it, remove the redundant empty line at the end of the tpm_read_log_acpi().

Fixes 0bfb23746052 ("tpm: Move eventlog files to a subdirectory")
Fixes 85467f63a05c ("tpm: Add support for event log pointer found in TPM2 ACPI table")
---
 drivers/char/tpm/eventlog/acpi.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/char/tpm/eventlog/acpi.c +9 -3
@@ -90,16 +90,21 @@ int tpm_read_log_acpi(struct tpm_chip *c
 			return -ENODEV;
 
 		if (tbl->header.length <
-				sizeof(*tbl) + sizeof(struct acpi_tpm2_phy))
+				sizeof(*tbl) + sizeof(struct acpi_tpm2_phy)) {
+			acpi_put_table((struct acpi_table_header *)tbl);
 			return -ENODEV;
+		}
 
 		tpm2_phy = (void *)tbl + sizeof(*tbl);
 		len = tpm2_phy->log_area_minimum_length;
 
 		start = tpm2_phy->log_area_start_address;
-		if (!start || !len)
+		if (!start || !len) {
+			acpi_put_table((struct acpi_table_header *)tbl);
 			return -ENODEV;
+		}
 
+		acpi_put_table((struct acpi_table_header *)tbl);
 		format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
 	} else {
 		/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
@@ -120,8 +125,10 @@ int tpm_read_log_acpi(struct tpm_chip *c
 			break;
 		}
 
+		acpi_put_table((struct acpi_table_header *)buff);
 		format = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
 	}
+
 	if (!len) {
 		dev_warn(&chip->dev, "%s: TCPA log area empty\n", __func__);
 		return -EIO;
@@ -156,5 +163,4 @@ err:
 	kfree(log->bios_event_log);
 	log->bios_event_log = NULL;
 	return ret;
-
 }
author maintainer
#51 lore raw

PATCH 51/290 tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak

In reply to Greg Kroah-Hartman

From: Hanjun Guo <[email protected]>

commit 37e90c374dd11cf4919c51e847c6d6ced0abc555 upstream.

In crb_acpi_add(), we get the TPM2 table to retrieve information like start method, and then assign them to the priv data, so the TPM2 table is not used after the init, should be freed, call acpi_put_table() to fix the memory leak.

---
 drivers/char/tpm/tpm_crb.c |   29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)
drivers/char/tpm/tpm_crb.c +20 -9
@@ -676,12 +676,16 @@ static int crb_acpi_add(struct acpi_devi
 
 	/* Should the FIFO driver handle this? */
 	sm = buf->start_method;
-	if (sm == ACPI_TPM2_MEMORY_MAPPED)
-		return -ENODEV;
+	if (sm == ACPI_TPM2_MEMORY_MAPPED) {
+		rc = -ENODEV;
+		goto out;
+	}
 
 	priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
+	if (!priv) {
+		rc = -ENOMEM;
+		goto out;
+	}
 
 	if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) {
 		if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) {
@@ -689,7 +693,8 @@ static int crb_acpi_add(struct acpi_devi
 				FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n",
 				buf->header.length,
 				ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC);
-			return -EINVAL;
+			rc = -EINVAL;
+			goto out;
 		}
 		crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf));
 		priv->smc_func_id = crb_smc->smc_func_id;
@@ -700,17 +705,23 @@ static int crb_acpi_add(struct acpi_devi
 
 	rc = crb_map_io(device, priv, buf);
 	if (rc)
-		return rc;
+		goto out;
 
 	chip = tpmm_chip_alloc(dev, &tpm_crb);
-	if (IS_ERR(chip))
-		return PTR_ERR(chip);
+	if (IS_ERR(chip)) {
+		rc = PTR_ERR(chip);
+		goto out;
+	}
 
 	dev_set_drvdata(&chip->dev, priv);
 	chip->acpi_dev_handle = device->handle;
 	chip->flags = TPM_CHIP_FLAG_TPM2;
 
-	return tpm_chip_register(chip);
+	rc = tpm_chip_register(chip);
+
+out:
+	acpi_put_table((struct acpi_table_header *)buf);
+	return rc;
 }
 
 static int crb_acpi_remove(struct acpi_device *device)
author maintainer
#52 lore raw

PATCH 52/290 tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak

In reply to Greg Kroah-Hartman

From: Hanjun Guo <[email protected]>

commit db9622f762104459ff87ecdf885cc42c18053fd9 upstream.

In check_acpi_tpm2(), we get the TPM2 table just to make sure the table is there, not used after the init, so the acpi_put_table() should be added to release the ACPI memory.

Fixes 4cb586a188d4 ("tpm_tis: Consolidate the platform and acpi probe flow")
---
 drivers/char/tpm/tpm_tis.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/char/tpm/tpm_tis.c +5 -4
@@ -125,6 +125,7 @@ static int check_acpi_tpm2(struct device
 	const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev);
 	struct acpi_table_tpm2 *tbl;
 	acpi_status st;
+	int ret = 0;
 
 	if (!aid || aid->driver_data != DEVICE_IS_TPM2)
 		return 0;
@@ -132,8 +133,7 @@ static int check_acpi_tpm2(struct device
 	/* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2
 	 * table is mandatory
 	 */
-	st =
-	    acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
+	st = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl);
 	if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) {
 		dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n");
 		return -EINVAL;
@@ -141,9 +141,10 @@ static int check_acpi_tpm2(struct device
 
 	/* The tpm2_crb driver handles this device */
 	if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED)
-		return -ENODEV;
+		ret = -ENODEV;
 
-	return 0;
+	acpi_put_table((struct acpi_table_header *)tbl);
+	return ret;
 }
 #else
 static int check_acpi_tpm2(struct device *dev)
author maintainer
#53 lore raw

PATCH 53/290 SUNRPC: Dont leak netobj memory when gss_read_proxy_verf() fails

In reply to Greg Kroah-Hartman

From: Chuck Lever <[email protected]>

commit da522b5fe1a5f8b7c20a0023e87b52a150e53bf5 upstream.

Fixes 030d794bf498 ("SUNRPC: Use gssproxy upcall for server RPCGSS authentication.")
---
 net/sunrpc/auth_gss/svcauth_gss.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
net/sunrpc/auth_gss/svcauth_gss.c +7 -2
@@ -1162,18 +1162,23 @@ static int gss_read_proxy_verf(struct sv
 		return res;
 
 	inlen = svc_getnl(argv);
-	if (inlen > (argv->iov_len + rqstp->rq_arg.page_len))
+	if (inlen > (argv->iov_len + rqstp->rq_arg.page_len)) {
+		kfree(in_handle->data);
 		return SVC_DENIED;
+	}
 
 	pages = DIV_ROUND_UP(inlen, PAGE_SIZE);
 	in_token->pages = kcalloc(pages, sizeof(struct page *), GFP_KERNEL);
-	if (!in_token->pages)
+	if (!in_token->pages) {
+		kfree(in_handle->data);
 		return SVC_DENIED;
+	}
 	in_token->page_base = 0;
 	in_token->page_len = inlen;
 	for (i = 0; i < pages; i++) {
 		in_token->pages[i] = alloc_page(GFP_KERNEL);
 		if (!in_token->pages[i]) {
+			kfree(in_handle->data);
 			gss_free_in_token_pages(in_token);
 			return SVC_DENIED;
 		}
author maintainer
#54 lore raw

PATCH 54/290 kcsan: Instrument memcpy/memset/memmove with newer Clang

In reply to Greg Kroah-Hartman

From: Marco Elver <[email protected]>

commit 7c201739beef1a586d806463f1465429cdce34c5 upstream.

With Clang version 16+, -fsanitize=thread will turn memcpy/memset/memmove calls in instrumented functions into __tsan_memcpy/__tsan_memset/__tsan_memmove calls respectively.

Add these functions to the core KCSAN runtime, so that we (a) catch data races with mem* functions, and (b) won't run into linker errors with such newer compilers.

Cc [email protected] # v5.10+
[ [email protected]: adjust check_access() call for v5.15 and earlier. ]
---
 kernel/kcsan/core.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
kernel/kcsan/core.c +50 -0
@@ -14,10 +14,12 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/minmax.h>
 #include <linux/moduleparam.h>
 #include <linux/percpu.h>
 #include <linux/preempt.h>
 #include <linux/sched.h>
+#include <linux/string.h>
 #include <linux/uaccess.h>
 
 #include "encoding.h"
@@ -1060,3 +1062,51 @@ EXPORT_SYMBOL(__tsan_atomic_thread_fence
 void __tsan_atomic_signal_fence(int memorder);
 void __tsan_atomic_signal_fence(int memorder) { }
 EXPORT_SYMBOL(__tsan_atomic_signal_fence);
+
+#ifdef __HAVE_ARCH_MEMSET
+void *__tsan_memset(void *s, int c, size_t count);
+noinline void *__tsan_memset(void *s, int c, size_t count)
+{
+	/*
+	 * Instead of not setting up watchpoints where accessed size is greater
+	 * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE.
+	 */
+	size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE);
+
+	check_access(s, check_len, KCSAN_ACCESS_WRITE);
+	return memset(s, c, count);
+}
+#else
+void *__tsan_memset(void *s, int c, size_t count) __alias(memset);
+#endif
+EXPORT_SYMBOL(__tsan_memset);
+
+#ifdef __HAVE_ARCH_MEMMOVE
+void *__tsan_memmove(void *dst, const void *src, size_t len);
+noinline void *__tsan_memmove(void *dst, const void *src, size_t len)
+{
+	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
+
+	check_access(dst, check_len, KCSAN_ACCESS_WRITE);
+	check_access(src, check_len, 0);
+	return memmove(dst, src, len);
+}
+#else
+void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove);
+#endif
+EXPORT_SYMBOL(__tsan_memmove);
+
+#ifdef __HAVE_ARCH_MEMCPY
+void *__tsan_memcpy(void *dst, const void *src, size_t len);
+noinline void *__tsan_memcpy(void *dst, const void *src, size_t len)
+{
+	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);
+
+	check_access(dst, check_len, KCSAN_ACCESS_WRITE);
+	check_access(src, check_len, 0);
+	return memcpy(dst, src, len);
+}
+#else
+void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy);
+#endif
+EXPORT_SYMBOL(__tsan_memcpy);
author maintainer
#55 lore raw

PATCH 55/290 ASoC: Intel/SOF: use set_stream() instead of set_tdm_slots() for HDAudio

In reply to Greg Kroah-Hartman

From: Pierre-Louis Bossart <[email protected]>

commit 636110411ca726f19ef8e87b0be51bb9a4cdef06 upstream.

Overloading the tx_mask with a linear value is asking for trouble and only works because the codec_dai hw_params() is called before the cpu_dai hw_params().

Move to the more generic set_stream() API to pass the hdac_stream information.

---
 sound/soc/codecs/hdac_hda.c       |   22 +++++++++++-----------
 sound/soc/intel/skylake/skl-pcm.c |    7 ++-----
 sound/soc/sof/intel/hda-dai.c     |    7 ++-----
 3 files changed, 15 insertions(+), 21 deletions(-)
sound/soc/codecs/hdac_hda.c +11 -11
@@ -46,9 +46,8 @@ static int hdac_hda_dai_hw_params(struct
 				  struct snd_soc_dai *dai);
 static int hdac_hda_dai_hw_free(struct snd_pcm_substream *substream,
 				struct snd_soc_dai *dai);
-static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai,
-				     unsigned int tx_mask, unsigned int rx_mask,
-				     int slots, int slot_width);
+static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai, void *stream,
+				   int direction);
 static struct hda_pcm *snd_soc_find_pcm_from_dai(struct hdac_hda_priv *hda_pvt,
 						 struct snd_soc_dai *dai);
 
@@ -58,7 +57,7 @@ static const struct snd_soc_dai_ops hdac
 	.prepare = hdac_hda_dai_prepare,
 	.hw_params = hdac_hda_dai_hw_params,
 	.hw_free = hdac_hda_dai_hw_free,
-	.set_tdm_slot = hdac_hda_dai_set_tdm_slot,
+	.set_stream = hdac_hda_dai_set_stream,
 };
 
 static struct snd_soc_dai_driver hdac_hda_dais[] = {
@@ -180,21 +179,22 @@ static struct snd_soc_dai_driver hdac_hd
 
 };
 
-static int hdac_hda_dai_set_tdm_slot(struct snd_soc_dai *dai,
-				     unsigned int tx_mask, unsigned int rx_mask,
-				     int slots, int slot_width)
+static int hdac_hda_dai_set_stream(struct snd_soc_dai *dai,
+				   void *stream, int direction)
 {
 	struct snd_soc_component *component = dai->component;
 	struct hdac_hda_priv *hda_pvt;
 	struct hdac_hda_pcm *pcm;
+	struct hdac_stream *hstream;
+
+	if (!stream)
+		return -EINVAL;
 
 	hda_pvt = snd_soc_component_get_drvdata(component);
 	pcm = &hda_pvt->pcm[dai->id];
+	hstream = (struct hdac_stream *)stream;
 
-	if (tx_mask)
-		pcm->stream_tag[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
-	else
-		pcm->stream_tag[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
+	pcm->stream_tag[direction] = hstream->stream_tag;
 
 	return 0;
 }
sound/soc/intel/skylake/skl-pcm.c +2 -5
@@ -562,11 +562,8 @@ static int skl_link_hw_params(struct snd
 
 	stream_tag = hdac_stream(link_dev)->stream_tag;
 
-	/* set the stream tag in the codec dai dma params  */
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		snd_soc_dai_set_tdm_slot(codec_dai, stream_tag, 0, 0, 0);
-	else
-		snd_soc_dai_set_tdm_slot(codec_dai, 0, stream_tag, 0, 0);
+	/* set the hdac_stream in the codec dai */
+	snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream);
 
 	p_params.s_fmt = snd_pcm_format_width(params_format(params));
 	p_params.ch = params_channels(params);
sound/soc/sof/intel/hda-dai.c +2 -5
@@ -236,11 +236,8 @@ static int hda_link_hw_params(struct snd
 	if (!link)
 		return -EINVAL;
 
-	/* set the stream tag in the codec dai dma params */
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		snd_soc_dai_set_tdm_slot(codec_dai, stream_tag, 0, 0, 0);
-	else
-		snd_soc_dai_set_tdm_slot(codec_dai, 0, stream_tag, 0, 0);
+	/* set the hdac_stream in the codec dai */
+	snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream);
 
 	p_params.s_fmt = snd_pcm_format_width(params_format(params));
 	p_params.ch = params_channels(params);
author maintainer
#56 lore raw

PATCH 56/290 ASoC/SoundWire: dai: expand stream concept beyond SoundWire

In reply to Greg Kroah-Hartman

From: Pierre-Louis Bossart <[email protected]>

commit e8444560b4d9302a511f0996f4cfdf85b628f4ca upstream.

The HDAudio ASoC support relies on the set_tdm_slots() helper to store the HDaudio stream tag in the tx_mask. This only works because of the pre-existing order in soc-pcm.c, where the hw_params() is handled for codec_dais *before* cpu_dais. When the order is reversed, the stream_tag is used as a mask in the codec fixup functions:

	/* fixup params based on TDM slot masks */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
	    codec_dai->tx_mask)
		soc_pcm_codec_params_fixup(&codec_params,
					   codec_dai->tx_mask);

As a result of this confusion, the codec_params_fixup() ends-up generating bad channel masks, depending on what stream_tag was allocated.

We could add a flag to state that the tx_mask is really not a mask, but it would be quite ugly to persist in overloading concepts.

Instead, this patch suggests a more generic get/set 'stream' API based on the existing model for SoundWire. We can expand the concept to store 'stream' opaque information that is specific to different DAI types. In the case of HDAudio DAIs, we only need to store a stream tag as an unsigned char pointer. The TDM rx_ and tx_masks should really only be used to store masks.

Rename get_sdw_stream/set_sdw_stream callbacks and helpers as get_stream/set_stream. No functionality change beyond the rename.

---
 drivers/soundwire/intel.c        |    8 ++++----
 drivers/soundwire/qcom.c         |    8 ++++----
 drivers/soundwire/stream.c       |    4 ++--
 include/sound/soc-dai.h          |   32 ++++++++++++++++----------------
 sound/soc/codecs/max98373-sdw.c  |    2 +-
 sound/soc/codecs/rt1308-sdw.c    |    2 +-
 sound/soc/codecs/rt1316-sdw.c    |    2 +-
 sound/soc/codecs/rt5682-sdw.c    |    2 +-
 sound/soc/codecs/rt700.c         |    2 +-
 sound/soc/codecs/rt711-sdca.c    |    2 +-
 sound/soc/codecs/rt711.c         |    2 +-
 sound/soc/codecs/rt715-sdca.c    |    2 +-
 sound/soc/codecs/rt715.c         |    2 +-
 sound/soc/codecs/sdw-mockup.c    |    2 +-
 sound/soc/codecs/wcd938x.c       |    2 +-
 sound/soc/codecs/wsa881x.c       |    2 +-
 sound/soc/intel/boards/sof_sdw.c |    6 +++---
 sound/soc/qcom/sdm845.c          |    4 ++--
 sound/soc/qcom/sm8250.c          |    4 ++--
 19 files changed, 45 insertions(+), 45 deletions(-)
drivers/soundwire/intel.c +4 -4
@@ -1065,8 +1065,8 @@ static const struct snd_soc_dai_ops inte
 	.prepare = intel_prepare,
 	.hw_free = intel_hw_free,
 	.shutdown = intel_shutdown,
-	.set_sdw_stream = intel_pcm_set_sdw_stream,
-	.get_sdw_stream = intel_get_sdw_stream,
+	.set_stream = intel_pcm_set_sdw_stream,
+	.get_stream = intel_get_sdw_stream,
 };
 
 static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
@@ -1075,8 +1075,8 @@ static const struct snd_soc_dai_ops inte
 	.prepare = intel_prepare,
 	.hw_free = intel_hw_free,
 	.shutdown = intel_shutdown,
-	.set_sdw_stream = intel_pdm_set_sdw_stream,
-	.get_sdw_stream = intel_get_sdw_stream,
+	.set_stream = intel_pdm_set_sdw_stream,
+	.get_stream = intel_get_sdw_stream,
 };
 
 static const struct snd_soc_component_driver dai_component = {
drivers/soundwire/qcom.c +4 -4
@@ -1032,8 +1032,8 @@ static int qcom_swrm_startup(struct snd_
 	ctrl->sruntime[dai->id] = sruntime;
 
 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
-		ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime,
-						 substream->stream);
+		ret = snd_soc_dai_set_stream(codec_dai, sruntime,
+					     substream->stream);
 		if (ret < 0 && ret != -ENOTSUPP) {
 			dev_err(dai->dev, "Failed to set sdw stream on %s\n",
 				codec_dai->name);
@@ -1059,8 +1059,8 @@ static const struct snd_soc_dai_ops qcom
 	.hw_free = qcom_swrm_hw_free,
 	.startup = qcom_swrm_startup,
 	.shutdown = qcom_swrm_shutdown,
-	.set_sdw_stream = qcom_swrm_set_sdw_stream,
-	.get_sdw_stream = qcom_swrm_get_sdw_stream,
+	.set_stream = qcom_swrm_set_sdw_stream,
+	.get_stream = qcom_swrm_get_sdw_stream,
 };
 
 static const struct snd_soc_component_driver qcom_swrm_dai_component = {
drivers/soundwire/stream.c +2 -2
@@ -1880,7 +1880,7 @@ static int set_stream(struct snd_pcm_sub
 
 	/* Set stream pointer on all DAIs */
 	for_each_rtd_dais(rtd, i, dai) {
-		ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
+		ret = snd_soc_dai_set_stream(dai, sdw_stream, substream->stream);
 		if (ret < 0) {
 			dev_err(rtd->dev, "failed to set stream pointer on dai %s\n", dai->name);
 			break;
@@ -1951,7 +1951,7 @@ void sdw_shutdown_stream(void *sdw_subst
 	/* Find stream from first CPU DAI */
 	dai = asoc_rtd_to_cpu(rtd, 0);
 
-	sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
 	if (IS_ERR(sdw_stream)) {
 		dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
include/sound/soc-dai.h +16 -16
@@ -295,9 +295,9 @@ struct snd_soc_dai_ops {
 			unsigned int *rx_num, unsigned int *rx_slot);
 	int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
 
-	int (*set_sdw_stream)(struct snd_soc_dai *dai,
-			void *stream, int direction);
-	void *(*get_sdw_stream)(struct snd_soc_dai *dai, int direction);
+	int (*set_stream)(struct snd_soc_dai *dai,
+			  void *stream, int direction);
+	void *(*get_stream)(struct snd_soc_dai *dai, int direction);
 
 	/*
 	 * DAI digital mute - optional.
@@ -515,42 +515,42 @@ static inline void *snd_soc_dai_get_drvd
 }
 
 /**
- * snd_soc_dai_set_sdw_stream() - Configures a DAI for SDW stream operation
+ * snd_soc_dai_set_stream() - Configures a DAI for stream operation
  * @dai: DAI
- * @stream: STREAM
+ * @stream: STREAM (opaque structure depending on DAI type)
  * @direction: Stream direction(Playback/Capture)
- * SoundWire subsystem doesn't have a notion of direction and we reuse
+ * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
  * the ASoC stream direction to configure sink/source ports.
  * Playback maps to source ports and Capture for sink ports.
  *
  * This should be invoked with NULL to clear the stream set previously.
  * Returns 0 on success, a negative error code otherwise.
  */
-static inline int snd_soc_dai_set_sdw_stream(struct snd_soc_dai *dai,
-				void *stream, int direction)
+static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
+					 void *stream, int direction)
 {
-	if (dai->driver->ops->set_sdw_stream)
-		return dai->driver->ops->set_sdw_stream(dai, stream, direction);
+	if (dai->driver->ops->set_stream)
+		return dai->driver->ops->set_stream(dai, stream, direction);
 	else
 		return -ENOTSUPP;
 }
 
 /**
- * snd_soc_dai_get_sdw_stream() - Retrieves SDW stream from DAI
+ * snd_soc_dai_get_stream() - Retrieves stream from DAI
  * @dai: DAI
  * @direction: Stream direction(Playback/Capture)
  *
  * This routine only retrieves that was previously configured
- * with snd_soc_dai_get_sdw_stream()
+ * with snd_soc_dai_get_stream()
  *
  * Returns pointer to stream or an ERR_PTR value, e.g.
  * ERR_PTR(-ENOTSUPP) if callback is not supported;
  */
-static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai,
-					       int direction)
+static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
+					   int direction)
 {
-	if (dai->driver->ops->get_sdw_stream)
-		return dai->driver->ops->get_sdw_stream(dai, direction);
+	if (dai->driver->ops->get_stream)
+		return dai->driver->ops->get_stream(dai, direction);
 	else
 		return ERR_PTR(-ENOTSUPP);
 }
sound/soc/codecs/max98373-sdw.c +1 -1
@@ -741,7 +741,7 @@ static int max98373_sdw_set_tdm_slot(str
 static const struct snd_soc_dai_ops max98373_dai_sdw_ops = {
 	.hw_params = max98373_sdw_dai_hw_params,
 	.hw_free = max98373_pcm_hw_free,
-	.set_sdw_stream = max98373_set_sdw_stream,
+	.set_stream = max98373_set_sdw_stream,
 	.shutdown = max98373_shutdown,
 	.set_tdm_slot = max98373_sdw_set_tdm_slot,
 };
sound/soc/codecs/rt1308-sdw.c +1 -1
@@ -613,7 +613,7 @@ static const struct snd_soc_component_dr
 static const struct snd_soc_dai_ops rt1308_aif_dai_ops = {
 	.hw_params = rt1308_sdw_hw_params,
 	.hw_free	= rt1308_sdw_pcm_hw_free,
-	.set_sdw_stream	= rt1308_set_sdw_stream,
+	.set_stream	= rt1308_set_sdw_stream,
 	.shutdown	= rt1308_sdw_shutdown,
 	.set_tdm_slot	= rt1308_sdw_set_tdm_slot,
 };
sound/soc/codecs/rt1316-sdw.c +1 -1
@@ -602,7 +602,7 @@ static const struct snd_soc_component_dr
 static const struct snd_soc_dai_ops rt1316_aif_dai_ops = {
 	.hw_params = rt1316_sdw_hw_params,
 	.hw_free	= rt1316_sdw_pcm_hw_free,
-	.set_sdw_stream	= rt1316_set_sdw_stream,
+	.set_stream	= rt1316_set_sdw_stream,
 	.shutdown	= rt1316_sdw_shutdown,
 };
 
sound/soc/codecs/rt5682-sdw.c +1 -1
@@ -272,7 +272,7 @@ static int rt5682_sdw_hw_free(struct snd
 static const struct snd_soc_dai_ops rt5682_sdw_ops = {
 	.hw_params	= rt5682_sdw_hw_params,
 	.hw_free	= rt5682_sdw_hw_free,
-	.set_sdw_stream	= rt5682_set_sdw_stream,
+	.set_stream	= rt5682_set_sdw_stream,
 	.shutdown	= rt5682_sdw_shutdown,
 };
 
sound/soc/codecs/rt700.c +1 -1
@@ -1015,7 +1015,7 @@ static int rt700_pcm_hw_free(struct snd_
 static const struct snd_soc_dai_ops rt700_ops = {
 	.hw_params	= rt700_pcm_hw_params,
 	.hw_free	= rt700_pcm_hw_free,
-	.set_sdw_stream	= rt700_set_sdw_stream,
+	.set_stream	= rt700_set_sdw_stream,
 	.shutdown	= rt700_shutdown,
 };
 
sound/soc/codecs/rt711-sdca.c +1 -1
@@ -1361,7 +1361,7 @@ static int rt711_sdca_pcm_hw_free(struct
 static const struct snd_soc_dai_ops rt711_sdca_ops = {
 	.hw_params	= rt711_sdca_pcm_hw_params,
 	.hw_free	= rt711_sdca_pcm_hw_free,
-	.set_sdw_stream	= rt711_sdca_set_sdw_stream,
+	.set_stream	= rt711_sdca_set_sdw_stream,
 	.shutdown	= rt711_sdca_shutdown,
 };
 
sound/soc/codecs/rt711.c +1 -1
@@ -1092,7 +1092,7 @@ static int rt711_pcm_hw_free(struct snd_
 static const struct snd_soc_dai_ops rt711_ops = {
 	.hw_params	= rt711_pcm_hw_params,
 	.hw_free	= rt711_pcm_hw_free,
-	.set_sdw_stream	= rt711_set_sdw_stream,
+	.set_stream	= rt711_set_sdw_stream,
 	.shutdown	= rt711_shutdown,
 };
 
sound/soc/codecs/rt715-sdca.c +1 -1
@@ -938,7 +938,7 @@ static int rt715_sdca_pcm_hw_free(struct
 static const struct snd_soc_dai_ops rt715_sdca_ops = {
 	.hw_params	= rt715_sdca_pcm_hw_params,
 	.hw_free	= rt715_sdca_pcm_hw_free,
-	.set_sdw_stream	= rt715_sdca_set_sdw_stream,
+	.set_stream	= rt715_sdca_set_sdw_stream,
 	.shutdown	= rt715_sdca_shutdown,
 };
 
sound/soc/codecs/rt715.c +1 -1
@@ -909,7 +909,7 @@ static int rt715_pcm_hw_free(struct snd_
 static const struct snd_soc_dai_ops rt715_ops = {
 	.hw_params	= rt715_pcm_hw_params,
 	.hw_free	= rt715_pcm_hw_free,
-	.set_sdw_stream	= rt715_set_sdw_stream,
+	.set_stream	= rt715_set_sdw_stream,
 	.shutdown	= rt715_shutdown,
 };
 
sound/soc/codecs/sdw-mockup.c +1 -1
@@ -138,7 +138,7 @@ static int sdw_mockup_pcm_hw_free(struct
 static const struct snd_soc_dai_ops sdw_mockup_ops = {
 	.hw_params	= sdw_mockup_pcm_hw_params,
 	.hw_free	= sdw_mockup_pcm_hw_free,
-	.set_sdw_stream	= sdw_mockup_set_sdw_stream,
+	.set_stream	= sdw_mockup_set_sdw_stream,
 	.shutdown	= sdw_mockup_shutdown,
 };
 
sound/soc/codecs/wcd938x.c +1 -1
@@ -4302,7 +4302,7 @@ static int wcd938x_codec_set_sdw_stream(
 static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = {
 	.hw_params = wcd938x_codec_hw_params,
 	.hw_free = wcd938x_codec_free,
-	.set_sdw_stream = wcd938x_codec_set_sdw_stream,
+	.set_stream = wcd938x_codec_set_sdw_stream,
 };
 
 static struct snd_soc_dai_driver wcd938x_dais[] = {
sound/soc/codecs/wsa881x.c +1 -1
@@ -1026,7 +1026,7 @@ static const struct snd_soc_dai_ops wsa8
 	.hw_params = wsa881x_hw_params,
 	.hw_free = wsa881x_hw_free,
 	.mute_stream = wsa881x_digital_mute,
-	.set_sdw_stream = wsa881x_set_sdw_stream,
+	.set_stream = wsa881x_set_sdw_stream,
 };
 
 static struct snd_soc_dai_driver wsa881x_dais[] = {
sound/soc/intel/boards/sof_sdw.c +3 -3
@@ -291,7 +291,7 @@ int sdw_prepare(struct snd_pcm_substream
 	/* Find stream from first CPU DAI */
 	dai = asoc_rtd_to_cpu(rtd, 0);
 
-	sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
 	if (IS_ERR(sdw_stream)) {
 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
@@ -311,7 +311,7 @@ int sdw_trigger(struct snd_pcm_substream
 	/* Find stream from first CPU DAI */
 	dai = asoc_rtd_to_cpu(rtd, 0);
 
-	sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
 	if (IS_ERR(sdw_stream)) {
 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
@@ -350,7 +350,7 @@ int sdw_hw_free(struct snd_pcm_substream
 	/* Find stream from first CPU DAI */
 	dai = asoc_rtd_to_cpu(rtd, 0);
 
-	sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+	sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
 	if (IS_ERR(sdw_stream)) {
 		dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
sound/soc/qcom/sdm845.c +2 -2
@@ -56,8 +56,8 @@ static int sdm845_slim_snd_hw_params(str
 	int ret = 0, i;
 
 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
-		sruntime = snd_soc_dai_get_sdw_stream(codec_dai,
-						      substream->stream);
+		sruntime = snd_soc_dai_get_stream(codec_dai,
+						  substream->stream);
 		if (sruntime != ERR_PTR(-ENOTSUPP))
 			pdata->sruntime[cpu_dai->id] = sruntime;
 
sound/soc/qcom/sm8250.c +2 -2
@@ -70,8 +70,8 @@ static int sm8250_snd_hw_params(struct s
 	switch (cpu_dai->id) {
 	case WSA_CODEC_DMA_RX_0:
 		for_each_rtd_codec_dais(rtd, i, codec_dai) {
-			sruntime = snd_soc_dai_get_sdw_stream(codec_dai,
-						      substream->stream);
+			sruntime = snd_soc_dai_get_stream(codec_dai,
+							  substream->stream);
 			if (sruntime != ERR_PTR(-ENOTSUPP))
 				pdata->sruntime[cpu_dai->id] = sruntime;
 		}
author maintainer
#57 lore raw

PATCH 57/290 rcu-tasks: Simplify trc_read_check_handler() atomic operations

In reply to Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

commit 96017bf9039763a2e02dcc6adaa18592cd73a39d upstream.

Currently, trc_wait_for_one_reader() atomically increments the trc_n_readers_need_end counter before sending the IPI invoking trc_read_check_handler(). All failure paths out of trc_read_check_handler() and also from the smp_call_function_single() within trc_wait_for_one_reader() must carefully atomically decrement this counter. This is more complex than it needs to be.

This commit therefore simplifies things and saves a few lines of code by dispensing with the atomic decrements in favor of having trc_read_check_handler() do the atomic increment only in the success case. In theory, this represents no change in functionality.

---
 kernel/rcu/tasks.h |   20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)
kernel/rcu/tasks.h +3 -17
@@ -892,32 +892,24 @@ static void trc_read_check_handler(void
 
 	// If the task is no longer running on this CPU, leave.
 	if (unlikely(texp != t)) {
-		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-			wake_up(&trc_wait);
 		goto reset_ipi; // Already on holdout list, so will check later.
 	}
 
 	// If the task is not in a read-side critical section, and
 	// if this is the last reader, awaken the grace-period kthread.
 	if (likely(!READ_ONCE(t->trc_reader_nesting))) {
-		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-			wake_up(&trc_wait);
-		// Mark as checked after decrement to avoid false
-		// positives on the above WARN_ON_ONCE().
 		WRITE_ONCE(t->trc_reader_checked, true);
 		goto reset_ipi;
 	}
 	// If we are racing with an rcu_read_unlock_trace(), try again later.
-	if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0)) {
-		if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-			wake_up(&trc_wait);
+	if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0))
 		goto reset_ipi;
-	}
 	WRITE_ONCE(t->trc_reader_checked, true);
 
 	// Get here if the task is in a read-side critical section.  Set
 	// its state so that it will awaken the grace-period kthread upon
 	// exit from that critical section.
+	atomic_inc(&trc_n_readers_need_end); // One more to wait on.
 	WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs));
 	WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
 
@@ -1017,21 +1009,15 @@ static void trc_wait_for_one_reader(stru
 		if (per_cpu(trc_ipi_to_cpu, cpu) || t->trc_ipi_to_cpu >= 0)
 			return;
 
-		atomic_inc(&trc_n_readers_need_end);
 		per_cpu(trc_ipi_to_cpu, cpu) = true;
 		t->trc_ipi_to_cpu = cpu;
 		rcu_tasks_trace.n_ipis++;
-		if (smp_call_function_single(cpu,
-					     trc_read_check_handler, t, 0)) {
+		if (smp_call_function_single(cpu, trc_read_check_handler, t, 0)) {
 			// Just in case there is some other reason for
 			// failure than the target CPU being offline.
 			rcu_tasks_trace.n_ipis_fails++;
 			per_cpu(trc_ipi_to_cpu, cpu) = false;
 			t->trc_ipi_to_cpu = cpu;
-			if (atomic_dec_and_test(&trc_n_readers_need_end)) {
-				WARN_ON_ONCE(1);
-				wake_up(&trc_wait);
-			}
 		}
 	}
 }
#58 lore raw

Re: [PATCH 5.15 057/290] rcu-tasks: Simplify trc_read_check_handler() atomic operations

Quoted 4 lines · Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

commit 96017bf9039763a2e02dcc6adaa18592cd73a39d upstream.

Thanks Greg, I had sent the same patch earlier for 5.15. Just so I learn, anything I did wrong or should have done differently?

- Joel

Quoted 82 lines

Currently, trc_wait_for_one_reader() atomically increments the trc_n_readers_need_end counter before sending the IPI invoking trc_read_check_handler(). All failure paths out of trc_read_check_handler() and also from the smp_call_function_single() within trc_wait_for_one_reader() must carefully atomically decrement this counter. This is more complex than it needs to be.

This commit therefore simplifies things and saves a few lines of code by dispensing with the atomic decrements in favor of having trc_read_check_handler() do the atomic increment only in the success case. In theory, this represents no change in functionality.

---
 kernel/rcu/tasks.h |   20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)
kernel/rcu/tasks.h +3 -17
@@ -892,32 +892,24 @@ static void trc_read_check_handler(void
 
        // If the task is no longer running on this CPU, leave.
        if (unlikely(texp != t)) {
-               if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-                       wake_up(&trc_wait);
                goto reset_ipi; // Already on holdout list, so will check later.
        }
 
        // If the task is not in a read-side critical section, and
        // if this is the last reader, awaken the grace-period kthread.
        if (likely(!READ_ONCE(t->trc_reader_nesting))) {
-               if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-                       wake_up(&trc_wait);
-               // Mark as checked after decrement to avoid false
-               // positives on the above WARN_ON_ONCE().
                WRITE_ONCE(t->trc_reader_checked, true);
                goto reset_ipi;
        }
        // If we are racing with an rcu_read_unlock_trace(), try again later.
-       if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0)) {
-               if (WARN_ON_ONCE(atomic_dec_and_test(&trc_n_readers_need_end)))
-                       wake_up(&trc_wait);
+       if (unlikely(READ_ONCE(t->trc_reader_nesting) < 0))
                goto reset_ipi;
-       }
        WRITE_ONCE(t->trc_reader_checked, true);
 
        // Get here if the task is in a read-side critical section.  Set
        // its state so that it will awaken the grace-period kthread upon
        // exit from that critical section.
+       atomic_inc(&trc_n_readers_need_end); // One more to wait on.
        WARN_ON_ONCE(READ_ONCE(t->trc_reader_special.b.need_qs));
        WRITE_ONCE(t->trc_reader_special.b.need_qs, true);
 
@@ -1017,21 +1009,15 @@ static void trc_wait_for_one_reader(stru
                if (per_cpu(trc_ipi_to_cpu, cpu) || t->trc_ipi_to_cpu >= 0)
                        return;
 
-               atomic_inc(&trc_n_readers_need_end);
                per_cpu(trc_ipi_to_cpu, cpu) = true;
                t->trc_ipi_to_cpu = cpu;
                rcu_tasks_trace.n_ipis++;
-               if (smp_call_function_single(cpu,
-                                            trc_read_check_handler, t, 0)) {
+               if (smp_call_function_single(cpu, trc_read_check_handler, t, 0)) {
                        // Just in case there is some other reason for
                        // failure than the target CPU being offline.
                        rcu_tasks_trace.n_ipis_fails++;
                        per_cpu(trc_ipi_to_cpu, cpu) = false;
                        t->trc_ipi_to_cpu = cpu;
-                       if (atomic_dec_and_test(&trc_n_readers_need_end)) {
-                               WARN_ON_ONCE(1);
-                               wake_up(&trc_wait);
-                       }
                }
        }
 }
#59 lore raw

Re: [PATCH 5.15 057/290] rcu-tasks: Simplify trc_read_check_handler() atomic operations

Quoted 10 lines · Joel Fernandes
Quoted 4 lines · Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

commit 96017bf9039763a2e02dcc6adaa18592cd73a39d upstream.

Thanks Greg, I had sent the same patch earlier for 5.15. Just so I learn, anything I did wrong or should have done differently?

Never mind, I think it is just coming from your queue after you picked mine up...

author maintainer
#60 lore raw

Re: [PATCH 5.15 057/290] rcu-tasks: Simplify trc_read_check_handler() atomic operations

Quoted 7 lines · Joel Fernandes
Quoted 6 lines · Joel Fernandes
Quoted 3 lines · Greg Kroah-Hartman

From: Paul E. McKenney <[email protected]>

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

commit 96017bf9039763a2e02dcc6adaa18592cd73a39d upstream.

Thanks Greg, I had sent the same patch earlier for 5.15. Just so I learn, anything I did wrong or should have done differently?

Never mind, I think it is just coming from your queue after you picked mine up...

Yes, this is the one you sent me to have applied :)

author maintainer
#61 lore raw

PATCH 58/290 net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO

In reply to Greg Kroah-Hartman

From: Hangbin Liu <[email protected]>

commit dfed913e8b55a0c2c4906f1242fd38fd9a116e49 upstream.

Currently, the kernel drops GSO VLAN tagged packet if it's created with socket(AF_PACKET, SOCK_RAW, 0) plus virtio_net_hdr.

The reason is AF_PACKET doesn't adjust the skb network header if there is a VLAN tag. Then after virtio_net_hdr_set_proto() called, the skb->protocol will be set to ETH_P_IP/IPv6. And in later inet/ipv6_gso_segment() the skb is dropped as network header position is invalid.

Let's handle VLAN packets by adjusting network header position in packet_parse_headers(). The adjustment is safe and does not affect the later xmit as tap device also did that.

In packet_snd(), packet_parse_headers() need to be moved before calling virtio_net_hdr_set_proto(), so we can set correct skb->protocol and network header first.

There is no need to update tpacket_snd() as it calls packet_parse_headers() in tpacket_fill_skb(), which is already before calling virtio_net_hdr_* functions.

skb->no_fcs setting is also moved upper to make all skb settings together and keep consistency with function packet_sendmsg_spkt().

---
 net/packet/af_packet.c |   18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
net/packet/af_packet.c +13 -5
@@ -1888,12 +1888,20 @@ oom:
 
 static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)
 {
+	int depth;
+
 	if ((!skb->protocol || skb->protocol == htons(ETH_P_ALL)) &&
 	    sock->type == SOCK_RAW) {
 		skb_reset_mac_header(skb);
 		skb->protocol = dev_parse_header_protocol(skb);
 	}
 
+	/* Move network header to the right position for VLAN tagged packets */
+	if (likely(skb->dev->type == ARPHRD_ETHER) &&
+	    eth_type_vlan(skb->protocol) &&
+	    __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
+		skb_set_network_header(skb, depth);
+
 	skb_probe_transport_header(skb);
 }
 
@@ -3008,6 +3016,11 @@ static int packet_snd(struct socket *soc
 	skb->mark = sockc.mark;
 	skb->tstamp = sockc.transmit_time;
 
+	if (unlikely(extra_len == 4))
+		skb->no_fcs = 1;
+
+	packet_parse_headers(skb, sock);
+
 	if (has_vnet_hdr) {
 		err = virtio_net_hdr_to_skb(skb, &vnet_hdr, vio_le());
 		if (err)
@@ -3016,11 +3029,6 @@ static int packet_snd(struct socket *soc
 		virtio_net_hdr_set_proto(skb, &vnet_hdr);
 	}
 
-	packet_parse_headers(skb, sock);
-
-	if (unlikely(extra_len == 4))
-		skb->no_fcs = 1;
-
 	err = po->xmit(skb);
 	if (unlikely(err != 0)) {
 		if (err > 0)
author maintainer
#62 lore raw

PATCH 59/290 net/af_packet: make sure to pull mac header

In reply to Greg Kroah-Hartman

From: Eric Dumazet <[email protected]>

commit e9d3f80935b6607dcdc5682b00b1d4b28e0a0c5d upstream.

GSO assumes skb->head contains link layer headers.

tun device in some case can provide base 14 bytes, regardless of VLAN being used or not.

After blamed commit, we can end up setting a network header offset of 18+, we better pull the missing bytes to avoid a posible crash in GSO.

syzbot report was:
kernel BUG at include/linux/skbuff.h:2699!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN

CPU: 1 PID: 3601 Comm: syz-executor210 Not tainted 5.18.0-syzkaller-11338-g2c5ca23f7414 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
RIP: 0010:__skb_pull include/linux/skbuff.h:2699 [inline]
RIP: 0010:skb_mac_gso_segment+0x48f/0x530 net/core/gro.c:136
Code: 00 48 c7 c7 00 96 d4 8a c6 05 cb d3 45 06 01 e8 26 bb d0 01 e9 2f fd ff ff 49 c7 c4 ea ff ff ff e9 f1 fe ff ff e8 91 84 19 fa <0f> 0b 48 89 df e8 97 44 66 fa e9 7f fd ff ff e8 ad 44 66 fa e9 48
RSP: 0018:ffffc90002e2f4b8 EFLAGS: 00010293
RAX: 0000000000000000 RBX: 0000000000000012 RCX: 0000000000000000
RDX: ffff88805bb58000 RSI: ffffffff8760ed0f RDI: 0000000000000004
RBP: 0000000000005dbc R08: 0000000000000004 R09: 0000000000000fe0
R10: 0000000000000fe4 R11: 0000000000000000 R12: 0000000000000fe0
R13: ffff88807194d780 R14: 1ffff920005c5e9b R15: 0000000000000012
FS:  000055555730f300(0000) GS:ffff8880b9d00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000200015c0 CR3: 0000000071ff8000 CR4: 0000000000350ee0
Call Trace:
 <TASK>
 __skb_gso_segment+0x327/0x6e0 net/core/dev.c:3411
 skb_gso_segment include/linux/netdevice.h:4749 [inline]
 validate_xmit_skb+0x6bc/0xf10 net/core/dev.c:3669
 validate_xmit_skb_list+0xbc/0x120 net/core/dev.c:3719
 sch_direct_xmit+0x3d1/0xbe0 net/sched/sch_generic.c:327
 __dev_xmit_skb net/core/dev.c:3815 [inline]
 __dev_queue_xmit+0x14a1/0x3a00 net/core/dev.c:4219
 packet_snd net/packet/af_packet.c:3071 [inline]
 packet_sendmsg+0x21cb/0x5550 net/packet/af_packet.c:3102
 sock_sendmsg_nosec net/socket.c:714 [inline]
 sock_sendmsg+0xcf/0x120 net/socket.c:734
 ____sys_sendmsg+0x6eb/0x810 net/socket.c:2492
 ___sys_sendmsg+0xf3/0x170 net/socket.c:2546
 __sys_sendmsg net/socket.c:2575 [inline]
 __do_sys_sendmsg net/socket.c:2584 [inline]
 __se_sys_sendmsg net/socket.c:2582 [inline]
 __x64_sys_sendmsg+0x132/0x220 net/socket.c:2582
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x46/0xb0
RIP: 0033:0x7f4b95da06c9
Code: 28 c3 e8 4a 15 00 00 66 2e 0f 1f 84 00 00 00 00 00 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 c0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffd7defc4c8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
RAX: ffffffffffffffda RBX: 00007ffd7defc4f0 RCX: 00007f4b95da06c9
RDX: 0000000000000000 RSI: 0000000020000140 RDI: 0000000000000003
RBP: 0000000000000003 R08: bb1414ac00000050 R09: bb1414ac00000050
R10: 0000000000000004 R11: 0000000000000246 R12: 0000000000000000
R13: 00007ffd7defc4e0 R14: 00007ffd7defc4d8 R15: 00007ffd7defc4d4
 </TASK>
Fixes dfed913e8b55 ("net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO")
Cc Michael S. Tsirkin <[email protected]>
---
 net/packet/af_packet.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
net/packet/af_packet.c +4 -2
@@ -1899,8 +1899,10 @@ static void packet_parse_headers(struct
 	/* Move network header to the right position for VLAN tagged packets */
 	if (likely(skb->dev->type == ARPHRD_ETHER) &&
 	    eth_type_vlan(skb->protocol) &&
-	    __vlan_get_protocol(skb, skb->protocol, &depth) != 0)
-		skb_set_network_header(skb, depth);
+	    __vlan_get_protocol(skb, skb->protocol, &depth) != 0) {
+		if (pskb_may_pull(skb, depth))
+			skb_set_network_header(skb, depth);
+	}
 
 	skb_probe_transport_header(skb);
 }
author maintainer
#63 lore raw

PATCH 60/290 media: stv0288: use explicitly signed char

In reply to Greg Kroah-Hartman

From: Jason A. Donenfeld <[email protected]>

commit 7392134428c92a4cb541bd5c8f4f5c8d2e88364d upstream.

With char becoming unsigned by default, and with char alone being ambiguous and based on architecture, signed chars need to be marked explicitly as such. Use s8 and u8 types here, since that's what surrounding code does. This fixes:

drivers/media/dvb-frontends/stv0288.c:471 stv0288_set_frontend() warn: assigning (-9) to unsigned variable 'tm' drivers/media/dvb-frontends/stv0288.c:471 stv0288_set_frontend() warn: we never enter this loop

---
 drivers/media/dvb-frontends/stv0288.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/media/dvb-frontends/stv0288.c +2 -3
@@ -440,9 +440,8 @@ static int stv0288_set_frontend(struct d
 	struct stv0288_state *state = fe->demodulator_priv;
 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
-	char tm;
-	unsigned char tda[3];
-	u8 reg, time_out = 0;
+	u8 tda[3], reg, time_out = 0;
+	s8 tm;
 
 	dprintk("%s : FE_SET_FRONTEND\n", __func__);
 
author maintainer
#64 lore raw

PATCH 61/290 soc: qcom: Select REMAP_MMIO for LLCC driver

In reply to Greg Kroah-Hartman

From: Manivannan Sadhasivam <[email protected]>

commit 5d2fe2d7b616b8baa18348ead857b504fc2de336 upstream.

LLCC driver uses REGMAP_MMIO for accessing the hardware registers. So select the dependency in Kconfig. Without this, there will be errors while building the driver with COMPILE_TEST only:

ERROR: modpost: "__devm_regmap_init_mmio_clk" [drivers/soc/qcom/llcc-qcom.ko] undefined! make[1]: *** [scripts/Makefile.modpost:126: Module.symvers] Error 1
make: *** [Makefile:1944: modpost] Error 2

---
 drivers/soc/qcom/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/soc/qcom/Kconfig +1 -0
@@ -63,6 +63,7 @@ config QCOM_GSBI
 config QCOM_LLCC
 	tristate "Qualcomm Technologies, Inc. LLCC driver"
 	depends on ARCH_QCOM || COMPILE_TEST
+	select REGMAP_MMIO
 	help
 	  Qualcomm Technologies, Inc. platform specific
 	  Last Level Cache Controller(LLCC) driver for platforms such as,
author maintainer
#65 lore raw

PATCH 62/290 kest.pl: Fix grub2 menu handling for rebooting

In reply to Greg Kroah-Hartman

From: Steven Rostedt <[email protected]>

commit 26df05a8c1420ad3de314fdd407e7fc2058cc7aa upstream.

grub2 has submenus where to use grub-reboot, it requires:

grub-reboot X>Y

where X is the main index and Y is the submenu. Thus if you have:

menuentry 'Debian GNU/Linux' --class debian --class gnu-linux ...

	[...]
}
submenu 'Advanced options for Debian GNU/Linux' $menuentry_id_option ...
        menuentry 'Debian GNU/Linux, with Linux 6.0.0-4-amd64' --class debian --class gnu-linux ...
                [...]
        }
        menuentry 'Debian GNU/Linux, with Linux 6.0.0-4-amd64 (recovery mode)' --class debian --class gnu-linux ...
		[...]
        }
        menuentry 'Debian GNU/Linux, with Linux test' --class debian --class gnu-linux ...
                [...]
        }

And wanted to boot to the "Linux test" kernel, you need to run:

 # grub-reboot 1>2

As 1 is the second top menu (the submenu) and 2 is the third of the sub menu entries.

Have the grub.cfg parsing for grub2 handle such cases.

---
 tools/testing/ktest/ktest.pl |   20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
tools/testing/ktest/ktest.pl +15 -5
@@ -1963,7 +1963,7 @@ sub run_scp_mod {
 
 sub _get_grub_index {
 
-    my ($command, $target, $skip) = @_;
+    my ($command, $target, $skip, $submenu) = @_;
 
     return if (defined($grub_number) && defined($last_grub_menu) &&
 	$last_grub_menu eq $grub_menu && defined($last_machine) &&
@@ -1980,11 +1980,16 @@ sub _get_grub_index {
 
     my $found = 0;
 
+    my $submenu_number = 0;
+
     while (<IN>) {
 	if (/$target/) {
 	    $grub_number++;
 	    $found = 1;
 	    last;
+	} elsif (defined($submenu) && /$submenu/) {
+		$submenu_number++;
+		$grub_number = -1;
 	} elsif (/$skip/) {
 	    $grub_number++;
 	}
@@ -1993,6 +1998,9 @@ sub _get_grub_index {
 
     dodie "Could not find '$grub_menu' through $command on $machine"
 	if (!$found);
+    if ($submenu_number > 0) {
+	$grub_number = "$submenu_number>$grub_number";
+    }
     doprint "$grub_number\n";
     $last_grub_menu = $grub_menu;
     $last_machine = $machine;
@@ -2003,6 +2011,7 @@ sub get_grub_index {
     my $command;
     my $target;
     my $skip;
+    my $submenu;
     my $grub_menu_qt;
 
     if ($reboot_type !~ /^grub/) {
@@ -2017,8 +2026,9 @@ sub get_grub_index {
 	$skip = '^\s*title\s';
     } elsif ($reboot_type eq "grub2") {
 	$command = "cat $grub_file";
-	$target = '^menuentry.*' . $grub_menu_qt;
-	$skip = '^menuentry\s|^submenu\s';
+	$target = '^\s*menuentry.*' . $grub_menu_qt;
+	$skip = '^\s*menuentry';
+	$submenu = '^\s*submenu\s';
     } elsif ($reboot_type eq "grub2bls") {
 	$command = $grub_bls_get;
 	$target = '^title=.*' . $grub_menu_qt;
@@ -2027,7 +2037,7 @@ sub get_grub_index {
 	return;
     }
 
-    _get_grub_index($command, $target, $skip);
+    _get_grub_index($command, $target, $skip, $submenu);
 }
 
 sub wait_for_input {
@@ -2090,7 +2100,7 @@ sub reboot_to {
     if ($reboot_type eq "grub") {
 	run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'";
     } elsif (($reboot_type eq "grub2") or ($reboot_type eq "grub2bls")) {
-	run_ssh "$grub_reboot $grub_number";
+	run_ssh "$grub_reboot \"'$grub_number'\"";
     } elsif ($reboot_type eq "syslinux") {
 	run_ssh "$syslinux --once \\\"$syslinux_label\\\" $syslinux_path";
     } elsif (defined $reboot_script) {
author maintainer
#66 lore raw

PATCH 63/290 ktest.pl minconfig: Unset configs instead of just removing them

In reply to Greg Kroah-Hartman

From: Steven Rostedt <[email protected]>

commit ef784eebb56425eed6e9b16e7d47e5c00dcf9c38 upstream.

After a full run of a make_min_config test, I noticed there were a lot of CONFIGs still enabled that really should not be. Looking at them, I noticed they were all defined as "default y". The issue is that the test simple removes the config and re-runs make oldconfig, which enables it again because it is set to default 'y'. Instead, explicitly disable the config with writing "# CONFIG_FOO is not set" to the file to keep it from being set again.

With this change, one of my box's minconfigs went from 768 configs set, down to 521 configs set.

Fixes 0a05c769a9de5 ("ktest: Added config_bisect test type")
---
 tools/testing/ktest/ktest.pl |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/ktest/ktest.pl +2 -1
@@ -3778,9 +3778,10 @@ sub test_this_config {
     # .config to make sure it is missing the config that
     # we had before
     my %configs = %min_configs;
-    delete $configs{$config};
+    $configs{$config} = "# $config is not set";
     make_new_config ((values %configs), (values %keep_configs));
     make_oldconfig;
+    delete $configs{$config};
     undef %configs;
     assign_configs \%configs, $output_config;
 
author maintainer
#67 lore raw

PATCH 64/290 jbd2: use the correct print format

In reply to Greg Kroah-Hartman

From: Bixuan Cui <[email protected]>

commit d87a7b4c77a997d5388566dd511ca8e6b8e8a0a8 upstream.

The print format error was found when using ftrace event:

    <...>-1406 [000] .... 23599442.895823: jbd2_end_commit: dev 252,8 transaction -1866216965 sync 0 head -1866217368
    <...>-1406 [000] .... 23599442.896299: jbd2_start_commit: dev 252,8 transaction -1866216964 sync 0

Use the correct print format for transaction, head and tid.

Fixes 879c5e6b7cb4 ('jbd2: convert instrumentation from markers to tracepoints')
---
 include/trace/events/jbd2.h |   44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)
include/trace/events/jbd2.h +22 -22
@@ -40,7 +40,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	char,	sync_commit		  )
-		__field(	int,	transaction		  )
+		__field(	tid_t,	transaction		  )
 	),
 
 	TP_fast_assign(
@@ -49,7 +49,7 @@ DECLARE_EVENT_CLASS(jbd2_commit,
 		__entry->transaction	= commit_transaction->t_tid;
 	),
 
-	TP_printk("dev %d,%d transaction %d sync %d",
+	TP_printk("dev %d,%d transaction %u sync %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->transaction, __entry->sync_commit)
 );
@@ -97,8 +97,8 @@ TRACE_EVENT(jbd2_end_commit,
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	char,	sync_commit		  )
-		__field(	int,	transaction		  )
-		__field(	int,	head		  	  )
+		__field(	tid_t,	transaction		  )
+		__field(	tid_t,	head		  	  )
 	),
 
 	TP_fast_assign(
@@ -108,7 +108,7 @@ TRACE_EVENT(jbd2_end_commit,
 		__entry->head		= journal->j_tail_sequence;
 	),
 
-	TP_printk("dev %d,%d transaction %d sync %d head %d",
+	TP_printk("dev %d,%d transaction %u sync %d head %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->transaction, __entry->sync_commit, __entry->head)
 );
@@ -134,14 +134,14 @@ TRACE_EVENT(jbd2_submit_inode_data,
 );
 
 DECLARE_EVENT_CLASS(jbd2_handle_start_class,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int requested_blocks),
 
 	TP_ARGS(dev, tid, type, line_no, requested_blocks),
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	 unsigned int,	type		)
 		__field(	 unsigned int,	line_no		)
 		__field(		  int,	requested_blocks)
@@ -155,28 +155,28 @@ DECLARE_EVENT_CLASS(jbd2_handle_start_cl
 		__entry->requested_blocks = requested_blocks;
 	),
 
-	TP_printk("dev %d,%d tid %lu type %u line_no %u "
+	TP_printk("dev %d,%d tid %u type %u line_no %u "
 		  "requested_blocks %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  __entry->type, __entry->line_no, __entry->requested_blocks)
 );
 
 DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_start,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int requested_blocks),
 
 	TP_ARGS(dev, tid, type, line_no, requested_blocks)
 );
 
 DEFINE_EVENT(jbd2_handle_start_class, jbd2_handle_restart,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int requested_blocks),
 
 	TP_ARGS(dev, tid, type, line_no, requested_blocks)
 );
 
 TRACE_EVENT(jbd2_handle_extend,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int buffer_credits,
 		 int requested_blocks),
 
@@ -184,7 +184,7 @@ TRACE_EVENT(jbd2_handle_extend,
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	 unsigned int,	type		)
 		__field(	 unsigned int,	line_no		)
 		__field(		  int,	buffer_credits  )
@@ -200,7 +200,7 @@ TRACE_EVENT(jbd2_handle_extend,
 		__entry->requested_blocks = requested_blocks;
 	),
 
-	TP_printk("dev %d,%d tid %lu type %u line_no %u "
+	TP_printk("dev %d,%d tid %u type %u line_no %u "
 		  "buffer_credits %d requested_blocks %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  __entry->type, __entry->line_no, __entry->buffer_credits,
@@ -208,7 +208,7 @@ TRACE_EVENT(jbd2_handle_extend,
 );
 
 TRACE_EVENT(jbd2_handle_stats,
-	TP_PROTO(dev_t dev, unsigned long tid, unsigned int type,
+	TP_PROTO(dev_t dev, tid_t tid, unsigned int type,
 		 unsigned int line_no, int interval, int sync,
 		 int requested_blocks, int dirtied_blocks),
 
@@ -217,7 +217,7 @@ TRACE_EVENT(jbd2_handle_stats,
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	 unsigned int,	type		)
 		__field(	 unsigned int,	line_no		)
 		__field(		  int,	interval	)
@@ -237,7 +237,7 @@ TRACE_EVENT(jbd2_handle_stats,
 		__entry->dirtied_blocks	  = dirtied_blocks;
 	),
 
-	TP_printk("dev %d,%d tid %lu type %u line_no %u interval %d "
+	TP_printk("dev %d,%d tid %u type %u line_no %u interval %d "
 		  "sync %d requested_blocks %d dirtied_blocks %d",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  __entry->type, __entry->line_no, __entry->interval,
@@ -246,14 +246,14 @@ TRACE_EVENT(jbd2_handle_stats,
 );
 
 TRACE_EVENT(jbd2_run_stats,
-	TP_PROTO(dev_t dev, unsigned long tid,
+	TP_PROTO(dev_t dev, tid_t tid,
 		 struct transaction_run_stats_s *stats),
 
 	TP_ARGS(dev, tid, stats),
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	unsigned long,	wait		)
 		__field(	unsigned long,	request_delay	)
 		__field(	unsigned long,	running		)
@@ -279,7 +279,7 @@ TRACE_EVENT(jbd2_run_stats,
 		__entry->blocks_logged	= stats->rs_blocks_logged;
 	),
 
-	TP_printk("dev %d,%d tid %lu wait %u request_delay %u running %u "
+	TP_printk("dev %d,%d tid %u wait %u request_delay %u running %u "
 		  "locked %u flushing %u logging %u handle_count %u "
 		  "blocks %u blocks_logged %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
@@ -294,14 +294,14 @@ TRACE_EVENT(jbd2_run_stats,
 );
 
 TRACE_EVENT(jbd2_checkpoint_stats,
-	TP_PROTO(dev_t dev, unsigned long tid,
+	TP_PROTO(dev_t dev, tid_t tid,
 		 struct transaction_chp_stats_s *stats),
 
 	TP_ARGS(dev, tid, stats),
 
 	TP_STRUCT__entry(
 		__field(		dev_t,	dev		)
-		__field(	unsigned long,	tid		)
+		__field(		tid_t,	tid		)
 		__field(	unsigned long,	chp_time	)
 		__field(		__u32,	forced_to_close	)
 		__field(		__u32,	written		)
@@ -317,7 +317,7 @@ TRACE_EVENT(jbd2_checkpoint_stats,
 		__entry->dropped	= stats->cs_dropped;
 	),
 
-	TP_printk("dev %d,%d tid %lu chp_time %u forced_to_close %u "
+	TP_printk("dev %d,%d tid %u chp_time %u forced_to_close %u "
 		  "written %u dropped %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid,
 		  jiffies_to_msecs(__entry->chp_time),
author maintainer
#68 lore raw

PATCH 65/290 perf/x86/intel/uncore: Disable I/O stacks to PMU mapping on ICX-D

In reply to Greg Kroah-Hartman

From: Alexander Antonov <[email protected]>

commit efe062705d149b20a15498cb999a9edbb8241e6f upstream.

Current implementation of I/O stacks to PMU mapping doesn't support ICX-D. Detect ICX-D system to disable mapping.

Fixes 10337e95e04c ("perf/x86/intel/uncore: Enable I/O stacks to IIO PMON mapping on ICX")
---
 arch/x86/events/intel/uncore.h       |    1 +
 arch/x86/events/intel/uncore_snbep.c |    5 +++++
 2 files changed, 6 insertions(+)
arch/x86/events/intel/uncore.h +1 -0
@@ -2,6 +2,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <asm/apicdef.h>
+#include <asm/intel-family.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 
 #include <linux/perf_event.h>
arch/x86/events/intel/uncore_snbep.c +5 -0
@@ -5144,6 +5144,11 @@ static int icx_iio_get_topology(struct i
 
 static int icx_iio_set_mapping(struct intel_uncore_type *type)
 {
+	/* Detect ICX-D system. This case is not supported */
+	if (boot_cpu_data.x86_model == INTEL_FAM6_ICELAKE_D) {
+		pmu_clear_mapping_attr(type->attr_update, &icx_iio_mapping_group);
+		return -EPERM;
+	}
 	return pmu_iio_set_mapping(type, &icx_iio_mapping_group);
 }
 
author maintainer
#69 lore raw

PATCH 66/290 perf/x86/intel/uncore: Clear attr_update properly

In reply to Greg Kroah-Hartman

From: Alexander Antonov <[email protected]>

commit 6532783310e2b2f50dc13f46c49aa6546cb6e7a3 upstream.

Current clear_attr_update procedure in pmu_set_mapping() sets attr_update field in NULL that is not correct because intel_uncore_type pmu types can contain several groups in attr_update field. For example, SPR platform already has uncore_alias_group to update and then UPI topology group will be added in next patches.

Fix current behavior and clear attr_update group related to mapping only.

Fixes bb42b3d39781 ("perf/x86/intel/uncore: Expose an Uncore unit to IIO PMON mapping")
---
 arch/x86/events/intel/uncore_snbep.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
arch/x86/events/intel/uncore_snbep.c +16 -1
@@ -3804,6 +3804,21 @@ static const struct attribute_group *skx
 	NULL,
 };
 
+static void pmu_clear_mapping_attr(const struct attribute_group **groups,
+				   struct attribute_group *ag)
+{
+	int i;
+
+	for (i = 0; groups[i]; i++) {
+		if (groups[i] == ag) {
+			for (i++; groups[i]; i++)
+				groups[i - 1] = groups[i];
+			groups[i - 1] = NULL;
+			break;
+		}
+	}
+}
+
 static int
 pmu_iio_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag)
 {
@@ -3852,7 +3867,7 @@ clear_attrs:
 clear_topology:
 	kfree(type->topology);
 clear_attr_update:
-	type->attr_update = NULL;
+	pmu_clear_mapping_attr(type->attr_update, ag);
 	return ret;
 }
 
author maintainer
#70 lore raw

PATCH 67/290 arm64: dts: qcom: sdm845-db845c: correct SPI2 pins drive strength

In reply to Greg Kroah-Hartman

From: Krzysztof Kozlowski <[email protected]>

commit 9905370560d9c29adc15f4937c5a0c0dac05f0b4 upstream.

The pin configuration (done with generic pin controller helpers and as expressed by bindings) requires children nodes with either:
1. "pins" property and the actual configuration,
2. another set of nodes with above point.

The qup_spi2_default pin configuration uses alreaady the second method with a "pinmux" child, so configure drive-strength similarly in "pinconf". Otherwise the PIN drive strength would not be applied.

---
 arch/arm64/boot/dts/qcom/sdm845-db845c.dts |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845-db845c.dts +4 -1
@@ -1045,7 +1045,10 @@
 
 /* PINCTRL - additions to nodes defined in sdm845.dtsi */
 &qup_spi2_default {
-	drive-strength = <16>;
+	pinconf {
+		pins = "gpio27", "gpio28", "gpio29", "gpio30";
+		drive-strength = <16>;
+	};
 };
 
 &qup_uart3_default{
author maintainer
#71 lore raw

PATCH 68/290 mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K

In reply to Greg Kroah-Hartman

From: Wenchao Chen <[email protected]>

commit ff874dbc4f868af128b412a9bd92637103cf11d7 upstream.

When the clock is less than 400K, some SD cards fail to initialize because CLK_AUTO is enabled.

Fixes fb8bd90f83c4 ("mmc: sdhci-sprd: Add Spreadtrum's initial host controller")
---
 drivers/mmc/host/sdhci-sprd.c |   16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/mmc/host/sdhci-sprd.c +9 -7
@@ -224,13 +224,15 @@ static inline void _sdhci_sprd_set_clock
 	div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
 	sdhci_enable_clk(host, div);
 
-	/* enable auto gate sdhc_enable_auto_gate */
-	val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
-	mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
-	       SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
-	if (mask != (val & mask)) {
-		val |= mask;
-		sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
+	/* Enable CLK_AUTO when the clock is greater than 400K. */
+	if (clk > 400000) {
+		val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
+		mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN |
+			SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN;
+		if (mask != (val & mask)) {
+			val |= mask;
+			sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI);
+		}
 	}
 }
 
author maintainer
#72 lore raw

PATCH 69/290 btrfs: fix resolving backrefs for inline extent followed by prealloc

In reply to Greg Kroah-Hartman

From: Boris Burkov <[email protected]>

commit 560840afc3e63bbe5d9c5ef6b2ecf8f3589adff6 upstream.

If a file consists of an inline extent followed by a regular or prealloc extent, then a legitimate attempt to resolve a logical address in the non-inline region will result in add_all_parents reading the invalid offset field of the inline extent. If the inline extent item is placed in the leaf eb s.t. it is the first item, attempting to access the offset field will not only be meaningless, it will go past the end of the eb and cause this panic:

  [17.626048] BTRFS warning (device dm-2): bad eb member end: ptr 0x3fd4 start 30834688 member offset 16377 size 8
  [17.631693] general protection fault, probably for non-canonical address 0x5088000000000: 0000 [#1] SMP PTI
  [17.635041] CPU: 2 PID: 1267 Comm: btrfs Not tainted 5.12.0-07246-g75175d5adc74-dirty #199
  [17.637969] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
  [17.641995] RIP: 0010:btrfs_get_64+0xe7/0x110
  [17.649890] RSP: 0018:ffffc90001f73a08 EFLAGS: 00010202
  [17.651652] RAX: 0000000000000001 RBX: ffff88810c42d000 RCX: 0000000000000000
  [17.653921] RDX: 0005088000000000 RSI: ffffc90001f73a0f RDI: 0000000000000001
  [17.656174] RBP: 0000000000000ff9 R08: 0000000000000007 R09: c0000000fffeffff
  [17.658441] R10: ffffc90001f73790 R11: ffffc90001f73788 R12: ffff888106afe918
  [17.661070] R13: 0000000000003fd4 R14: 0000000000003f6f R15: cdcdcdcdcdcdcdcd
  [17.663617] FS:  00007f64e7627d80(0000) GS:ffff888237c80000(0000) knlGS:0000000000000000
  [17.666525] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  [17.668664] CR2: 000055d4a39152e8 CR3: 000000010c596002 CR4: 0000000000770ee0
  [17.671253] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  [17.673634] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
  [17.676034] PKRU: 55555554
  [17.677004] Call Trace:
  [17.677877]  add_all_parents+0x276/0x480
  [17.679325]  find_parent_nodes+0xfae/0x1590
  [17.680771]  btrfs_find_all_leafs+0x5e/0xa0
  [17.682217]  iterate_extent_inodes+0xce/0x260
  [17.683809]  ? btrfs_inode_flags_to_xflags+0x50/0x50
  [17.685597]  ? iterate_inodes_from_logical+0xa1/0xd0
  [17.687404]  iterate_inodes_from_logical+0xa1/0xd0
  [17.689121]  ? btrfs_inode_flags_to_xflags+0x50/0x50
  [17.691010]  btrfs_ioctl_logical_to_ino+0x131/0x190
  [17.692946]  btrfs_ioctl+0x104a/0x2f60
  [17.694384]  ? selinux_file_ioctl+0x182/0x220
  [17.695995]  ? __x64_sys_ioctl+0x84/0xc0
  [17.697394]  __x64_sys_ioctl+0x84/0xc0
  [17.698697]  do_syscall_64+0x33/0x40
  [17.700017]  entry_SYSCALL_64_after_hwframe+0x44/0xae
  [17.701753] RIP: 0033:0x7f64e72761b7
  [17.709355] RSP: 002b:00007ffefb067f58 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
  [17.712088] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f64e72761b7
  [17.714667] RDX: 00007ffefb067fb0 RSI: 00000000c0389424 RDI: 0000000000000003
  [17.717386] RBP: 00007ffefb06d188 R08: 000055d4a390d2b0 R09: 00007f64e7340a60
  [17.719938] R10: 0000000000000231 R11: 0000000000000246 R12: 0000000000000001
  [17.722383] R13: 0000000000000000 R14: 00000000c0389424 R15: 000055d4a38fd2a0
  [17.724839] Modules linked in:

Fix the bug by detecting the inline extent item in add_all_parents and skipping to the next extent item.

---
 fs/btrfs/backref.c |    4 ++++
 1 file changed, 4 insertions(+)
fs/btrfs/backref.c +4 -0
@@ -433,6 +433,7 @@ static int add_all_parents(struct btrfs_
 	u64 wanted_disk_byte = ref->wanted_disk_byte;
 	u64 count = 0;
 	u64 data_offset;
+	u8 type;
 
 	if (level != 0) {
 		eb = path->nodes[level];
@@ -487,6 +488,9 @@ static int add_all_parents(struct btrfs_
 			continue;
 		}
 		fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
+		type = btrfs_file_extent_type(eb, fi);
+		if (type == BTRFS_FILE_EXTENT_INLINE)
+			goto next;
 		disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
 		data_offset = btrfs_file_extent_offset(eb, fi);
 
author maintainer
#73 lore raw

PATCH 70/290 ARM: ux500: do not directly dereference __iomem

In reply to Greg Kroah-Hartman

From: Jason A. Donenfeld <[email protected]>

commit 65b0e307a1a9193571db12910f382f84195a3d29 upstream.

Sparse reports that calling add_device_randomness() on uid is a violation of address spaces. And indeed the next usage uses readl() properly, but that was left out when passing it toadd_device_ randomness(). So instead copy the whole thing to the stack first.

---
 drivers/soc/ux500/ux500-soc-id.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/soc/ux500/ux500-soc-id.c +4 -6
@@ -167,20 +167,18 @@ ATTRIBUTE_GROUPS(ux500_soc);
 static const char *db8500_read_soc_id(struct device_node *backupram)
 {
 	void __iomem *base;
-	void __iomem *uid;
 	const char *retstr;
+	u32 uid[5];
 
 	base = of_iomap(backupram, 0);
 	if (!base)
 		return NULL;
-	uid = base + 0x1fc0;
+	memcpy_fromio(uid, base + 0x1fc0, sizeof(uid));
 
 	/* Throw these device-specific numbers into the entropy pool */
-	add_device_randomness(uid, 0x14);
+	add_device_randomness(uid, sizeof(uid));
 	retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x",
-			 readl((u32 *)uid+0),
-			 readl((u32 *)uid+1), readl((u32 *)uid+2),
-			 readl((u32 *)uid+3), readl((u32 *)uid+4));
+			   uid[0], uid[1], uid[2], uid[3], uid[4]);
 	iounmap(base);
 	return retstr;
 }
author maintainer
#74 lore raw

PATCH 71/290 arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength

In reply to Greg Kroah-Hartman

From: Krzysztof Kozlowski <[email protected]>

commit fd49776d8f458bba5499384131eddc0b8bcaf50c upstream.

The pin configuration (done with generic pin controller helpers and as expressed by bindings) requires children nodes with either:
1. "pins" property and the actual configuration,
2. another set of nodes with above point.

The qup_i2c12_default pin configuration used second method - with a "pinmux" child.

---
 arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +4 -2
@@ -475,8 +475,10 @@
 };
 
 &qup_i2c12_default {
-	drive-strength = <2>;
-	bias-disable;
+	pinmux {
+		drive-strength = <2>;
+		bias-disable;
+	};
 };
 
 &qup_uart6_default {
author maintainer
#75 lore raw

PATCH 72/290 selftests: Use optional USERCFLAGS and USERLDFLAGS

In reply to Greg Kroah-Hartman

From: Mickaël Salaün <[email protected]>

commit de3ee3f63400a23954e7c1ad1cb8c20f29ab6fe3 upstream.

This change enables to extend CFLAGS and LDFLAGS from command line, e.g. to extend compiler checks: make USERCFLAGS=-Werror USERLDFLAGS=-static

USERCFLAGS and USERLDFLAGS are documented in Documentation/kbuild/makefiles.rst and Documentation/kbuild/kbuild.rst

This should be backported (down to 5.10) to improve previous kernel versions testing as well.

---
 tools/testing/selftests/lib.mk |    5 +++++
 1 file changed, 5 insertions(+)
tools/testing/selftests/lib.mk +5 -0
@@ -129,6 +129,11 @@ endef
 clean:
 	$(CLEAN)
 
+# Enables to extend CFLAGS and LDFLAGS from command line, e.g.
+# make USERCFLAGS=-Werror USERLDFLAGS=-static
+CFLAGS += $(USERCFLAGS)
+LDFLAGS += $(USERLDFLAGS)
+
 # When make O= with kselftest target from main level
 # the following aren't defined.
 #
author maintainer
#76 lore raw

PATCH 73/290 PM/devfreq: governor: Add a private governor_data for governor

In reply to Greg Kroah-Hartman

From: Kant Fan <[email protected]>

commit 5fdded8448924e3631d466eea499b11606c43640 upstream.

The member void *data in the structure devfreq can be overwrite by governor_userspace. For example:
1. The device driver assigned the devfreq governor to simple_ondemand by the function devfreq_add_device() and init the devfreq member void *data to a pointer of a static structure devfreq_simple_ondemand_data by the function devfreq_add_device().
2. The user changed the devfreq governor to userspace by the command "echo userspace > /sys/class/devfreq/.../governor".
3. The governor userspace alloced a dynamic memory for the struct userspace_data and assigend the member void *data of devfreq to this memory by the function userspace_init().
4. The user changed the devfreq governor back to simple_ondemand by the command "echo simple_ondemand > /sys/class/devfreq/.../governor".
5. The governor userspace exited and assigned the member void *data in the structure devfreq to NULL by the function userspace_exit().
6. The governor simple_ondemand fetched the static information of devfreq_simple_ondemand_data in the function devfreq_simple_ondemand_func() but the member void *data of devfreq was assigned to NULL by the function userspace_exit().
7. The information of upthreshold and downdifferential is lost and the governor simple_ondemand can't work correctly.

The member void *data in the structure devfreq is designed for a static pointer used in a governor and inited by the function devfreq_add_device(). This patch add an element named governor_data in the devfreq structure which can be used by a governor(E.g userspace) who want to assign a private data to do some private things.

Fixes ce26c5bb9569 ("PM / devfreq: Add basic governors")
---
 drivers/devfreq/devfreq.c            |    6 ++----
 drivers/devfreq/governor_userspace.c |   12 ++++++------
 include/linux/devfreq.h              |    7 ++++---
 3 files changed, 12 insertions(+), 13 deletions(-)
drivers/devfreq/devfreq.c +2 -4
@@ -775,8 +775,7 @@ static void remove_sysfs_files(struct de
  * @dev:	the device to add devfreq feature.
  * @profile:	device-specific profile to run devfreq.
  * @governor_name:	name of the policy to choose frequency.
- * @data:	private data for the governor. The devfreq framework does not
- *		touch this value.
+ * @data:	devfreq driver pass to governors, governor should not change it.
  */
 struct devfreq *devfreq_add_device(struct device *dev,
 				   struct devfreq_dev_profile *profile,
@@ -1003,8 +1002,7 @@ static void devm_devfreq_dev_release(str
  * @dev:	the device to add devfreq feature.
  * @profile:	device-specific profile to run devfreq.
  * @governor_name:	name of the policy to choose frequency.
- * @data:	private data for the governor. The devfreq framework does not
- *		touch this value.
+ * @data:	 devfreq driver pass to governors, governor should not change it.
  *
  * This function manages automatically the memory of devfreq device using device
  * resource management and simplify the free operation for memory of devfreq
drivers/devfreq/governor_userspace.c +6 -6
@@ -21,7 +21,7 @@ struct userspace_data {
 
 static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq)
 {
-	struct userspace_data *data = df->data;
+	struct userspace_data *data = df->governor_data;
 
 	if (data->valid)
 		*freq = data->user_frequency;
@@ -40,7 +40,7 @@ static ssize_t set_freq_store(struct dev
 	int err = 0;
 
 	mutex_lock(&devfreq->lock);
-	data = devfreq->data;
+	data = devfreq->governor_data;
 
 	sscanf(buf, "%lu", &wanted);
 	data->user_frequency = wanted;
@@ -60,7 +60,7 @@ static ssize_t set_freq_show(struct devi
 	int err = 0;
 
 	mutex_lock(&devfreq->lock);
-	data = devfreq->data;
+	data = devfreq->governor_data;
 
 	if (data->valid)
 		err = sprintf(buf, "%lu\n", data->user_frequency);
@@ -91,7 +91,7 @@ static int userspace_init(struct devfreq
 		goto out;
 	}
 	data->valid = false;
-	devfreq->data = data;
+	devfreq->governor_data = data;
 
 	err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group);
 out:
@@ -107,8 +107,8 @@ static void userspace_exit(struct devfre
 	if (devfreq->dev.kobj.sd)
 		sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group);
 
-	kfree(devfreq->data);
-	devfreq->data = NULL;
+	kfree(devfreq->governor_data);
+	devfreq->governor_data = NULL;
 }
 
 static int devfreq_userspace_handler(struct devfreq *devfreq,
include/linux/devfreq.h +4 -3
@@ -149,8 +149,8 @@ struct devfreq_stats {
  * @work:	delayed work for load monitoring.
  * @previous_freq:	previously configured frequency value.
  * @last_status:	devfreq user device info, performance statistics
- * @data:	Private data of the governor. The devfreq framework does not
- *		touch this.
+ * @data:	devfreq driver pass to governors, governor should not change it.
+ * @governor_data:	private data for governors, devfreq core doesn't touch it.
  * @user_min_freq_req:	PM QoS minimum frequency request from user (via sysfs)
  * @user_max_freq_req:	PM QoS maximum frequency request from user (via sysfs)
  * @scaling_min_freq:	Limit minimum frequency requested by OPP interface
@@ -187,7 +187,8 @@ struct devfreq {
 	unsigned long previous_freq;
 	struct devfreq_dev_status last_status;
 
-	void *data; /* private data for governors */
+	void *data;
+	void *governor_data;
 
 	struct dev_pm_qos_request user_min_freq_req;
 	struct dev_pm_qos_request user_max_freq_req;
author maintainer
#77 lore raw

PATCH 74/290 cpufreq: Init completion before kobject_init_and_add()

In reply to Greg Kroah-Hartman

From: Yongqiang Liu <[email protected]>

commit 5c51054896bcce1d33d39fead2af73fec24f40b6 upstream.

In cpufreq_policy_alloc(), it will call uninitialed completion in cpufreq_sysfs_release() when kobject_init_and_add() fails. And that will cause a crash such as the following page fault in complete:

BUG: unable to handle page fault for address: fffffffffffffff8
[..]
RIP: 0010:complete+0x98/0x1f0
[..]
Call Trace:
 kobject_put+0x1be/0x4c0
 cpufreq_online.cold+0xee/0x1fd
 cpufreq_add_dev+0x183/0x1e0
 subsys_interface_register+0x3f5/0x4e0
 cpufreq_register_driver+0x3b7/0x670
 acpi_cpufreq_init+0x56c/0x1000 [acpi_cpufreq]
 do_one_initcall+0x13d/0x780
 do_init_module+0x1c3/0x630
 load_module+0x6e67/0x73b0
 __do_sys_finit_module+0x181/0x240
 do_syscall_64+0x35/0x80
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Fixes 4ebe36c94aed ("cpufreq: Fix kobject memleak")
Cc 5.2+ <[email protected]> # 5.2+
---
 drivers/cpufreq/cpufreq.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cpufreq.c +1 -1
@@ -1212,6 +1212,7 @@ static struct cpufreq_policy *cpufreq_po
 	if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
 		goto err_free_rcpumask;
 
+	init_completion(&policy->kobj_unregister);
 	ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
 				   cpufreq_global_kobject, "policy%u", cpu);
 	if (ret) {
@@ -1250,7 +1251,6 @@ static struct cpufreq_policy *cpufreq_po
 	init_rwsem(&policy->rwsem);
 	spin_lock_init(&policy->transition_lock);
 	init_waitqueue_head(&policy->transition_wait);
-	init_completion(&policy->kobj_unregister);
 	INIT_WORK(&policy->update, handle_update);
 
 	policy->cpu = cpu;
author maintainer
#78 lore raw

PATCH 75/290 ALSA: patch_realtek: Fix Dell Inspiron Plus 16

In reply to Greg Kroah-Hartman

From: Philipp Jungkamp <[email protected]>

[ Upstream commit 2912cdda734d9136615ed05636d9fcbca2a7a3c5 ]

The Dell Inspiron Plus 16, in both laptop and 2in1 form factor, has top speakers connected on NID 0x17, which the codec reports as unconnected. These speakers should be connected to the DAC on NID 0x03.

Stable-dep-of: a4517c4f3423 ("ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops")

---
 sound/pci/hda/patch_realtek.c | 37 +++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
sound/pci/hda/patch_realtek.c +37 -0
index 79c65da1b4ee..f74c49987f1a 100644
@@ -6709,6 +6709,34 @@ static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
 	}
 }
 
+static void alc295_fixup_dell_inspiron_top_speakers(struct hda_codec *codec,
+					  const struct hda_fixup *fix, int action)
+{
+	static const struct hda_pintbl pincfgs[] = {
+		{ 0x14, 0x90170151 },
+		{ 0x17, 0x90170150 },
+		{ }
+	};
+	static const hda_nid_t conn[] = { 0x02, 0x03 };
+	static const hda_nid_t preferred_pairs[] = {
+		0x14, 0x02,
+		0x17, 0x03,
+		0x21, 0x02,
+		0
+	};
+	struct alc_spec *spec = codec->spec;
+
+	alc_fixup_no_shutup(codec, fix, action);
+
+	switch (action) {
+	case HDA_FIXUP_ACT_PRE_PROBE:
+		snd_hda_apply_pincfgs(codec, pincfgs);
+		snd_hda_override_conn_list(codec, 0x17, ARRAY_SIZE(conn), conn);
+		spec->gen.preferred_dacs = preferred_pairs;
+		break;
+	}
+}
+
 enum {
 	ALC269_FIXUP_GPIO2,
 	ALC269_FIXUP_SONY_VAIO,
@@ -6940,6 +6968,7 @@ enum {
 	ALC285_FIXUP_LEGION_Y9000X_SPEAKERS,
 	ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
 	ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
+	ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -8766,6 +8795,12 @@ static const struct hda_fixup alc269_fixups[] = {
 		.chained = true,
 		.chain_id = ALC285_FIXUP_HP_MUTE_LED,
 	},
+	[ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc295_fixup_dell_inspiron_top_speakers,
+		.chained = true,
+		.chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
+	},
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8865,6 +8900,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x0b19, "Dell XPS 15 9520", ALC289_FIXUP_DUAL_SPK),
 	SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
+	SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
+	SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Signature · 1 line
2.35.1
author maintainer
#79 lore raw

PATCH 76/290 ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops

In reply to Greg Kroah-Hartman

From: Chris Chiu <[email protected]>

[ Upstream commit a4517c4f3423c7c448f2c359218f97c1173523a1 ]

The Dell Latiture 3340/3440/3540 laptops with Realtek ALC3204 have dual codecs and need the ALC1220_FIXUP_GB_DUAL_CODECS to fix the conflicts of Master controls. The existing headset mic fixup for Dell is also required to enable the jack sense and the headset mic.

Introduce a new fixup to fix the dual codec and headset mic issues for particular Dell laptops since other old Dell laptops with the same codec configuration are already well handled by the fixup in alc269_fallback_pin_fixup_tbl[].

---
 sound/pci/hda/patch_realtek.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)
sound/pci/hda/patch_realtek.c +13 -0
index f74c49987f1a..642e212278ac 100644
@@ -6969,6 +6969,7 @@ enum {
 	ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
 	ALC285_FIXUP_HP_SPEAKERS_MICMUTE_LED,
 	ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS,
+	ALC236_FIXUP_DELL_DUAL_CODECS,
 };
 
 /* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -8801,6 +8802,12 @@ static const struct hda_fixup alc269_fixups[] = {
 		.chained = true,
 		.chain_id = ALC269_FIXUP_DELL4_MIC_NO_PRESENCE,
 	},
+	[ALC236_FIXUP_DELL_DUAL_CODECS] = {
+		.type = HDA_FIXUP_PINS,
+		.v.func = alc1220_fixup_gb_dual_codecs,
+		.chained = true,
+		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+	},
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -8902,6 +8909,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK),
 	SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
 	SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS),
+	SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1c, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1d, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS),
+	SND_PCI_QUIRK(0x1028, 0x0c1e, "Dell Precision 3540", ALC236_FIXUP_DELL_DUAL_CODECS),
 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
Signature · 1 line
2.35.1
author maintainer
#80 lore raw

PATCH 77/290 fs: dlm: fix sock release if listen fails

In reply to Greg Kroah-Hartman

From: Alexander Aring <[email protected]>

commit 08ae0547e75ec3d062b6b6b9cf4830c730df68df upstream.

This patch fixes a double sock_release() call when the listen() is called for the dlm lowcomms listen socket. The caller of dlm_listen_for_all should never care about releasing the socket if dlm_listen_for_all() fails, it's done now only once if listen() fails.

Fixes 2dc6b1158c28 ("fs: dlm: introduce generic listen")
---
 fs/dlm/lowcomms.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
fs/dlm/lowcomms.c +1 -2
@@ -1797,7 +1797,7 @@ static int dlm_listen_for_all(void)
 	result = sock->ops->listen(sock, 5);
 	if (result < 0) {
 		dlm_close_sock(&listen_con.sock);
-		goto out;
+		return result;
 	}
 
 	return 0;
@@ -2000,7 +2000,6 @@ fail_listen:
 	dlm_proto_ops = NULL;
 fail_proto_ops:
 	dlm_allow_conn = 0;
-	dlm_close_sock(&listen_con.sock);
 	work_stop();
 fail_local:
 	deinit_local();
author maintainer
#81 lore raw

PATCH 78/290 fs: dlm: retry accept() until -EAGAIN or error returns

In reply to Greg Kroah-Hartman

From: Alexander Aring <[email protected]>

commit f0f4bb431bd543ed7bebbaea3ce326cfcd5388bc upstream.

This patch fixes a race if we get two times an socket data ready event while the listen connection worker is queued. Currently it will be served only once but we need to do it (in this case twice) until we hit -EAGAIN which tells us there is no pending accept going on.

This patch wraps an do while loop until we receive a return value which is different than 0 as it was done before commit d11ccd451b65 ("fs: dlm:
listen socket out of connection hash").

Fixes d11ccd451b65 ("fs: dlm: listen socket out of connection hash")
---
 fs/dlm/lowcomms.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
fs/dlm/lowcomms.c +5 -1
@@ -1520,7 +1520,11 @@ static void process_recv_sockets(struct
 
 static void process_listen_recv_socket(struct work_struct *work)
 {
-	accept_from_sock(&listen_con);
+	int ret;
+
+	do {
+		ret = accept_from_sock(&listen_con);
+	} while (!ret);
 }
 
 static void dlm_connect(struct connection *con)
author maintainer
#82 lore raw

PATCH 79/290 mptcp: mark ops structures as ro_after_init

In reply to Greg Kroah-Hartman

From: Florian Westphal <[email protected]>

commit 51fa7f8ebf0e25c7a9039fa3988a623d5f3855aa upstream.

These structures are initialised from the init hooks, so we can't make them 'const'. But no writes occur afterwards, so we can use ro_after_init.

Also, remove bogus EXPORT_SYMBOL, the only access comes from ip stack, not from kernel modules.

---
 net/mptcp/subflow.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)
net/mptcp/subflow.c +7 -8
@@ -484,8 +484,7 @@ do_reset:
 }
 
 struct request_sock_ops mptcp_subflow_request_sock_ops;
-EXPORT_SYMBOL_GPL(mptcp_subflow_request_sock_ops);
-static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops;
+static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
 
 static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
@@ -506,9 +505,9 @@ drop:
 }
 
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
-static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops;
-static struct inet_connection_sock_af_ops subflow_v6_specific;
-static struct inet_connection_sock_af_ops subflow_v6m_specific;
+static struct tcp_request_sock_ops subflow_request_sock_ipv6_ops __ro_after_init;
+static struct inet_connection_sock_af_ops subflow_v6_specific __ro_after_init;
+static struct inet_connection_sock_af_ops subflow_v6m_specific __ro_after_init;
 static struct proto tcpv6_prot_override;
 
 static int subflow_v6_conn_request(struct sock *sk, struct sk_buff *skb)
@@ -790,7 +789,7 @@ dispose_child:
 	return child;
 }
 
-static struct inet_connection_sock_af_ops subflow_specific;
+static struct inet_connection_sock_af_ops subflow_specific __ro_after_init;
 static struct proto tcp_prot_override;
 
 enum mapping_status {
@@ -1327,7 +1326,7 @@ static void subflow_write_space(struct s
 	mptcp_write_space(sk);
 }
 
-static struct inet_connection_sock_af_ops *
+static const struct inet_connection_sock_af_ops *
 subflow_default_af_ops(struct sock *sk)
 {
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
@@ -1342,7 +1341,7 @@ void mptcpv6_handle_mapped(struct sock *
 {
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
-	struct inet_connection_sock_af_ops *target;
+	const struct inet_connection_sock_af_ops *target;
 
 	target = mapped ? &subflow_v6m_specific : subflow_default_af_ops(sk);
 
author maintainer
#83 lore raw

PATCH 80/290 mptcp: remove MPTCP ifdef in TCP SYN cookies

In reply to Greg Kroah-Hartman

From: Matthieu Baerts <[email protected]>

commit 3fff88186f047627bb128d65155f42517f8e448f upstream.

To ease the maintenance, it is often recommended to avoid having #ifdef preprocessor conditions.

Here the section related to CONFIG_MPTCP was quite short but the next commit needs to add more code around. It is then cleaner to move specific MPTCP code to functions located in net/mptcp directory.

Now that mptcp_subflow_request_sock_ops structure can be static, it can also be marked as "read only after init".

---
 include/net/mptcp.h   |   12 ++++++++++--
 net/ipv4/syncookies.c |    7 +++----
 net/mptcp/subflow.c   |   12 +++++++++++-
 3 files changed, 24 insertions(+), 7 deletions(-)
include/net/mptcp.h +10 -2
@@ -93,8 +93,6 @@ struct mptcp_out_options {
 };
 
 #ifdef CONFIG_MPTCP
-extern struct request_sock_ops mptcp_subflow_request_sock_ops;
-
 void mptcp_init(void);
 
 static inline bool sk_is_mptcp(const struct sock *sk)
@@ -182,6 +180,9 @@ void mptcp_seq_show(struct seq_file *seq
 int mptcp_subflow_init_cookie_req(struct request_sock *req,
 				  const struct sock *sk_listener,
 				  struct sk_buff *skb);
+struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
+					       struct sock *sk_listener,
+					       bool attach_listener);
 
 __be32 mptcp_get_reset_option(const struct sk_buff *skb);
 
@@ -274,6 +275,13 @@ static inline int mptcp_subflow_init_coo
 	return 0; /* TCP fallback */
 }
 
+static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
+							     struct sock *sk_listener,
+							     bool attach_listener)
+{
+	return NULL;
+}
+
 static inline __be32 mptcp_reset_option(const struct sk_buff *skb)  { return htonl(0u); }
 #endif /* CONFIG_MPTCP */
 
net/ipv4/syncookies.c +3 -4
@@ -290,12 +290,11 @@ struct request_sock *cookie_tcp_reqsk_al
 	struct tcp_request_sock *treq;
 	struct request_sock *req;
 
-#ifdef CONFIG_MPTCP
 	if (sk_is_mptcp(sk))
-		ops = &mptcp_subflow_request_sock_ops;
-#endif
+		req = mptcp_subflow_reqsk_alloc(ops, sk, false);
+	else
+		req = inet_reqsk_alloc(ops, sk, false);
 
-	req = inet_reqsk_alloc(ops, sk, false);
 	if (!req)
 		return NULL;
 
net/mptcp/subflow.c +11 -1
@@ -483,7 +483,7 @@ do_reset:
 	mptcp_subflow_reset(sk);
 }
 
-struct request_sock_ops mptcp_subflow_request_sock_ops;
+static struct request_sock_ops mptcp_subflow_request_sock_ops __ro_after_init;
 static struct tcp_request_sock_ops subflow_request_sock_ipv4_ops __ro_after_init;
 
 static int subflow_v4_conn_request(struct sock *sk, struct sk_buff *skb)
@@ -536,6 +536,16 @@ drop:
 }
 #endif
 
+struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
+					       struct sock *sk_listener,
+					       bool attach_listener)
+{
+	ops = &mptcp_subflow_request_sock_ops;
+
+	return inet_reqsk_alloc(ops, sk_listener, attach_listener);
+}
+EXPORT_SYMBOL(mptcp_subflow_reqsk_alloc);
+
 /* validate hmac received in third ACK */
 static bool subflow_hmac_valid(const struct request_sock *req,
 			       const struct mptcp_options_received *mp_opt)
author maintainer
#84 lore raw

PATCH 81/290 dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort

In reply to Greg Kroah-Hartman

From: Mike Snitzer <[email protected]>

commit 352b837a5541690d4f843819028cf2b8be83d424 upstream.

Same ABBA deadlock pattern fixed in commit 4b60f452ec51 ("dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata") to DM-cache's metadata.

Fixes 028ae9f76f29 ("dm cache: add fail io mode and needs_check flag")
---
 drivers/md/dm-cache-metadata.c |   54 +++++++++++++++++++++++++++++++++++------
 1 file changed, 47 insertions(+), 7 deletions(-)
drivers/md/dm-cache-metadata.c +47 -7
@@ -551,11 +551,13 @@ static int __create_persistent_data_obje
 	return r;
 }
 
-static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd)
+static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd,
+					      bool destroy_bm)
 {
 	dm_sm_destroy(cmd->metadata_sm);
 	dm_tm_destroy(cmd->tm);
-	dm_block_manager_destroy(cmd->bm);
+	if (destroy_bm)
+		dm_block_manager_destroy(cmd->bm);
 }
 
 typedef unsigned long (*flags_mutator)(unsigned long);
@@ -826,7 +828,7 @@ static struct dm_cache_metadata *lookup_
 		cmd2 = lookup(bdev);
 		if (cmd2) {
 			mutex_unlock(&table_lock);
-			__destroy_persistent_data_objects(cmd);
+			__destroy_persistent_data_objects(cmd, true);
 			kfree(cmd);
 			return cmd2;
 		}
@@ -874,7 +876,7 @@ void dm_cache_metadata_close(struct dm_c
 		mutex_unlock(&table_lock);
 
 		if (!cmd->fail_io)
-			__destroy_persistent_data_objects(cmd);
+			__destroy_persistent_data_objects(cmd, true);
 		kfree(cmd);
 	}
 }
@@ -1808,14 +1810,52 @@ int dm_cache_metadata_needs_check(struct
 
 int dm_cache_metadata_abort(struct dm_cache_metadata *cmd)
 {
-	int r;
+	int r = -EINVAL;
+	struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
+
+	/* fail_io is double-checked with cmd->root_lock held below */
+	if (unlikely(cmd->fail_io))
+		return r;
+
+	/*
+	 * Replacement block manager (new_bm) is created and old_bm destroyed outside of
+	 * cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
+	 * shrinker associated with the block manager's bufio client vs cmd root_lock).
+	 * - must take shrinker_rwsem without holding cmd->root_lock
+	 */
+	new_bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
+					 CACHE_MAX_CONCURRENT_LOCKS);
 
 	WRITE_LOCK(cmd);
-	__destroy_persistent_data_objects(cmd);
-	r = __create_persistent_data_objects(cmd, false);
+	if (cmd->fail_io) {
+		WRITE_UNLOCK(cmd);
+		goto out;
+	}
+
+	__destroy_persistent_data_objects(cmd, false);
+	old_bm = cmd->bm;
+	if (IS_ERR(new_bm)) {
+		DMERR("could not create block manager during abort");
+		cmd->bm = NULL;
+		r = PTR_ERR(new_bm);
+		goto out_unlock;
+	}
+
+	cmd->bm = new_bm;
+	r = __open_or_format_metadata(cmd, false);
+	if (r) {
+		cmd->bm = NULL;
+		goto out_unlock;
+	}
+	new_bm = NULL;
+out_unlock:
 	if (r)
 		cmd->fail_io = true;
 	WRITE_UNLOCK(cmd);
+	dm_block_manager_destroy(old_bm);
+out:
+	if (new_bm && !IS_ERR(new_bm))
+		dm_block_manager_destroy(new_bm);
 
 	return r;
 }
author maintainer
#85 lore raw

PATCH 82/290 dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata

In reply to Greg Kroah-Hartman

From: Zhihao Cheng <[email protected]>

commit 8111964f1b8524c4bb56b02cd9c7a37725ea21fd upstream.

Following concurrent processes:

P1(drop cache) P2(kworker)
drop_caches_sysctl_handler
drop_slab
shrink_slab
down_read(&shrinker_rwsem) - LOCK A
do_shrink_slab

    super_cache_scan
     prune_icache_sb
      dispose_list
       evict
        ext4_evict_inode
	 ext4_clear_inode
	  ext4_discard_preallocations
	   ext4_mb_load_buddy_gfp
	    ext4_mb_init_cache
	     ext4_read_block_bitmap_nowait
	      ext4_read_bh_nowait
	       submit_bh
	        dm_submit_bio
		                 do_worker
				  process_deferred_bios
				   commit
				    metadata_operation_failed
				     dm_pool_abort_metadata
				      down_write(&pmd->root_lock) - LOCK B
		                      __destroy_persistent_data_objects
				       dm_block_manager_destroy
				        dm_bufio_client_destroy
				         unregister_shrinker
					  down_write(&shrinker_rwsem)
		 thin_map                            |
		  dm_thin_find_block                 ↓
		   down_read(&pmd->root_lock) --> ABBA deadlock

, which triggers hung task:

[   76.974820] INFO: task kworker/u4:3:63 blocked for more than 15 seconds.
[   76.976019]       Not tainted 6.1.0-rc4-00011-g8f17dd350364-dirty #910
[   76.978521] task:kworker/u4:3    state:D stack:0     pid:63    ppid:2
[   76.978534] Workqueue: dm-thin do_worker
[   76.978552] Call Trace:
[   76.978564]  __schedule+0x6ba/0x10f0
[   76.978582]  schedule+0x9d/0x1e0
[   76.978588]  rwsem_down_write_slowpath+0x587/0xdf0
[   76.978600]  down_write+0xec/0x110
[   76.978607]  unregister_shrinker+0x2c/0xf0
[   76.978616]  dm_bufio_client_destroy+0x116/0x3d0
[   76.978625]  dm_block_manager_destroy+0x19/0x40
[   76.978629]  __destroy_persistent_data_objects+0x5e/0x70
[   76.978636]  dm_pool_abort_metadata+0x8e/0x100
[   76.978643]  metadata_operation_failed+0x86/0x110
[   76.978649]  commit+0x6a/0x230
[   76.978655]  do_worker+0xc6e/0xd90
[   76.978702]  process_one_work+0x269/0x630
[   76.978714]  worker_thread+0x266/0x630
[   76.978730]  kthread+0x151/0x1b0
[   76.978772] INFO: task test.sh:2646 blocked for more than 15 seconds.
[   76.979756]       Not tainted 6.1.0-rc4-00011-g8f17dd350364-dirty #910
[   76.982111] task:test.sh         state:D stack:0     pid:2646  ppid:2459
[   76.982128] Call Trace:
[   76.982139]  __schedule+0x6ba/0x10f0
[   76.982155]  schedule+0x9d/0x1e0
[   76.982159]  rwsem_down_read_slowpath+0x4f4/0x910
[   76.982173]  down_read+0x84/0x170
[   76.982177]  dm_thin_find_block+0x4c/0xd0
[   76.982183]  thin_map+0x201/0x3d0
[   76.982188]  __map_bio+0x5b/0x350
[   76.982195]  dm_submit_bio+0x2b6/0x930
[   76.982202]  __submit_bio+0x123/0x2d0
[   76.982209]  submit_bio_noacct_nocheck+0x101/0x3e0
[   76.982222]  submit_bio_noacct+0x389/0x770
[   76.982227]  submit_bio+0x50/0xc0
[   76.982232]  submit_bh_wbc+0x15e/0x230
[   76.982238]  submit_bh+0x14/0x20
[   76.982241]  ext4_read_bh_nowait+0xc5/0x130
[   76.982247]  ext4_read_block_bitmap_nowait+0x340/0xc60
[   76.982254]  ext4_mb_init_cache+0x1ce/0xdc0
[   76.982259]  ext4_mb_load_buddy_gfp+0x987/0xfa0
[   76.982263]  ext4_discard_preallocations+0x45d/0x830
[   76.982274]  ext4_clear_inode+0x48/0xf0
[   76.982280]  ext4_evict_inode+0xcf/0xc70
[   76.982285]  evict+0x119/0x2b0
[   76.982290]  dispose_list+0x43/0xa0
[   76.982294]  prune_icache_sb+0x64/0x90
[   76.982298]  super_cache_scan+0x155/0x210
[   76.982303]  do_shrink_slab+0x19e/0x4e0
[   76.982310]  shrink_slab+0x2bd/0x450
[   76.982317]  drop_slab+0xcc/0x1a0
[   76.982323]  drop_caches_sysctl_handler+0xb7/0xe0
[   76.982327]  proc_sys_call_handler+0x1bc/0x300
[   76.982331]  proc_sys_write+0x17/0x20
[   76.982334]  vfs_write+0x3d3/0x570
[   76.982342]  ksys_write+0x73/0x160
[   76.982347]  __x64_sys_write+0x1e/0x30
[   76.982352]  do_syscall_64+0x35/0x80
[   76.982357]  entry_SYSCALL_64_after_hwframe+0x63/0xcd

Function metadata_operation_failed() is called when operations failed on dm pool metadata, dm pool will destroy and recreate metadata. So, shrinker will be unregistered and registered, which could down write shrinker_rwsem under pmd_write_lock.

Fix it by allocating dm_block_manager before locking pmd->root_lock and destroying old dm_block_manager after unlocking pmd->root_lock, then old dm_block_manager is replaced with new dm_block_manager under pmd->root_lock. So, shrinker register/unregister could be done without holding pmd->root_lock.

Fetch a reproducer in [Link].

Fixes e49e582965b3 ("dm thin: add read only and fail io modes")
---
 drivers/md/dm-thin-metadata.c |   51 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 8 deletions(-)
drivers/md/dm-thin-metadata.c +43 -8
@@ -776,13 +776,15 @@ static int __create_persistent_data_obje
 	return r;
 }
 
-static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd)
+static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd,
+					      bool destroy_bm)
 {
 	dm_sm_destroy(pmd->data_sm);
 	dm_sm_destroy(pmd->metadata_sm);
 	dm_tm_destroy(pmd->nb_tm);
 	dm_tm_destroy(pmd->tm);
-	dm_block_manager_destroy(pmd->bm);
+	if (destroy_bm)
+		dm_block_manager_destroy(pmd->bm);
 }
 
 static int __begin_transaction(struct dm_pool_metadata *pmd)
@@ -989,7 +991,7 @@ int dm_pool_metadata_close(struct dm_poo
 	}
 	pmd_write_unlock(pmd);
 	if (!pmd->fail_io)
-		__destroy_persistent_data_objects(pmd);
+		__destroy_persistent_data_objects(pmd, true);
 
 	kfree(pmd);
 	return 0;
@@ -1888,19 +1890,52 @@ static void __set_abort_with_changes_fla
 int dm_pool_abort_metadata(struct dm_pool_metadata *pmd)
 {
 	int r = -EINVAL;
+	struct dm_block_manager *old_bm = NULL, *new_bm = NULL;
+
+	/* fail_io is double-checked with pmd->root_lock held below */
+	if (unlikely(pmd->fail_io))
+		return r;
+
+	/*
+	 * Replacement block manager (new_bm) is created and old_bm destroyed outside of
+	 * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of
+	 * shrinker associated with the block manager's bufio client vs pmd root_lock).
+	 * - must take shrinker_rwsem without holding pmd->root_lock
+	 */
+	new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT,
+					 THIN_MAX_CONCURRENT_LOCKS);
 
 	pmd_write_lock(pmd);
-	if (pmd->fail_io)
+	if (pmd->fail_io) {
+		pmd_write_unlock(pmd);
 		goto out;
+	}
 
 	__set_abort_with_changes_flags(pmd);
-	__destroy_persistent_data_objects(pmd);
-	r = __create_persistent_data_objects(pmd, false);
+	__destroy_persistent_data_objects(pmd, false);
+	old_bm = pmd->bm;
+	if (IS_ERR(new_bm)) {
+		DMERR("could not create block manager during abort");
+		pmd->bm = NULL;
+		r = PTR_ERR(new_bm);
+		goto out_unlock;
+	}
+
+	pmd->bm = new_bm;
+	r = __open_or_format_metadata(pmd, false);
+	if (r) {
+		pmd->bm = NULL;
+		goto out_unlock;
+	}
+	new_bm = NULL;
+out_unlock:
 	if (r)
 		pmd->fail_io = true;
-
-out:
 	pmd_write_unlock(pmd);
+	dm_block_manager_destroy(old_bm);
+out:
+	if (new_bm && !IS_ERR(new_bm))
+		dm_block_manager_destroy(new_bm);
 
 	return r;
 }
author maintainer
#86 lore raw

PATCH 83/290 dm thin: Use last transactions pmd->root when commit failed

In reply to Greg Kroah-Hartman

From: Zhihao Cheng <[email protected]>

commit 7991dbff6849f67e823b7cc0c15e5a90b0549b9f upstream.

Recently we found a softlock up problem in dm thin pool btree lookup code due to corrupted metadata:

 Kernel panic - not syncing: softlockup: hung tasks
 CPU: 7 PID: 2669225 Comm: kworker/u16:3
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
 Workqueue: dm-thin do_worker [dm_thin_pool]
 Call Trace:
   <IRQ>
   dump_stack+0x9c/0xd3
   panic+0x35d/0x6b9
   watchdog_timer_fn.cold+0x16/0x25
   __run_hrtimer+0xa2/0x2d0
   </IRQ>
   RIP: 0010:__relink_lru+0x102/0x220 [dm_bufio]
   __bufio_new+0x11f/0x4f0 [dm_bufio]
   new_read+0xa3/0x1e0 [dm_bufio]
   dm_bm_read_lock+0x33/0xd0 [dm_persistent_data]
   ro_step+0x63/0x100 [dm_persistent_data]
   btree_lookup_raw.constprop.0+0x44/0x220 [dm_persistent_data]
   dm_btree_lookup+0x16f/0x210 [dm_persistent_data]
   dm_thin_find_block+0x12c/0x210 [dm_thin_pool]
   __process_bio_read_only+0xc5/0x400 [dm_thin_pool]
   process_thin_deferred_bios+0x1a4/0x4a0 [dm_thin_pool]
   process_one_work+0x3c5/0x730

Following process may generate a broken btree mixed with fresh and stale btree nodes, which could get dm thin trapped in an infinite loop while looking up data block:
Transaction 1: pmd->root = A, A->B->C // One path in btree

                pmd->root = X, X->Y->Z   // Copy-up
 Transaction 2: X,Z is updated on disk, Y write failed.
                // Commit failed, dm thin becomes read-only.
                process_bio_read_only
		 dm_thin_find_block
		  __find_block
		   dm_btree_lookup(pmd->root)

The pmd->root points to a broken btree, Y may contain stale node pointing to any block, for example X, which gets dm thin trapped into a dead loop while looking up Z.

Fix this by setting pmd->root in __open_metadata(), so that dm thin will use the last transaction's pmd->root if commit failed.

Fetch a reproducer in [Link].

Linke: https://bugzilla.kernel.org/show_bug.cgi?id=216790

Fixes 991d9fa02da0 ("dm: add thin provisioning target")
---
 drivers/md/dm-thin-metadata.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/md/dm-thin-metadata.c +9 -0
@@ -724,6 +724,15 @@ static int __open_metadata(struct dm_poo
 		goto bad_cleanup_data_sm;
 	}
 
+	/*
+	 * For pool metadata opening process, root setting is redundant
+	 * because it will be set again in __begin_transaction(). But dm
+	 * pool aborting process really needs to get last transaction's
+	 * root to avoid accessing broken btree.
+	 */
+	pmd->root = le64_to_cpu(disk_super->data_mapping_root);
+	pmd->details_root = le64_to_cpu(disk_super->device_details_root);
+
 	__setup_btree_details(pmd);
 	dm_bm_unlock(sblock);
 
author maintainer
#87 lore raw

PATCH 84/290 dm thin: resume even if in FAIL mode

In reply to Greg Kroah-Hartman

From: Luo Meng <[email protected]>

commit 19eb1650afeb1aa86151f61900e9e5f1de5d8d02 upstream.

If a thinpool set fail_io while suspending, resume will fail with:
device-mapper: resume ioctl on vg-thinpool failed: Invalid argument

The thin-pool also can't be removed if an in-flight bio is in the deferred list.

This can be easily reproduced using:

echo "offline" > /sys/block/sda/device/state dd if=/dev/zero of=/dev/mapper/thin bs=4K count=1 dmsetup suspend /dev/mapper/pool mkfs.ext4 /dev/mapper/thin
dmsetup resume /dev/mapper/pool

The root cause is maybe_resize_data_dev() will check fail_io and return error before called dm_resume.

Fix this by adding FAIL mode check at the end of pool_preresume().

Fixes da105ed5fd7e ("dm thin metadata: introduce dm_pool_abort_metadata")
---
 drivers/md/dm-thin.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/md/dm-thin.c +12 -4
@@ -3566,20 +3566,28 @@ static int pool_preresume(struct dm_targ
 	 */
 	r = bind_control_target(pool, ti);
 	if (r)
-		return r;
+		goto out;
 
 	r = maybe_resize_data_dev(ti, &need_commit1);
 	if (r)
-		return r;
+		goto out;
 
 	r = maybe_resize_metadata_dev(ti, &need_commit2);
 	if (r)
-		return r;
+		goto out;
 
 	if (need_commit1 || need_commit2)
 		(void) commit(pool);
+out:
+	/*
+	 * When a thin-pool is PM_FAIL, it cannot be rebuilt if
+	 * bio is in deferred list. Therefore need to return 0
+	 * to allow pool_resume() to flush IO.
+	 */
+	if (r && get_pool_mode(pool) == PM_FAIL)
+		r = 0;
 
-	return 0;
+	return r;
 }
 
 static void pool_suspend_active_thins(struct pool *pool)
author maintainer
#88 lore raw

PATCH 85/290 dm thin: Fix UAF in run_timer_softirq()

In reply to Greg Kroah-Hartman

From: Luo Meng <[email protected]>

commit 88430ebcbc0ec637b710b947738839848c20feff upstream.

When dm_resume() and dm_destroy() are concurrent, it will lead to UAF, as follows:

 BUG: KASAN: use-after-free in __run_timers+0x173/0x710
 Write of size 8 at addr ffff88816d9490f0 by task swapper/0/0
<snip>
 Call Trace:
  <IRQ>
  dump_stack_lvl+0x73/0x9f
  print_report.cold+0x132/0xaa2
  _raw_spin_lock_irqsave+0xcd/0x160
  __run_timers+0x173/0x710
  kasan_report+0xad/0x110
  __run_timers+0x173/0x710
  __asan_store8+0x9c/0x140
  __run_timers+0x173/0x710
  call_timer_fn+0x310/0x310
  pvclock_clocksource_read+0xfa/0x250
  kvm_clock_read+0x2c/0x70
  kvm_clock_get_cycles+0xd/0x20
  ktime_get+0x5c/0x110
  lapic_next_event+0x38/0x50
  clockevents_program_event+0xf1/0x1e0
  run_timer_softirq+0x49/0x90
  __do_softirq+0x16e/0x62c
  __irq_exit_rcu+0x1fa/0x270
  irq_exit_rcu+0x12/0x20
  sysvec_apic_timer_interrupt+0x8e/0xc0

One of the concurrency UAF can be shown as below:

use free

do_resume                           |
  __find_device_hash_cell           |
    dm_get                          |
      atomic_inc(&md->holders)      |
                                    | dm_destroy
                                    |   __dm_destroy
                                    |     if (!dm_suspended_md(md))
                                    |     atomic_read(&md->holders)
                                    |     msleep(1)
  dm_resume                         |
    __dm_resume                     |
      dm_table_resume_targets       |
        pool_resume                 |
          do_waker  #add delay work |
  dm_put                            |
    atomic_dec(&md->holders)        |
                                    |     dm_table_destroy
                                    |       pool_dtr
                                    |         __pool_dec
                                    |           __pool_destroy
                                    |             destroy_workqueue
                                    |             kfree(pool) # free pool

time out
__do_softirq
run_timer_softirq # pool has already been freed

This can be easily reproduced using:
1. create thin-pool
2. dmsetup suspend pool
3. dmsetup resume pool
4. dmsetup remove_all # Concurrent with 3

The root cause of this UAF bug is that dm_resume() adds timer after dm_destroy() skips cancelling the timer because of suspend status. After timeout, it will call run_timer_softirq(), however pool has already been freed. The concurrency UAF bug will happen.

Therefore, cancelling timer again in __pool_destroy().

Fixes 991d9fa02da0d ("dm: add thin provisioning target")
---
 drivers/md/dm-thin.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/md/dm-thin.c +2 -0
@@ -2907,6 +2907,8 @@ static void __pool_destroy(struct pool *
 	dm_bio_prison_destroy(pool->prison);
 	dm_kcopyd_client_destroy(pool->copier);
 
+	cancel_delayed_work_sync(&pool->waker);
+	cancel_delayed_work_sync(&pool->no_space_timeout);
 	if (pool->wq)
 		destroy_workqueue(pool->wq);
 
author maintainer
#89 lore raw

PATCH 86/290 dm integrity: Fix UAF in dm_integrity_dtr()

In reply to Greg Kroah-Hartman

From: Luo Meng <[email protected]>

commit f50cb2cbabd6c4a60add93d72451728f86e4791c upstream.

Dm_integrity also has the same UAF problem when dm_resume() and dm_destroy() are concurrent.

Therefore, cancelling timer again in dm_integrity_dtr().

Fixes 7eada909bfd7a ("dm: add integrity target")
---
 drivers/md/dm-integrity.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/md/dm-integrity.c +2 -0
@@ -4539,6 +4539,8 @@ static void dm_integrity_dtr(struct dm_t
 	BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
 	BUG_ON(!list_empty(&ic->wait_list));
 
+	if (ic->mode == 'B')
+		cancel_delayed_work_sync(&ic->bitmap_flush_work);
 	if (ic->metadata_wq)
 		destroy_workqueue(ic->metadata_wq);
 	if (ic->wait_wq)
author maintainer
#90 lore raw

PATCH 87/290 dm clone: Fix UAF in clone_dtr()

In reply to Greg Kroah-Hartman

From: Luo Meng <[email protected]>

commit e4b5957c6f749a501c464f92792f1c8e26b61a94 upstream.

Dm_clone also has the same UAF problem when dm_resume() and dm_destroy() are concurrent.

Therefore, cancelling timer again in clone_dtr().

Fixes 7431b7835f554 ("dm: add clone target")
---
 drivers/md/dm-clone-target.c |    1 +
 1 file changed, 1 insertion(+)
drivers/md/dm-clone-target.c +1 -0
@@ -1959,6 +1959,7 @@ static void clone_dtr(struct dm_target *
 
 	mempool_exit(&clone->hydration_pool);
 	dm_kcopyd_client_destroy(clone->kcopyd_client);
+	cancel_delayed_work_sync(&clone->waker);
 	destroy_workqueue(clone->wq);
 	hash_table_exit(clone);
 	dm_clone_metadata_close(clone->cmd);
author maintainer
#91 lore raw

PATCH 88/290 dm cache: Fix UAF in destroy()

In reply to Greg Kroah-Hartman

From: Luo Meng <[email protected]>

commit 6a459d8edbdbe7b24db42a5a9f21e6aa9e00c2aa upstream.

Dm_cache also has the same UAF problem when dm_resume() and dm_destroy() are concurrent.

Therefore, cancelling timer again in destroy().

Fixes c6b4fcbad044e ("dm: add cache target")
---
 drivers/md/dm-cache-target.c |    1 +
 1 file changed, 1 insertion(+)
drivers/md/dm-cache-target.c +1 -0
@@ -1895,6 +1895,7 @@ static void destroy(struct cache *cache)
 	if (cache->prison)
 		dm_bio_prison_destroy_v2(cache->prison);
 
+	cancel_delayed_work_sync(&cache->waker);
 	if (cache->wq)
 		destroy_workqueue(cache->wq);
 
author maintainer
#92 lore raw

PATCH 89/290 dm cache: set needs_check flag after aborting metadata

In reply to Greg Kroah-Hartman

From: Mike Snitzer <[email protected]>

commit 6b9973861cb2e96dcd0bb0f1baddc5c034207c5c upstream.

Otherwise the commit that will be aborted will be associated with the metadata objects that will be torn down. Must write needs_check flag to metadata with a reset block manager.

Found through code-inspection (and compared against dm-thin.c).

Fixes 028ae9f76f29 ("dm cache: add fail io mode and needs_check flag")
---
 drivers/md/dm-cache-target.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/md/dm-cache-target.c +5 -5
@@ -915,16 +915,16 @@ static void abort_transaction(struct cac
 	if (get_cache_mode(cache) >= CM_READ_ONLY)
 		return;
 
-	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
-		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
-		set_cache_mode(cache, CM_FAIL);
-	}
-
 	DMERR_LIMIT("%s: aborting current metadata transaction", dev_name);
 	if (dm_cache_metadata_abort(cache->cmd)) {
 		DMERR("%s: failed to abort metadata transaction", dev_name);
 		set_cache_mode(cache, CM_FAIL);
 	}
+
+	if (dm_cache_metadata_set_needs_check(cache->cmd)) {
+		DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name);
+		set_cache_mode(cache, CM_FAIL);
+	}
 }
 
 static void metadata_operation_failed(struct cache *cache, const char *op, int r)
author maintainer
#93 lore raw

PATCH 90/290 tracing/hist: Fix out-of-bound write on action_data.var_ref_idx

In reply to Greg Kroah-Hartman

From: Zheng Yejian <[email protected]>

commit 82470f7d9044842618c847a7166de2b7458157a7 upstream.

When generate a synthetic event with many params and then create a trace action for it [1], kernel panic happened [2].

It is because that in trace_action_create() 'data->n_params' is up to SYNTH_FIELDS_MAX (current value is 64), and array 'data->var_ref_idx' keeps indices into array 'hist_data->var_refs' for each synthetic event param, but the length of 'data->var_ref_idx' is TRACING_MAP_VARS_MAX (current value is 16), so out-of-bound write happened when 'data->n_params' more than 16. In this case, 'data->match_data.event' is overwritten and eventually cause the panic.

To solve the issue, adjust the length of 'data->var_ref_idx' to be SYNTH_FIELDS_MAX and add sanity checks to avoid out-of-bound write.

[1]

 # cd /sys/kernel/tracing/
 # echo "my_synth_event int v1; int v2; int v3; int v4; int v5; int v6;\
int v7; int v8; int v9; int v10; int v11; int v12; int v13; int v14;\
int v15; int v16; int v17; int v18; int v19; int v20; int v21; int v22;\
int v23; int v24; int v25; int v26; int v27; int v28; int v29; int v30;\
int v31; int v32; int v33; int v34; int v35; int v36; int v37; int v38;\
int v39; int v40; int v41; int v42; int v43; int v44; int v45; int v46;\
int v47; int v48; int v49; int v50; int v51; int v52; int v53; int v54;\
int v55; int v56; int v57; int v58; int v59; int v60; int v61; int v62;\
int v63" >> synthetic_events
 # echo 'hist:keys=pid:ts0=common_timestamp.usecs if comm=="bash"' >> \
events/sched/sched_waking/trigger
 # echo "hist:keys=next_pid:onmatch(sched.sched_waking).my_synth_event(\
pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\
pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\
pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,pid,\
pid,pid,pid,pid,pid,pid,pid,pid,pid)" >> events/sched/sched_switch/trigger

[2]

BUG: unable to handle page fault for address: ffff91c900000000
PGD 61001067 P4D 61001067 PUD 0
Oops: 0000 [#1] PREEMPT SMP NOPTI
CPU: 2 PID: 322 Comm: bash Tainted: G        W          6.1.0-rc8+ #229
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
RIP: 0010:strcmp+0xc/0x30
Code: 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee
c3 cc cc cc cc 0f 1f 00 31 c0 eb 08 48 83 c0 01 84 d2 74 13 <0f> b6 14
07 3a 14 06 74 ef 19 c0 83 c8 01 c3 cc cc cc cc 31 c3
RSP: 0018:ffff9b3b00f53c48 EFLAGS: 00000246
RAX: 0000000000000000 RBX: ffffffffba958a68 RCX: 0000000000000000
RDX: 0000000000000010 RSI: ffff91c943d33a90 RDI: ffff91c900000000
RBP: ffff91c900000000 R08: 00000018d604b529 R09: 0000000000000000
R10: ffff91c9483eddb1 R11: ffff91ca483eddab R12: ffff91c946171580
R13: ffff91c9479f0538 R14: ffff91c9457c2848 R15: ffff91c9479f0538
FS:  00007f1d1cfbe740(0000) GS:ffff91c9bdc80000(0000)
knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff91c900000000 CR3: 0000000006316000 CR4: 00000000000006e0
Call Trace:
 <TASK>
 __find_event_file+0x55/0x90
 action_create+0x76c/0x1060
 event_hist_trigger_parse+0x146d/0x2060
 ? event_trigger_write+0x31/0xd0
 trigger_process_regex+0xbb/0x110
 event_trigger_write+0x6b/0xd0
 vfs_write+0xc8/0x3e0
 ? alloc_fd+0xc0/0x160
 ? preempt_count_add+0x4d/0xa0
 ? preempt_count_add+0x70/0xa0
 ksys_write+0x5f/0xe0
 do_syscall_64+0x3b/0x90
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x7f1d1d0cf077
Code: 64 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e

fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74
RSP: 002b:00007ffcebb0e568 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000000143 RCX: 00007f1d1d0cf077
RDX: 0000000000000143 RSI: 00005639265aa7e0 RDI: 0000000000000001
RBP: 00005639265aa7e0 R08: 000000000000000a R09: 0000000000000142
R10: 000056392639c017 R11: 0000000000000246 R12: 0000000000000143
R13: 00007f1d1d1ae6a0 R14: 00007f1d1d1aa4a0 R15: 00007f1d1d1a98a0

 </TASK>
Modules linked in:
CR2: ffff91c900000000
---[ end trace 0000000000000000 ]---
RIP: 0010:strcmp+0xc/0x30
Code: 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee
c3 cc cc cc cc 0f 1f 00 31 c0 eb 08 48 83 c0 01 84 d2 74 13 <0f> b6 14
07 3a 14 06 74 ef 19 c0 83 c8 01 c3 cc cc cc cc 31 c3
RSP: 0018:ffff9b3b00f53c48 EFLAGS: 00000246
RAX: 0000000000000000 RBX: ffffffffba958a68 RCX: 0000000000000000
RDX: 0000000000000010 RSI: ffff91c943d33a90 RDI: ffff91c900000000
RBP: ffff91c900000000 R08: 00000018d604b529 R09: 0000000000000000
R10: ffff91c9483eddb1 R11: ffff91ca483eddab R12: ffff91c946171580
R13: ffff91c9479f0538 R14: ffff91c9457c2848 R15: ffff91c9479f0538
FS:  00007f1d1cfbe740(0000) GS:ffff91c9bdc80000(0000)
knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffff91c900000000 CR3: 0000000006316000 CR4: 00000000000006e0
Fixes d380dcde9a07 ("tracing: Fix now invalid var_ref_vals assumption in trace action")
---
 kernel/trace/trace_events_hist.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
kernel/trace/trace_events_hist.c +8 -2
@@ -452,7 +452,7 @@ struct action_data {
 	 * event param, and is passed to the synthetic event
 	 * invocation.
 	 */
-	unsigned int		var_ref_idx[TRACING_MAP_VARS_MAX];
+	unsigned int		var_ref_idx[SYNTH_FIELDS_MAX];
 	struct synth_event	*synth_event;
 	bool			use_trace_keyword;
 	char			*synth_event_name;
@@ -1895,7 +1895,9 @@ static struct hist_field *create_var_ref
 			return ref_field;
 		}
 	}
-
+	/* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
+	if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
+		return NULL;
 	ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
 	if (ref_field) {
 		if (init_var_ref(ref_field, var_field, system, event_name)) {
@@ -3524,6 +3526,10 @@ static int trace_action_create(struct hi
 
 	lockdep_assert_held(&event_mutex);
 
+	/* Sanity check to avoid out-of-bound write on 'data->var_ref_idx' */
+	if (data->n_params > SYNTH_FIELDS_MAX)
+		return -EINVAL;
+
 	if (data->use_trace_keyword)
 		synth_event_name = data->synth_event_name;
 	else
author maintainer
#94 lore raw

PATCH 91/290 perf/core: Call LSM hook after copying perf_event_attr

In reply to Greg Kroah-Hartman

From: Namhyung Kim <[email protected]>

commit 0a041ebca4956292cadfb14a63ace3a9c1dcb0a3 upstream.

It passes the attr struct to the security_perf_event_open() but it's not initialized yet.

---
 kernel/events/core.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/events/core.c +3 -3
@@ -12215,12 +12215,12 @@ SYSCALL_DEFINE5(perf_event_open,
 	if (flags & ~PERF_FLAG_ALL)
 		return -EINVAL;
 
-	/* Do we allow access to perf_event_open(2) ? */
-	err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
+	err = perf_copy_attr(attr_uptr, &attr);
 	if (err)
 		return err;
 
-	err = perf_copy_attr(attr_uptr, &attr);
+	/* Do we allow access to perf_event_open(2) ? */
+	err = security_perf_event_open(&attr, PERF_SECURITY_OPEN);
 	if (err)
 		return err;
 
author maintainer
#95 lore raw

PATCH 92/290 of/kexec: Fix reading 32-bit "linux,initrd-{start,end}" values

In reply to Greg Kroah-Hartman

From: Rob Herring <[email protected]>

commit e553ad8d7957697385e81034bf76db3b2cb2cf27 upstream.

"linux,initrd-start" and "linux,initrd-end" can be 32-bit values even on a 64-bit platform. Ideally, the size should be based on '#address-cells', but that has never been enforced in the kernel's FDT boot parsing code (early_init_dt_check_for_initrd()). Bootloader behavior is known to vary. For example, kexec always writes these as 64-bit. The result of incorrectly reading 32-bit values is most likely the reserved memory for the original initrd will still be reserved for the new kernel. The original arm64 equivalent of this code failed to release the initrd reserved memory in *all* cases.

Use of_read_number() to mirror the early_init_dt_check_for_initrd() code.

---
 drivers/of/kexec.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/of/kexec.c +5 -5
@@ -284,7 +284,7 @@ void *of_kexec_alloc_and_setup_fdt(const
 				   const char *cmdline, size_t extra_fdt_size)
 {
 	void *fdt;
-	int ret, chosen_node;
+	int ret, chosen_node, len;
 	const void *prop;
 	size_t fdt_size;
 
@@ -327,19 +327,19 @@ void *of_kexec_alloc_and_setup_fdt(const
 		goto out;
 
 	/* Did we boot using an initrd? */
-	prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", NULL);
+	prop = fdt_getprop(fdt, chosen_node, "linux,initrd-start", &len);
 	if (prop) {
 		u64 tmp_start, tmp_end, tmp_size;
 
-		tmp_start = fdt64_to_cpu(*((const fdt64_t *) prop));
+		tmp_start = of_read_number(prop, len / 4);
 
-		prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", NULL);
+		prop = fdt_getprop(fdt, chosen_node, "linux,initrd-end", &len);
 		if (!prop) {
 			ret = -EINVAL;
 			goto out;
 		}
 
-		tmp_end = fdt64_to_cpu(*((const fdt64_t *) prop));
+		tmp_end = of_read_number(prop, len / 4);
 
 		/*
 		 * kexec reserves exact initrd size, while firmware may
author maintainer
#96 lore raw

PATCH 93/290 KVM: VMX: Resume guest immediately when injecting #GP on ECREATE

In reply to Greg Kroah-Hartman

From: Sean Christopherson <[email protected]>

commit eb3992e833d3a17f9b0a3e0371d0b1d3d566f740 upstream.

Resume the guest immediately when injecting a #GP on ECREATE due to an invalid enclave size, i.e. don't attempt ECREATE in the host. The #GP is a terminal fault, e.g. skipping the instruction if ECREATE is successful would result in KVM injecting #GP on the instruction following ECREATE.

Fixes 70210c044b4e ("KVM: VMX: Add SGX ENCLS[ECREATE] handler to enforce CPUID restrictions")
Cc Kai Huang <[email protected]>
---
 arch/x86/kvm/vmx/sgx.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/sgx.c +3 -1
@@ -188,8 +188,10 @@ static int __handle_encls_ecreate(struct
 	/* Enforce CPUID restriction on max enclave size. */
 	max_size_log2 = (attributes & SGX_ATTR_MODE64BIT) ? sgx_12_0->edx >> 8 :
 							    sgx_12_0->edx;
-	if (size >= BIT_ULL(max_size_log2))
+	if (size >= BIT_ULL(max_size_log2)) {
 		kvm_inject_gp(vcpu, 0);
+		return 1;
+	}
 
 	/*
 	 * sgx_virt_ecreate() returns:
author maintainer
#97 lore raw

PATCH 94/290 KVM: nVMX: Inject #GP, not #UD, if "generic" VMXON CR0/CR4 check fails

In reply to Greg Kroah-Hartman

From: Sean Christopherson <[email protected]>

commit 9cc409325ddd776f6fd6293d5ce93ce1248af6e4 upstream.

Inject #GP for if VMXON is attempting with a CR0/CR4 that fails the generic "is CRx valid" check, but passes the CR4.VMXE check, and do the generic checks _after_ handling the post-VMXON VM-Fail.

The CR4.VMXE check, and all other #UD cases, are special pre-conditions that are enforced prior to pivoting on the current VMX mode, i.e. occur before interception if VMXON is attempted in VMX non-root mode.

All other CR0/CR4 checks generate #GP and effectively have lower priority than the post-VMXON check.

Per the SDM:

    IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or ...
        THEN #UD;
    ELSIF not in VMX operation
        THEN
            IF (CPL > 0) or (in A20M mode) or
            (the values of CR0 and CR4 are not supported in VMX operation)
                THEN #GP(0);
    ELSIF in VMX non-root operation
        THEN VMexit;
    ELSIF CPL > 0
        THEN #GP(0);
    ELSE VMfail("VMXON executed in VMX root operation");
    FI;

which, if re-written without ELSIF, yields:

IF (register operand) or (CR0.PE = 0) or (CR4.VMXE = 0) or ...
THEN #UD

IF in VMX non-root operation
THEN VMexit;

IF CPL > 0
THEN #GP(0)

IF in VMX operation
THEN VMfail("VMXON executed in VMX root operation");

IF (in A20M mode) or
(the values of CR0 and CR4 are not supported in VMX operation)
THEN #GP(0);

Note, KVM unconditionally forwards VMXON VM-Exits that occur in L2 to L1, i.e. there is no need to check the vCPU is not in VMX non-root mode. Add a comment to explain why unconditionally forwarding such exits is functionally correct.

Fixes c7d855c2aff2 ("KVM: nVMX: Inject #UD if VMXON is attempted with incompatible CR0/CR4")
---
 arch/x86/kvm/vmx/nested.c |   44 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)
arch/x86/kvm/vmx/nested.c +33 -11
@@ -4970,24 +4970,35 @@ static int handle_vmon(struct kvm_vcpu *
 		| FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
 
 	/*
-	 * Note, KVM cannot rely on hardware to perform the CR0/CR4 #UD checks
-	 * that have higher priority than VM-Exit (see Intel SDM's pseudocode
-	 * for VMXON), as KVM must load valid CR0/CR4 values into hardware while
-	 * running the guest, i.e. KVM needs to check the _guest_ values.
+	 * Manually check CR4.VMXE checks, KVM must force CR4.VMXE=1 to enter
+	 * the guest and so cannot rely on hardware to perform the check,
+	 * which has higher priority than VM-Exit (see Intel SDM's pseudocode
+	 * for VMXON).
 	 *
-	 * Rely on hardware for the other two pre-VM-Exit checks, !VM86 and
-	 * !COMPATIBILITY modes.  KVM may run the guest in VM86 to emulate Real
-	 * Mode, but KVM will never take the guest out of those modes.
+	 * Rely on hardware for the other pre-VM-Exit checks, CR0.PE=1, !VM86
+	 * and !COMPATIBILITY modes.  For an unrestricted guest, KVM doesn't
+	 * force any of the relevant guest state.  For a restricted guest, KVM
+	 * does force CR0.PE=1, but only to also force VM86 in order to emulate
+	 * Real Mode, and so there's no need to check CR0.PE manually.
 	 */
-	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
-	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
+	if (!kvm_read_cr4_bits(vcpu, X86_CR4_VMXE)) {
 		kvm_queue_exception(vcpu, UD_VECTOR);
 		return 1;
 	}
 
 	/*
-	 * CPL=0 and all other checks that are lower priority than VM-Exit must
-	 * be checked manually.
+	 * The CPL is checked for "not in VMX operation" and for "in VMX root",
+	 * and has higher priority than the VM-Fail due to being post-VMXON,
+	 * i.e. VMXON #GPs outside of VMX non-root if CPL!=0.  In VMX non-root,
+	 * VMXON causes VM-Exit and KVM unconditionally forwards VMXON VM-Exits
+	 * from L2 to L1, i.e. there's no need to check for the vCPU being in
+	 * VMX non-root.
+	 *
+	 * Forwarding the VM-Exit unconditionally, i.e. without performing the
+	 * #UD checks (see above), is functionally ok because KVM doesn't allow
+	 * L1 to run L2 without CR4.VMXE=0, and because KVM never modifies L2's
+	 * CR0 or CR4, i.e. it's L2's responsibility to emulate #UDs that are
+	 * missed by hardware due to shadowing CR0 and/or CR4.
 	 */
 	if (vmx_get_cpl(vcpu)) {
 		kvm_inject_gp(vcpu, 0);
@@ -4997,6 +5008,17 @@ static int handle_vmon(struct kvm_vcpu *
 	if (vmx->nested.vmxon)
 		return nested_vmx_fail(vcpu, VMXERR_VMXON_IN_VMX_ROOT_OPERATION);
 
+	/*
+	 * Invalid CR0/CR4 generates #GP.  These checks are performed if and
+	 * only if the vCPU isn't already in VMX operation, i.e. effectively
+	 * have lower priority than the VM-Fail above.
+	 */
+	if (!nested_host_cr0_valid(vcpu, kvm_read_cr0(vcpu)) ||
+	    !nested_host_cr4_valid(vcpu, kvm_read_cr4(vcpu))) {
+		kvm_inject_gp(vcpu, 0);
+		return 1;
+	}
+
 	if ((vmx->msr_ia32_feature_control & VMXON_NEEDED_FEATURES)
 			!= VMXON_NEEDED_FEATURES) {
 		kvm_inject_gp(vcpu, 0);
author maintainer
#98 lore raw

PATCH 95/290 KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1

In reply to Greg Kroah-Hartman

From: Sean Christopherson <[email protected]>

commit 31de69f4eea77b28a9724b3fa55aae104fc91fc7 upstream.

Set ENABLE_USR_WAIT_PAUSE in KVM's supported VMX MSR configuration if the feature is supported in hardware and enabled in KVM's base, non-nested configuration, i.e. expose ENABLE_USR_WAIT_PAUSE to L1 if it's supported. This fixes a bug where saving/restoring, i.e. migrating, a vCPU will fail if WAITPKG (the associated CPUID feature) is enabled for the vCPU, and obviously allows L1 to enable the feature for L2.

KVM already effectively exposes ENABLE_USR_WAIT_PAUSE to L1 by stuffing the allowed-1 control ina vCPU's virtual MSR_IA32_VMX_PROCBASED_CTLS2 when updating secondary controls in response to KVM_SET_CPUID(2), but (a) that depends on flawed code (KVM shouldn't touch VMX MSRs in response to CPUID updates) and (b) runs afoul of vmx_restore_control_msr()'s restriction that the guest value must be a strict subset of the supported host value.

Although no past commit explicitly enabled nested support for WAITPKG, doing so is safe and functionally correct from an architectural perspective as no additional KVM support is needed to virtualize TPAUSE, UMONITOR, and UMWAIT for L2 relative to L1, and KVM already forwards VM-Exits to L1 as necessary (commit bf653b78f960, "KVM: vmx: Introduce handle_unexpected_vmexit and handle WAITPKG vmexit").

Note, KVM always keeps the hosts MSR_IA32_UMWAIT_CONTROL resident in hardware, i.e. always runs both L1 and L2 with the host's power management settings for TPAUSE and UMWAIT. See commit bf09fb6cba4f ("KVM: VMX: Stop context switching MSR_IA32_UMWAIT_CONTROL") for more details.

Fixes e69e72faa3a0 ("KVM: x86: Add support for user wait instructions")

Message-Id: <[email protected]>

---
 arch/x86/kvm/vmx/nested.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kvm/vmx/nested.c +2 -1
@@ -6666,7 +6666,8 @@ void nested_vmx_setup_ctls_msrs(struct n
 		SECONDARY_EXEC_ENABLE_INVPCID |
 		SECONDARY_EXEC_RDSEED_EXITING |
 		SECONDARY_EXEC_XSAVES |
-		SECONDARY_EXEC_TSC_SCALING;
+		SECONDARY_EXEC_TSC_SCALING |
+		SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE;
 
 	/*
 	 * We can emulate "VMCS shadowing," even if the hardware
author maintainer
#99 lore raw

PATCH 96/290 x86/microcode/intel: Do not retry microcode reloading on the APs

In reply to Greg Kroah-Hartman

From: Ashok Raj <[email protected]>

commit be1b670f61443aa5d0d01782e9b8ea0ee825d018 upstream.

The retries in load_ucode_intel_ap() were in place to support systems with mixed steppings. Mixed steppings are no longer supported and there is only one microcode image at a time. Any retries will simply reattempt to apply the same image over and over without making progress.

[ bp: Zap the circumstantial reasoning from the commit message. ]

---
 arch/x86/kernel/cpu/microcode/intel.c |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
arch/x86/kernel/cpu/microcode/intel.c +1 -7
@@ -659,7 +659,6 @@ void load_ucode_intel_ap(void)
 	else
 		iup = &intel_ucode_patch;
 
-reget:
 	if (!*iup) {
 		patch = __load_ucode_intel(&uci);
 		if (!patch)
@@ -670,12 +669,7 @@ reget:
 
 	uci.mc = *iup;
 
-	if (apply_microcode_early(&uci, true)) {
-		/* Mixed-silicon system? Try to refetch the proper patch: */
-		*iup = NULL;
-
-		goto reget;
-	}
+	apply_microcode_early(&uci, true);
 }
 
 static struct microcode_intel *find_patch(struct ucode_cpu_info *uci)
author maintainer
#100 lore raw

PATCH 97/290 ftrace/x86: Add back ftrace_expected for ftrace bug reports

In reply to Greg Kroah-Hartman

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

commit fd3dc56253acbe9c641a66d312d8393cd55eb04c upstream.

After someone reported a bug report with a failed modification due to the expected value not matching what was found, it came to my attention that the ftrace_expected is no longer set when that happens. This makes for debugging the issue a bit more difficult.

Set ftrace_expected to the expected code before calling ftrace_bug, so that it shows what was expected and why it failed.

Cc Masami Hiramatsu <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Ingo Molnar <[email protected]>
Fixes 768ae4406a5c ("x86/ftrace: Use text_poke()")
---
 arch/x86/kernel/ftrace.c |    2 ++
 1 file changed, 2 insertions(+)
arch/x86/kernel/ftrace.c +2 -0
@@ -219,7 +219,9 @@ void ftrace_replace_code(int enable)
 
 		ret = ftrace_verify_code(rec->ip, old);
 		if (ret) {
+			ftrace_expected = old;
 			ftrace_bug(ret, rec);
+			ftrace_expected = NULL;
 			return;
 		}
 	}
author maintainer
#101 lore raw

PATCH 98/290 x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK

In reply to Greg Kroah-Hartman

From: Masami Hiramatsu (Google) <[email protected]>

commit 1993bf97992df2d560287f3c4120eda57426843d upstream.

Since the CONFIG_RETHUNK and CONFIG_SLS will use INT3 for stopping speculative execution after RET instruction, kprobes always failes to check the probed instruction boundary by decoding the function body if the probed address is after such sequence. (Note that some conditional code blocks will be placed after function return, if compiler decides it is not on the hot path.)

This is because kprobes expects kgdb puts the INT3 as a software breakpoint and it will replace the original instruction. But these INT3 are not such purpose, it doesn't need to recover the original instruction.

To avoid this issue, kprobes checks whether the INT3 is owned by kgdb or not, and if so, stop decoding and make it fail. The other INT3 will come from CONFIG_RETHUNK/CONFIG_SLS and those can be treated as a one-byte instruction.

---
 arch/x86/kernel/kprobes/core.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
arch/x86/kernel/kprobes/core.c +7 -3
@@ -37,6 +37,7 @@
 #include <linux/extable.h>
 #include <linux/kdebug.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 #include <linux/ftrace.h>
 #include <linux/kasan.h>
 #include <linux/moduleloader.h>
@@ -289,12 +290,15 @@ static int can_probe(unsigned long paddr
 		if (ret < 0)
 			return 0;
 
+#ifdef CONFIG_KGDB
 		/*
-		 * Another debugging subsystem might insert this breakpoint.
-		 * In that case, we can't recover it.
+		 * If there is a dynamically installed kgdb sw breakpoint,
+		 * this function should not be probed.
 		 */
-		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
+		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
+		    kgdb_has_hit_break(addr))
 			return 0;
+#endif
 		addr += insn.length;
 	}
 
author maintainer
#102 lore raw

PATCH 99/290 x86/kprobes: Fix optprobe optimization check with CONFIG_RETHUNK

In reply to Greg Kroah-Hartman

From: Masami Hiramatsu (Google) <[email protected]>

commit 63dc6325ff41ee9e570bde705ac34a39c5dbeb44 upstream.

Since the CONFIG_RETHUNK and CONFIG_SLS will use INT3 for stopping speculative execution after function return, kprobe jump optimization always fails on the functions with such INT3 inside the function body. (It already checks the INT3 padding between functions, but not inside
the function)

To avoid this issue, as same as kprobes, check whether the INT3 comes from kgdb or not, and if so, stop decoding and make it fail. The other INT3 will come from CONFIG_RETHUNK/CONFIG_SLS and those can be treated as a one-byte instruction.

---
 arch/x86/kernel/kprobes/opt.c |   28 ++++++++--------------------
 1 file changed, 8 insertions(+), 20 deletions(-)
arch/x86/kernel/kprobes/opt.c +8 -20
@@ -15,6 +15,7 @@
 #include <linux/extable.h>
 #include <linux/kdebug.h>
 #include <linux/kallsyms.h>
+#include <linux/kgdb.h>
 #include <linux/ftrace.h>
 #include <linux/objtool.h>
 #include <linux/pgtable.h>
@@ -272,19 +273,6 @@ static int insn_is_indirect_jump(struct
 	return ret;
 }
 
-static bool is_padding_int3(unsigned long addr, unsigned long eaddr)
-{
-	unsigned char ops;
-
-	for (; addr < eaddr; addr++) {
-		if (get_kernel_nofault(ops, (void *)addr) < 0 ||
-		    ops != INT3_INSN_OPCODE)
-			return false;
-	}
-
-	return true;
-}
-
 /* Decode whole function to ensure any instructions don't jump into target */
 static int can_optimize(unsigned long paddr)
 {
@@ -327,15 +315,15 @@ static int can_optimize(unsigned long pa
 		ret = insn_decode_kernel(&insn, (void *)recovered_insn);
 		if (ret < 0)
 			return 0;
-
+#ifdef CONFIG_KGDB
 		/*
-		 * In the case of detecting unknown breakpoint, this could be
-		 * a padding INT3 between functions. Let's check that all the
-		 * rest of the bytes are also INT3.
+		 * If there is a dynamically installed kgdb sw breakpoint,
+		 * this function should not be probed.
 		 */
-		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE)
-			return is_padding_int3(addr, paddr - offset + size) ? 1 : 0;
-
+		if (insn.opcode.bytes[0] == INT3_INSN_OPCODE &&
+		    kgdb_has_hit_break(addr))
+			return 0;
+#endif
 		/* Recover address */
 		insn.kaddr = (void *)addr;
 		insn.next_byte = (void *)(addr + insn.length);
author maintainer
#103 lore raw

PATCH 100/290 tracing: Fix race where eprobes can be called before the event

In reply to Greg Kroah-Hartman

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

commit d5f30a7da8ea8e6450250275cec5670cee3c4264 upstream.

The flag that tells the event to call its triggers after reading the event is set for eprobes after the eprobe is enabled. This leads to a race where the eprobe may be triggered at the beginning of the event where the record information is NULL. The eprobe then dereferences the NULL record causing a NULL kernel pointer bug.

Test for a NULL record to keep this from happening.

---
 kernel/trace/trace_eprobe.c |    3 +++
 1 file changed, 3 insertions(+)
kernel/trace/trace_eprobe.c +3 -0
@@ -570,6 +570,9 @@ static void eprobe_trigger_func(struct e
 	if (unlikely(!rec))
 		return;
 
+	if (unlikely(!rec))
+		return;
+
 	__eprobe_trace_func(edata, rec);
 }
 
author maintainer
#104 lore raw

PATCH 101/290 tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE

In reply to Greg Kroah-Hartman

From: Masami Hiramatsu (Google) <[email protected]>

commit e25e43a4e5d8cb2323553d8b6a7ba08d2ebab21f upstream.

Both CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER partially enables the CONFIG_TRACER_MAX_TRACE code, but that is complicated and has introduced a bug; It declares tracing_max_lat_fops data structure outside of #ifdefs, but since it is defined only when CONFIG_TRACER_MAX_TRACE=y or CONFIG_HWLAT_TRACER=y, if only CONFIG_OSNOISE_TRACER=y, that declaration comes to a definition(!).

To fix this issue, and do not repeat the similar problem, makes CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER enables the CONFIG_TRACER_MAX_TRACE always. It has there benefits;
- Fix the tracing_max_lat_fops bug
- Simplify the #ifdefs
- CONFIG_TRACER_MAX_TRACE code is fully enabled, or not.

---
 kernel/trace/Kconfig |    2 ++
 kernel/trace/trace.c |   23 +++++++++++++----------
 kernel/trace/trace.h |    8 +++-----
 3 files changed, 18 insertions(+), 15 deletions(-)
kernel/trace/Kconfig +2 -0
@@ -328,6 +328,7 @@ config SCHED_TRACER
 config HWLAT_TRACER
 	bool "Tracer to detect hardware latencies (like SMIs)"
 	select GENERIC_TRACER
+	select TRACER_MAX_TRACE
 	help
 	 This tracer, when enabled will create one or more kernel threads,
 	 depending on what the cpumask file is set to, which each thread
@@ -363,6 +364,7 @@ config HWLAT_TRACER
 config OSNOISE_TRACER
 	bool "OS Noise tracer"
 	select GENERIC_TRACER
+	select TRACER_MAX_TRACE
 	help
 	  In the context of high-performance computing (HPC), the Operating
 	  System Noise (osnoise) refers to the interference experienced by an
kernel/trace/trace.c +13 -10
@@ -1409,6 +1409,7 @@ int tracing_snapshot_cond_disable(struct
 	return false;
 }
 EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
+#define free_snapshot(tr)	do { } while (0)
 #endif /* CONFIG_TRACER_SNAPSHOT */
 
 void tracer_tracing_off(struct trace_array *tr)
@@ -1679,6 +1680,8 @@ static ssize_t trace_seq_to_buffer(struc
 }
 
 unsigned long __read_mostly	tracing_thresh;
+
+#ifdef CONFIG_TRACER_MAX_TRACE
 static const struct file_operations tracing_max_lat_fops;
 
 #ifdef LATENCY_FS_NOTIFY
@@ -1735,18 +1738,14 @@ void latency_fsnotify(struct trace_array
 	irq_work_queue(&tr->fsnotify_irqwork);
 }
 
-#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)	\
-	|| defined(CONFIG_OSNOISE_TRACER)
+#else /* !LATENCY_FS_NOTIFY */
 
 #define trace_create_maxlat_file(tr, d_tracer)				\
 	trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,	\
 			  d_tracer, &tr->max_latency, &tracing_max_lat_fops)
 
-#else
-#define trace_create_maxlat_file(tr, d_tracer)	 do { } while (0)
 #endif
 
-#ifdef CONFIG_TRACER_MAX_TRACE
 /*
  * Copy the new maximum trace into the separate maximum-trace
  * structure. (this way the maximum trace is permanently saved,
@@ -1821,14 +1820,15 @@ update_max_tr(struct trace_array *tr, st
 		ring_buffer_record_off(tr->max_buffer.buffer);
 
 #ifdef CONFIG_TRACER_SNAPSHOT
-	if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data))
-		goto out_unlock;
+	if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) {
+		arch_spin_unlock(&tr->max_lock);
+		return;
+	}
 #endif
 	swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
 
 	__update_max_tr(tr, tsk, cpu);
 
- out_unlock:
 	arch_spin_unlock(&tr->max_lock);
 }
 
@@ -1875,6 +1875,7 @@ update_max_tr_single(struct trace_array
 	__update_max_tr(tr, tsk, cpu);
 	arch_spin_unlock(&tr->max_lock);
 }
+
 #endif /* CONFIG_TRACER_MAX_TRACE */
 
 static int wait_on_pipe(struct trace_iterator *iter, int full)
@@ -6536,7 +6537,7 @@ out:
 	return ret;
 }
 
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
+#ifdef CONFIG_TRACER_MAX_TRACE
 
 static ssize_t
 tracing_max_lat_read(struct file *filp, char __user *ubuf,
@@ -7560,7 +7561,7 @@ static const struct file_operations trac
 	.llseek		= generic_file_llseek,
 };
 
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
+#ifdef CONFIG_TRACER_MAX_TRACE
 static const struct file_operations tracing_max_lat_fops = {
 	.open		= tracing_open_generic,
 	.read		= tracing_max_lat_read,
@@ -9549,7 +9550,9 @@ init_tracer_tracefs(struct trace_array *
 
 	create_trace_options_dir(tr);
 
+#ifdef CONFIG_TRACER_MAX_TRACE
 	trace_create_maxlat_file(tr, d_tracer);
+#endif
 
 	if (ftrace_create_function_files(tr, d_tracer))
 		MEM_FAIL(1, "Could not allocate function filter files");
kernel/trace/trace.h +3 -5
@@ -309,8 +309,7 @@ struct trace_array {
 	struct array_buffer	max_buffer;
 	bool			allocated_snapshot;
 #endif
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
-	|| defined(CONFIG_OSNOISE_TRACER)
+#ifdef CONFIG_TRACER_MAX_TRACE
 	unsigned long		max_latency;
 #ifdef CONFIG_FSNOTIFY
 	struct dentry		*d_max_latency;
@@ -688,12 +687,11 @@ void update_max_tr(struct trace_array *t
 		   void *cond_data);
 void update_max_tr_single(struct trace_array *tr,
 			  struct task_struct *tsk, int cpu);
-#endif /* CONFIG_TRACER_MAX_TRACE */
 
-#if (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
-	|| defined(CONFIG_OSNOISE_TRACER)) && defined(CONFIG_FSNOTIFY)
+#ifdef CONFIG_FSNOTIFY
 #define LATENCY_FS_NOTIFY
 #endif
+#endif /* CONFIG_TRACER_MAX_TRACE */
 
 #ifdef LATENCY_FS_NOTIFY
 void latency_fsnotify(struct trace_array *tr);
author maintainer
#105 lore raw

PATCH 102/290 tracing/hist: Fix wrong return value in parse_action_params()

In reply to Greg Kroah-Hartman

From: Zheng Yejian <[email protected]>

commit 2cc6a528882d0e0ccbc1bca5f95b8c963cedac54 upstream.

When number of synth fields is more than SYNTH_FIELDS_MAX, parse_action_params() should return -EINVAL.

Fixes c282a386a397 ("tracing: Add 'onmatch' hist trigger action support")
---
 kernel/trace/trace_events_hist.c |    1 +
 1 file changed, 1 insertion(+)
kernel/trace/trace_events_hist.c +1 -0
@@ -3190,6 +3190,7 @@ static int parse_action_params(struct tr
 	while (params) {
 		if (data->n_params >= SYNTH_FIELDS_MAX) {
 			hist_err(tr, HIST_ERR_TOO_MANY_PARAMS, 0);
+			ret = -EINVAL;
 			goto out;
 		}
 
author maintainer
#106 lore raw

PATCH 103/290 tracing/probes: Handle system names with hyphens

In reply to Greg Kroah-Hartman

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

commit 575b76cb885532aae13a9d979fd476bb2b156cb9 upstream.

When creating probe names, a check is done to make sure it matches basic C standard variable naming standards. Basically, starts with alphabetic or underline, and then the rest of the characters have alpha-numeric or underline in them.

But system names do not have any true naming conventions, as they are created by the TRACE_SYSTEM macro and nothing tests to see what they are. The "xhci-hcd" trace events has a '-' in the system name. When trying to attach a eprobe to one of these trace points, it fails because the system name does not follow the variable naming convention because of the hyphen, and the eprobe checks fail on this.

Allow hyphens in the system name so that eprobes can attach to the "xhci-hcd" trace events.

Cc Masami Hiramatsu <[email protected]>
Fixes 5b7a96220900e ("tracing/probe: Check event/group naming rule at parsing")
---
 kernel/trace/trace.h       |   19 ++++++++++++++++---
 kernel/trace/trace_probe.c |    2 +-
 2 files changed, 17 insertions(+), 4 deletions(-)
kernel/trace/trace.h +16 -3
@@ -1939,17 +1939,30 @@ static __always_inline void trace_iterat
 }
 
 /* Check the name is good for event/group/fields */
-static inline bool is_good_name(const char *name)
+static inline bool __is_good_name(const char *name, bool hash_ok)
 {
-	if (!isalpha(*name) && *name != '_')
+	if (!isalpha(*name) && *name != '_' && (!hash_ok || *name != '-'))
 		return false;
 	while (*++name != '\0') {
-		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
+		if (!isalpha(*name) && !isdigit(*name) && *name != '_' &&
+		    (!hash_ok || *name != '-'))
 			return false;
 	}
 	return true;
 }
 
+/* Check the name is good for event/group/fields */
+static inline bool is_good_name(const char *name)
+{
+	return __is_good_name(name, false);
+}
+
+/* Check the name is good for system */
+static inline bool is_good_system_name(const char *name)
+{
+	return __is_good_name(name, true);
+}
+
 /* Convert certain expected symbols into '_' when generating event names */
 static inline void sanitize_event_name(char *name)
 {
kernel/trace/trace_probe.c +1 -1
@@ -246,7 +246,7 @@ int traceprobe_parse_event_name(const ch
 			return -EINVAL;
 		}
 		strlcpy(buf, event, slash - event + 1);
-		if (!is_good_name(buf)) {
+		if (!is_good_system_name(buf)) {
 			trace_probe_log_err(offset, BAD_GROUP_NAME);
 			return -EINVAL;
 		}
author maintainer
#107 lore raw

PATCH 104/290 tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line

In reply to Greg Kroah-Hartman

From: Yang Jihong <[email protected]>

commit c1ac03af6ed45d05786c219d102f37eb44880f28 upstream.

print_trace_line may overflow seq_file buffer. If the event is not consumed, the while loop keeps peeking this event, causing a infinite loop.

Cc Masami Hiramatsu <[email protected]>
Fixes 088b1e427dbba ("ftrace: pipe fixes")
---
 kernel/trace/trace.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
kernel/trace/trace.c +14 -1
@@ -6764,7 +6764,20 @@ waitagain:
 
 		ret = print_trace_line(iter);
 		if (ret == TRACE_TYPE_PARTIAL_LINE) {
-			/* don't print partial lines */
+			/*
+			 * If one print_trace_line() fills entire trace_seq in one shot,
+			 * trace_seq_to_user() will returns -EBUSY because save_len == 0,
+			 * In this case, we need to consume it, otherwise, loop will peek
+			 * this event next time, resulting in an infinite loop.
+			 */
+			if (save_len == 0) {
+				iter->seq.full = 0;
+				trace_seq_puts(&iter->seq, "[LINE TOO BIG]\n");
+				trace_consume(iter);
+				break;
+			}
+
+			/* In other cases, don't print partial lines */
 			iter->seq.seq.len = save_len;
 			break;
 		}
author maintainer
#108 lore raw

PATCH 105/290 staging: media: tegra-video: fix chan->mipi value on error

In reply to Greg Kroah-Hartman

From: Luca Ceresoli <[email protected]>

commit 10b5ce6743c839fa75336042c64e2479caec9430 upstream.

chan->mipi takes the return value of tegra_mipi_request() which can be a valid pointer or an error. However chan->mipi is checked in several places, including error-cleanup code in tegra_csi_channels_cleanup(), as 'if (chan->mipi)', which suggests the initial intent was that chan->mipi should be either NULL or a valid pointer, never an error. As a consequence, cleanup code in case of tegra_mipi_request() errors would dereference an invalid pointer.

Fix by ensuring chan->mipi always contains either NULL or a void pointer.

Also add that to the documentation.

Fixes 523c857e34ce ("media: tegra-video: Add CSI MIPI pads calibration")
---
 drivers/staging/media/tegra-video/csi.c |    1 +
 drivers/staging/media/tegra-video/csi.h |    2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/staging/media/tegra-video/csi.c +1 -0
@@ -448,6 +448,7 @@ static int tegra_csi_channel_alloc(struc
 	chan->mipi = tegra_mipi_request(csi->dev, node);
 	if (IS_ERR(chan->mipi)) {
 		ret = PTR_ERR(chan->mipi);
+		chan->mipi = NULL;
 		dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
 	}
 
drivers/staging/media/tegra-video/csi.h +1 -1
@@ -56,7 +56,7 @@ struct tegra_csi;
  * @framerate: active framerate for TPG
  * @h_blank: horizontal blanking for TPG active format
  * @v_blank: vertical blanking for TPG active format
- * @mipi: mipi device for corresponding csi channel pads
+ * @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error)
  * @pixel_rate: active pixel rate from the sensor on this channel
  */
 struct tegra_csi_channel {
author maintainer
#109 lore raw

PATCH 106/290 staging: media: tegra-video: fix device_node use after free

In reply to Greg Kroah-Hartman

From: Luca Ceresoli <[email protected]>

commit c4d344163c3a7f90712525f931a6c016bbb35e18 upstream.

At probe time this code path is followed:

* tegra_csi_init
* tegra_csi_channels_alloc
* for_each_child_of_node(node, channel) -- iterates over channels
* automatically gets 'channel'
* tegra_csi_channel_alloc()
* saves into chan->of_node a pointer to the channel OF node
* automatically gets and puts 'channel'
* now the node saved in chan->of_node has refcount 0, can disappear
* tegra_csi_channels_init
* iterates over channels
* tegra_csi_channel_init -- uses chan->of_node

After that, chan->of_node keeps storing the node until the device is removed.

of_node_get() the node and of_node_put() it during teardown to avoid any risk.

Fixes 1ebaeb09830f ("media: tegra-video: Add support for external sensor capture")
Cc Sowjanya Komatineni <[email protected]>
---
 drivers/staging/media/tegra-video/csi.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/staging/media/tegra-video/csi.c +2 -1
@@ -433,7 +433,7 @@ static int tegra_csi_channel_alloc(struc
 	for (i = 0; i < chan->numgangports; i++)
 		chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;
 
-	chan->of_node = node;
+	chan->of_node = of_node_get(node);
 	chan->numpads = num_pads;
 	if (num_pads & 0x2) {
 		chan->pads[0].flags = MEDIA_PAD_FL_SINK;
@@ -641,6 +641,7 @@ static void tegra_csi_channels_cleanup(s
 			media_entity_cleanup(&subdev->entity);
 		}
 
+		of_node_put(chan->of_node);
 		list_del(&chan->list);
 		kfree(chan);
 	}
author maintainer
#110 lore raw

PATCH 107/290 ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod

In reply to Greg Kroah-Hartman

From: Nick Desaulniers <[email protected]>

commit 3220022038b9a3845eea762af85f1c5694b9f861 upstream.

clang-15's ability to elide loops completely became more aggressive when it can deduce how a variable is being updated in a loop. Counting down one variable by an increment of another can be replaced by a modulo operation.

For 64b variables on 32b ARM EABI targets, this can result in the compiler generating calls to __aeabi_uldivmod, which it does for a do while loop in float64_rem().

For the kernel, we'd generally prefer that developers not open code 64b division via binary / operators and instead use the more explicit helpers from div64.h. On arm-linux-gnuabi targets, failure to do so can result in linkage failures due to undefined references to __aeabi_uldivmod().

While developers can avoid open coding divisions on 64b variables, the compiler doesn't know that the Linux kernel has a partial implementation of a compiler runtime (--rtlib) to enforce this convention.

It's also undecidable for the compiler whether the code in question would be faster to execute the loop vs elide it and do the 64b division.

While I actively avoid using the internal -mllvm command line flags, I think we get better code than using barrier() here, which will force reloads+spills in the loop for all toolchains.

---
 arch/arm/nwfpe/Makefile |    6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/nwfpe/Makefile +6 -0
@@ -11,3 +11,9 @@ nwfpe-y				+= fpa11.o fpa11_cpdo.o fpa11
 				   entry.o
 
 nwfpe-$(CONFIG_FPE_NWFPE_XP)	+= extended_cpdo.o
+
+# Try really hard to avoid generating calls to __aeabi_uldivmod() from
+# float64_rem() due to loop elision.
+ifdef CONFIG_CC_IS_CLANG
+CFLAGS_softfloat.o	+= -mllvm -replexitval=never
+endif
author maintainer
#111 lore raw

PATCH 108/290 media: dvb-core: Fix double free in dvb_register_device()

In reply to Greg Kroah-Hartman

From: Keita Suzuki <[email protected]>

commit 6b0d0477fce747d4137aa65856318b55fba72198 upstream.

In function dvb_register_device() -> dvb_register_media_device() -> dvb_create_media_entity(), dvb->entity is allocated and initialized. If the initialization fails, it frees the dvb->entity, and return an error code. The caller takes the error code and handles the error by calling dvb_media_device_free(), which unregisters the entity and frees the field again if it is not NULL. As dvb->entity may not NULLed in dvb_create_media_entity() when the allocation of dvbdev->pad fails, a double free may occur. This may also cause an Use After free in media_device_unregister_entity().

Fix this by storing NULL to dvb->entity when it is freed.

---
 drivers/media/dvb-core/dvbdev.c |    1 +
 1 file changed, 1 insertion(+)
drivers/media/dvb-core/dvbdev.c +1 -0
@@ -345,6 +345,7 @@ static int dvb_create_media_entity(struc
 				       GFP_KERNEL);
 		if (!dvbdev->pads) {
 			kfree(dvbdev->entity);
+			dvbdev->entity = NULL;
 			return -ENOMEM;
 		}
 	}
author maintainer
#112 lore raw

PATCH 109/290 media: dvb-core: Fix UAF due to refcount races at releasing

In reply to Greg Kroah-Hartman

From: Takashi Iwai <[email protected]>

commit fd3d91ab1c6ab0628fe642dd570b56302c30a792 upstream.

The dvb-core tries to sync the releases of opened files at dvb_dmxdev_release() with two refcounts: dvbdev->users and dvr_dvbdev->users. A problem is present in those two syncs: when yet another dvb_demux_open() is called during those sync waits, dvb_demux_open() continues to process even if the device is being closed. This includes the increment of the former refcount, resulting in the leftover refcount after the sync of the latter refcount at dvb_dmxdev_release(). It ends up with use-after-free, since the function believes that all usages were gone and releases the resources.

This patch addresses the problem by adding the check of dmxdev->exit flag at dvb_demux_open(), just like dvb_dvr_open() already does. With the exit flag check, the second call of dvb_demux_open() fails, hence the further corruption can be avoided.

Also for avoiding the races of the dmxdev->exit flag reference, this patch serializes the dmxdev->exit set up and the sync waits with the dmxdev->mutex lock at dvb_dmxdev_release(). Without the mutex lock, dvb_demux_open() (or dvb_dvr_open()) may run concurrently with dvb_dmxdev_release(), which allows to skip the exit flag check and continue the open process that is being closed.

CVE-2022-41218 is assigned to those bugs above.

---
 drivers/media/dvb-core/dmxdev.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/media/dvb-core/dmxdev.c +8 -0
@@ -800,6 +800,11 @@ static int dvb_demux_open(struct inode *
 	if (mutex_lock_interruptible(&dmxdev->mutex))
 		return -ERESTARTSYS;
 
+	if (dmxdev->exit) {
+		mutex_unlock(&dmxdev->mutex);
+		return -ENODEV;
+	}
+
 	for (i = 0; i < dmxdev->filternum; i++)
 		if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
 			break;
@@ -1458,7 +1463,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
 
 void dvb_dmxdev_release(struct dmxdev *dmxdev)
 {
+	mutex_lock(&dmxdev->mutex);
 	dmxdev->exit = 1;
+	mutex_unlock(&dmxdev->mutex);
+
 	if (dmxdev->dvbdev->users > 1) {
 		wait_event(dmxdev->dvbdev->wait_queue,
 				dmxdev->dvbdev->users == 1);
author maintainer
#113 lore raw

PATCH 110/290 cifs: fix confusing debug message

In reply to Greg Kroah-Hartman

From: Paulo Alcantara <[email protected]>

commit a85ceafd41927e41a4103d228a993df7edd8823b upstream.

Since rc was initialised to -ENOMEM in cifs_get_smb_ses(), when an existing smb session was found, free_xid() would be called and then print

CIFS: fs/cifs/connect.c: Existing tcp session with server found
CIFS: fs/cifs/connect.c: VFS: in cifs_get_smb_ses as Xid: 44 with uid: 0
CIFS: fs/cifs/connect.c: Existing smb sess found (status=1)
CIFS: fs/cifs/connect.c: VFS: leaving cifs_get_smb_ses (xid = 44) rc = -12

Fix this by initialising rc to 0 and then let free_xid() print this instead

CIFS: fs/cifs/connect.c: Existing tcp session with server found
CIFS: fs/cifs/connect.c: VFS: in cifs_get_smb_ses as Xid: 14 with uid: 0
CIFS: fs/cifs/connect.c: Existing smb sess found (status=1)
CIFS: fs/cifs/connect.c: VFS: leaving cifs_get_smb_ses (xid = 14) rc = 0

---
 fs/cifs/connect.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/cifs/connect.c +3 -1
@@ -1948,7 +1948,7 @@ cifs_set_cifscreds(struct smb3_fs_contex
 struct cifs_ses *
 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
 {
-	int rc = -ENOMEM;
+	int rc = 0;
 	unsigned int xid;
 	struct cifs_ses *ses;
 	struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
@@ -1990,6 +1990,8 @@ cifs_get_smb_ses(struct TCP_Server_Info
 		return ses;
 	}
 
+	rc = -ENOMEM;
+
 	cifs_dbg(FYI, "Existing smb sess not found\n");
 	ses = sesInfoAlloc();
 	if (ses == NULL)
author maintainer
#114 lore raw

PATCH 111/290 cifs: fix missing display of three mount options

In reply to Greg Kroah-Hartman

From: Steve French <[email protected]>

commit 2bfd81043e944af0e52835ef6d9b41795af22341 upstream.

Three mount options: "tcpnodelay" and "noautotune" and "noblocksend" were not displayed when passed in on cifs/smb3 mounts (e.g. displayed in /proc/mounts e.g.). No change to defaults so these are not displayed if not specified on mount.

---
 fs/cifs/cifsfs.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
fs/cifs/cifsfs.c +7 -1
@@ -656,9 +656,15 @@ cifs_show_options(struct seq_file *s, st
 	seq_printf(s, ",echo_interval=%lu",
 			tcon->ses->server->echo_interval / HZ);
 
-	/* Only display max_credits if it was overridden on mount */
+	/* Only display the following if overridden on mount */
 	if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
 		seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
+	if (tcon->ses->server->tcp_nodelay)
+		seq_puts(s, ",tcpnodelay");
+	if (tcon->ses->server->noautotune)
+		seq_puts(s, ",noautotune");
+	if (tcon->ses->server->noblocksnd)
+		seq_puts(s, ",noblocksend");
 
 	if (tcon->snapshot_time)
 		seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
author maintainer
#115 lore raw

PATCH 112/290 rtc: ds1347: fix value written to century register

In reply to Greg Kroah-Hartman

From: Ian Abbott <[email protected]>

commit 4dfe05bdc1ade79b943d4979a2e2a8b5ef68fbb5 upstream.

In ds1347_set_time(), the wrong value is being written to the DS1347_CENTURY_REG register. It needs to be converted to BCD. Fix it.

Fixes 147dae76dbb9 ("rtc: ds1347: handle century register")
Cc <[email protected]> # v5.5+
---
 drivers/rtc/rtc-ds1347.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-ds1347.c +1 -1
@@ -112,7 +112,7 @@ static int ds1347_set_time(struct device
 		return err;
 
 	century = (dt->tm_year / 100) + 19;
-	err = regmap_write(map, DS1347_CENTURY_REG, century);
+	err = regmap_write(map, DS1347_CENTURY_REG, bin2bcd(century));
 	if (err)
 		return err;
 
author maintainer
#116 lore raw

PATCH 113/290 block: mq-deadline: Do not break sequential write streams to zoned HDDs

In reply to Greg Kroah-Hartman

From: Damien Le Moal <[email protected]>

commit 015d02f48537cf2d1a65eeac50717566f9db6eec upstream.

mq-deadline ensures an in order dispatching of write requests to zoned block devices using a per zone lock (a bit). This implies that for any purely sequential write workload, the drive is exercised most of the time at a maximum queue depth of one.

However, when such sequential write workload crosses a zone boundary (when sequentially writing multiple contiguous zones), zone write locking may prevent the last write to one zone to be issued (as the previous write is still being executed) but allow the first write to the following zone to be issued (as that zone is not yet being writen and not locked). This result in an out of order delivery of the sequential write commands to the device every time a zone boundary is crossed.

While such behavior does not break the sequential write constraint of zoned block devices (and does not generate any write error), some zoned hard-disks react badly to seeing these out of order writes, resulting in lower write throughput.

This problem can be addressed by always dispatching the first request of a stream of sequential write requests, regardless of the zones targeted by these sequential writes. To do so, the function deadline_skip_seq_writes() is introduced and used in deadline_next_request() to select the next write command to issue if the target device is an HDD (blk_queue_nonrot() being false). deadline_fifo_request() is modified using the new deadline_earlier_request() and deadline_is_seq_write() helpers to ignore requests in the fifo list that have a preceding request in lba order that is sequential.

With this fix, a sequential write workload executed with the following fio command:

fio  --name=seq-write --filename=/dev/sda --zonemode=zbd --direct=1 \
     --size=68719476736  --ioengine=libaio --iodepth=32 --rw=write \
     --bs=65536

results in an increase from 225 MB/s to 250 MB/s of the write throughput of an SMR HDD (11% increase).

---
 block/mq-deadline.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 4 deletions(-)
block/mq-deadline.c +62 -4
@@ -154,6 +154,20 @@ static u8 dd_rq_ioclass(struct request *
 }
 
 /*
+ * get the request before `rq' in sector-sorted order
+ */
+static inline struct request *
+deadline_earlier_request(struct request *rq)
+{
+	struct rb_node *node = rb_prev(&rq->rb_node);
+
+	if (node)
+		return rb_entry_rq(node);
+
+	return NULL;
+}
+
+/*
  * get the request after `rq' in sector-sorted order
  */
 static inline struct request *
@@ -289,6 +303,39 @@ static inline int deadline_check_fifo(st
 }
 
 /*
+ * Check if rq has a sequential request preceding it.
+ */
+static bool deadline_is_seq_writes(struct deadline_data *dd, struct request *rq)
+{
+	struct request *prev = deadline_earlier_request(rq);
+
+	if (!prev)
+		return false;
+
+	return blk_rq_pos(prev) + blk_rq_sectors(prev) == blk_rq_pos(rq);
+}
+
+/*
+ * Skip all write requests that are sequential from @rq, even if we cross
+ * a zone boundary.
+ */
+static struct request *deadline_skip_seq_writes(struct deadline_data *dd,
+						struct request *rq)
+{
+	sector_t pos = blk_rq_pos(rq);
+	sector_t skipped_sectors = 0;
+
+	while (rq) {
+		if (blk_rq_pos(rq) != pos + skipped_sectors)
+			break;
+		skipped_sectors += blk_rq_sectors(rq);
+		rq = deadline_latter_request(rq);
+	}
+
+	return rq;
+}
+
+/*
  * For the specified data direction, return the next request to
  * dispatch using arrival ordered lists.
  */
@@ -308,11 +355,16 @@ deadline_fifo_request(struct deadline_da
 
 	/*
 	 * Look for a write request that can be dispatched, that is one with
-	 * an unlocked target zone.
+	 * an unlocked target zone. For some HDDs, breaking a sequential
+	 * write stream can lead to lower throughput, so make sure to preserve
+	 * sequential write streams, even if that stream crosses into the next
+	 * zones and these zones are unlocked.
 	 */
 	spin_lock_irqsave(&dd->zone_lock, flags);
 	list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) {
-		if (blk_req_can_dispatch_to_zone(rq))
+		if (blk_req_can_dispatch_to_zone(rq) &&
+		    (blk_queue_nonrot(rq->q) ||
+		     !deadline_is_seq_writes(dd, rq)))
 			goto out;
 	}
 	rq = NULL;
@@ -342,13 +394,19 @@ deadline_next_request(struct deadline_da
 
 	/*
 	 * Look for a write request that can be dispatched, that is one with
-	 * an unlocked target zone.
+	 * an unlocked target zone. For some HDDs, breaking a sequential
+	 * write stream can lead to lower throughput, so make sure to preserve
+	 * sequential write streams, even if that stream crosses into the next
+	 * zones and these zones are unlocked.
 	 */
 	spin_lock_irqsave(&dd->zone_lock, flags);
 	while (rq) {
 		if (blk_req_can_dispatch_to_zone(rq))
 			break;
-		rq = deadline_latter_request(rq);
+		if (blk_queue_nonrot(rq->q))
+			rq = deadline_latter_request(rq);
+		else
+			rq = deadline_skip_seq_writes(dd, rq);
 	}
 	spin_unlock_irqrestore(&dd->zone_lock, flags);
 
author maintainer
#117 lore raw

PATCH 114/290 md/bitmap: Fix bitmap chunk size overflow issues

In reply to Greg Kroah-Hartman

From: Florian-Ewald Mueller <[email protected]>

commit 4555211190798b6b6fa2c37667d175bf67945c78 upstream.

- limit bitmap chunk size internal u64 variable to values not overflowing the u32 bitmap superblock structure variable stored on persistent media
- assign bitmap chunk size internal u64 variable from unsigned values to avoid possible sign extension artifacts when assigning from a s32 value

The bug has been there since at least kernel 4.0.
Steps to reproduce it:
1: mdadm -C /dev/mdx -l 1 --bitmap=internal --bitmap-chunk=256M -e 1.2 -n2 /dev/rnbd1 /dev/rnbd2
2 resize member device rnbd1 and rnbd2 to 8 TB
3 mdadm --grow /dev/mdx --size=max

The bitmap_chunksize will overflow without patch.

---
 drivers/md/md-bitmap.c |   20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
drivers/md/md-bitmap.c +12 -8
@@ -486,7 +486,7 @@ void md_bitmap_print_sb(struct bitmap *b
 	sb = kmap_atomic(bitmap->storage.sb_page);
 	pr_debug("%s: bitmap file superblock:\n", bmname(bitmap));
 	pr_debug("         magic: %08x\n", le32_to_cpu(sb->magic));
-	pr_debug("       version: %d\n", le32_to_cpu(sb->version));
+	pr_debug("       version: %u\n", le32_to_cpu(sb->version));
 	pr_debug("          uuid: %08x.%08x.%08x.%08x\n",
 		 le32_to_cpu(*(__le32 *)(sb->uuid+0)),
 		 le32_to_cpu(*(__le32 *)(sb->uuid+4)),
@@ -497,11 +497,11 @@ void md_bitmap_print_sb(struct bitmap *b
 	pr_debug("events cleared: %llu\n",
 		 (unsigned long long) le64_to_cpu(sb->events_cleared));
 	pr_debug("         state: %08x\n", le32_to_cpu(sb->state));
-	pr_debug("     chunksize: %d B\n", le32_to_cpu(sb->chunksize));
-	pr_debug("  daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep));
+	pr_debug("     chunksize: %u B\n", le32_to_cpu(sb->chunksize));
+	pr_debug("  daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep));
 	pr_debug("     sync size: %llu KB\n",
 		 (unsigned long long)le64_to_cpu(sb->sync_size)/2);
-	pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind));
+	pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind));
 	kunmap_atomic(sb);
 }
 
@@ -2106,7 +2106,8 @@ int md_bitmap_resize(struct bitmap *bitm
 			bytes = DIV_ROUND_UP(chunks, 8);
 			if (!bitmap->mddev->bitmap_info.external)
 				bytes += sizeof(bitmap_super_t);
-		} while (bytes > (space << 9));
+		} while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) <
+			(BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1));
 	} else
 		chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT;
 
@@ -2151,7 +2152,7 @@ int md_bitmap_resize(struct bitmap *bitm
 	bitmap->counts.missing_pages = pages;
 	bitmap->counts.chunkshift = chunkshift;
 	bitmap->counts.chunks = chunks;
-	bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift +
+	bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift +
 						     BITMAP_BLOCK_SHIFT);
 
 	blocks = min(old_counts.chunks << old_counts.chunkshift,
@@ -2177,8 +2178,8 @@ int md_bitmap_resize(struct bitmap *bitm
 				bitmap->counts.missing_pages = old_counts.pages;
 				bitmap->counts.chunkshift = old_counts.chunkshift;
 				bitmap->counts.chunks = old_counts.chunks;
-				bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift +
-									     BITMAP_BLOCK_SHIFT);
+				bitmap->mddev->bitmap_info.chunksize =
+					1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT);
 				blocks = old_counts.chunks << old_counts.chunkshift;
 				pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n");
 				break;
@@ -2519,6 +2520,9 @@ chunksize_store(struct mddev *mddev, con
 	if (csize < 512 ||
 	    !is_power_of_2(csize))
 		return -EINVAL;
+	if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE *
+		sizeof(((bitmap_super_t *)0)->chunksize))))
+		return -EOVERFLOW;
 	mddev->bitmap_info.chunksize = csize;
 	return len;
 }
author maintainer
#118 lore raw

PATCH 115/290 efi: Add iMac Pro 2017 to uefi skip cert quirk

In reply to Greg Kroah-Hartman

From: Aditya Garg <[email protected]>

commit 0be56a116220f9e5731a6609e66a11accfe8d8e2 upstream.

The iMac Pro 2017 is also a T2 Mac. Thus add it to the list of uefi skip cert.

Fixes 155ca952c7ca ("efi: Do not import certificates from UEFI Secure Boot for T2 Macs")
---
 security/integrity/platform_certs/load_uefi.c |    1 +
 1 file changed, 1 insertion(+)
security/integrity/platform_certs/load_uefi.c +1 -0
@@ -34,6 +34,7 @@ static const struct dmi_system_id uefi_s
 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "MacPro7,1") },
 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,1") },
 	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMac20,2") },
+	{ UEFI_QUIRK_SKIP_CERT("Apple Inc.", "iMacPro1,1") },
 	{ }
 };
 
author maintainer
#119 lore raw

PATCH 116/290 wifi: wilc1000: sdio: fix module autoloading

In reply to Greg Kroah-Hartman

From: Michael Walle <[email protected]>

commit 57d545b5a3d6ce3a8fb6b093f02bfcbb908973f3 upstream.

There are no SDIO module aliases included in the driver, therefore, module autoloading isn't working. Add the proper MODULE_DEVICE_TABLE().

---
 drivers/net/wireless/microchip/wilc1000/sdio.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/microchip/wilc1000/sdio.c +1 -0
@@ -20,6 +20,7 @@ static const struct sdio_device_id wilc_
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
 	{ },
 };
+MODULE_DEVICE_TABLE(sdio, wilc_sdio_ids);
 
 #define WILC_SDIO_BLOCK_SIZE 512
 
author maintainer
#120 lore raw

PATCH 117/290 ASoC: jz4740-i2s: Handle independent FIFO flush bits

In reply to Greg Kroah-Hartman

From: Aidan MacDonald <[email protected]>

commit 8b3a9ad86239f80ed569e23c3954a311f66481d6 upstream.

On the JZ4740, there is a single bit that flushes (empties) both the transmit and receive FIFO. Later SoCs have independent flush bits for each FIFO.

Independent FIFOs can be flushed before the snd_soc_dai_active() check because it won't disturb other active streams. This ensures that the FIFO we're about to use is always flushed before starting up. With shared FIFOs we can't do that because if another substream is active, flushing its FIFO would cause underrun errors.

This also fixes a bug: since we were only setting the JZ4740's flush bit, which corresponds to the TX FIFO flush bit on other SoCs, other SoCs were not having their RX FIFO flushed at all.

---
 sound/soc/jz4740/jz4740-i2s.c |   39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)
sound/soc/jz4740/jz4740-i2s.c +34 -5
@@ -56,7 +56,8 @@
 #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
 #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
 #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
-#define JZ_AIC_CTRL_FLUSH		BIT(8)
+#define JZ_AIC_CTRL_TFLUSH		BIT(8)
+#define JZ_AIC_CTRL_RFLUSH		BIT(7)
 #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
 #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
 #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
@@ -91,6 +92,8 @@ enum jz47xx_i2s_version {
 struct i2s_soc_info {
 	enum jz47xx_i2s_version version;
 	struct snd_soc_dai_driver *dai;
+
+	bool shared_fifo_flush;
 };
 
 struct jz4740_i2s {
@@ -119,19 +122,44 @@ static inline void jz4740_i2s_write(cons
 	writel(value, i2s->base + reg);
 }
 
+static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s,
+	unsigned int reg, uint32_t bits)
+{
+	uint32_t value = jz4740_i2s_read(i2s, reg);
+	value |= bits;
+	jz4740_i2s_write(i2s, reg, value);
+}
+
 static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *dai)
 {
 	struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	uint32_t conf, ctrl;
+	uint32_t conf;
 	int ret;
 
+	/*
+	 * When we can flush FIFOs independently, only flush the FIFO
+	 * that is starting up. We can do this when the DAI is active
+	 * because it does not disturb other active substreams.
+	 */
+	if (!i2s->soc_info->shared_fifo_flush) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
+		else
+			jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH);
+	}
+
 	if (snd_soc_dai_active(dai))
 		return 0;
 
-	ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
-	ctrl |= JZ_AIC_CTRL_FLUSH;
-	jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
+	/*
+	 * When there is a shared flush bit for both FIFOs, the TFLUSH
+	 * bit flushes both FIFOs. Flushing while the DAI is active would
+	 * cause FIFO underruns in other active substreams so we have to
+	 * guard this behind the snd_soc_dai_active() check.
+	 */
+	if (i2s->soc_info->shared_fifo_flush)
+		jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
 
 	ret = clk_prepare_enable(i2s->clk_i2s);
 	if (ret)
@@ -462,6 +490,7 @@ static struct snd_soc_dai_driver jz4740_
 static const struct i2s_soc_info jz4740_i2s_soc_info = {
 	.version = JZ_I2S_JZ4740,
 	.dai = &jz4740_i2s_dai,
+	.shared_fifo_flush = true,
 };
 
 static const struct i2s_soc_info jz4760_i2s_soc_info = {
author maintainer
#121 lore raw

PATCH 118/290 ipu3-imgu: Fix NULL pointer dereference in imgu_subdev_set_selection()

In reply to Greg Kroah-Hartman

From: Maximilian Luz <[email protected]>

commit dc608edf7d45ba0c2ad14c06eccd66474fec7847 upstream.

Calling v4l2_subdev_get_try_crop() and v4l2_subdev_get_try_compose() with a subdev state of NULL leads to a NULL pointer dereference. This can currently happen in imgu_subdev_set_selection() when the state passed in is NULL, as this method first gets pointers to both the "try" and "active" states and only then decides which to use.

The same issue has been addressed for imgu_subdev_get_selection() with commit 30d03a0de650 ("ipu3-imgu: Fix NULL pointer dereference in active selection access"). However the issue still persists in imgu_subdev_set_selection().

Therefore, apply a similar fix as done in the aforementioned commit to imgu_subdev_set_selection(). To keep things a bit cleaner, introduce helper functions for "crop" and "compose" access and use them in both imgu_subdev_set_selection() and imgu_subdev_get_selection().

Fixes 0d346d2a6f54 ("media: v4l2-subdev: add subdev-wide state struct")
Cc [email protected] # for v5.14 and later
---
 drivers/staging/media/ipu3/ipu3-v4l2.c | 57 +++++++++++++++-----------
 1 file changed, 34 insertions(+), 23 deletions(-)
drivers/staging/media/ipu3/ipu3-v4l2.c +34 -23
index ce13e746c15f..e530767e80a5 100644
@@ -188,6 +188,28 @@ static int imgu_subdev_set_fmt(struct v4l2_subdev *sd,
 	return 0;
 }
 
+static struct v4l2_rect *
+imgu_subdev_get_crop(struct imgu_v4l2_subdev *sd,
+		     struct v4l2_subdev_state *sd_state, unsigned int pad,
+		     enum v4l2_subdev_format_whence which)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return v4l2_subdev_get_try_crop(&sd->subdev, sd_state, pad);
+	else
+		return &sd->rect.eff;
+}
+
+static struct v4l2_rect *
+imgu_subdev_get_compose(struct imgu_v4l2_subdev *sd,
+			struct v4l2_subdev_state *sd_state, unsigned int pad,
+			enum v4l2_subdev_format_whence which)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return v4l2_subdev_get_try_compose(&sd->subdev, sd_state, pad);
+	else
+		return &sd->rect.bds;
+}
+
 static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
 				     struct v4l2_subdev_state *sd_state,
 				     struct v4l2_subdev_selection *sel)
@@ -200,18 +222,12 @@ static int imgu_subdev_get_selection(struct v4l2_subdev *sd,
 
 	switch (sel->target) {
 	case V4L2_SEL_TGT_CROP:
-		if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
-			sel->r = *v4l2_subdev_get_try_crop(sd, sd_state,
-							   sel->pad);
-		else
-			sel->r = imgu_sd->rect.eff;
+		sel->r = *imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
+					       sel->which);
 		return 0;
 	case V4L2_SEL_TGT_COMPOSE:
-		if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
-			sel->r = *v4l2_subdev_get_try_compose(sd, sd_state,
-							      sel->pad);
-		else
-			sel->r = imgu_sd->rect.bds;
+		sel->r = *imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
+						  sel->which);
 		return 0;
 	default:
 		return -EINVAL;
@@ -223,10 +239,9 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
 				     struct v4l2_subdev_selection *sel)
 {
 	struct imgu_device *imgu = v4l2_get_subdevdata(sd);
-	struct imgu_v4l2_subdev *imgu_sd = container_of(sd,
-							struct imgu_v4l2_subdev,
-							subdev);
-	struct v4l2_rect *rect, *try_sel;
+	struct imgu_v4l2_subdev *imgu_sd =
+		container_of(sd, struct imgu_v4l2_subdev, subdev);
+	struct v4l2_rect *rect;
 
 	dev_dbg(&imgu->pci_dev->dev,
 		 "set subdev %u sel which %u target 0x%4x rect [%ux%u]",
@@ -238,22 +253,18 @@ static int imgu_subdev_set_selection(struct v4l2_subdev *sd,
 
 	switch (sel->target) {
 	case V4L2_SEL_TGT_CROP:
-		try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
-		rect = &imgu_sd->rect.eff;
+		rect = imgu_subdev_get_crop(imgu_sd, sd_state, sel->pad,
+					    sel->which);
 		break;
 	case V4L2_SEL_TGT_COMPOSE:
-		try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
-		rect = &imgu_sd->rect.bds;
+		rect = imgu_subdev_get_compose(imgu_sd, sd_state, sel->pad,
+					       sel->which);
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
-		*try_sel = sel->r;
-	else
-		*rect = sel->r;
-
+	*rect = sel->r;
 	return 0;
 }
 
Signature · 1 line
2.39.0
author maintainer
#122 lore raw

PATCH 119/290 ipmi: fix long wait in unload when IPMI disconnect

In reply to Greg Kroah-Hartman

From: Zhang Yuchen <[email protected]>

commit f6f1234d98cce69578bfac79df147a1f6660596c upstream.

When fixing the problem mentioned in PATCH1, we also found the following problem:

If the IPMI is disconnected and in the sending process, the uninstallation driver will be stuck for a long time.

The main problem is that uninstalling the driver waits for curr_msg to be sent or HOSED. After stopping tasklet, the only place to trigger the timeout mechanism is the circular poll in shutdown_smi.

The poll function delays 10us and calls smi_event_handler(smi_info,10). Smi_event_handler deducts 10us from kcs->ibf_timeout.

But the poll func is followed by schedule_timeout_uninterruptible(1). The time consumed here is not counted in kcs->ibf_timeout.

So when 10us is deducted from kcs->ibf_timeout, at least 1 jiffies has actually passed. The waiting time has increased by more than a hundredfold.

Now instead of calling poll(). call smi_event_handler() directly and calculate the elapsed time.

For verification, you can directly use ebpf to check the kcs-> ibf_timeout for each call to kcs_event() when IPMI is disconnected. Decrement at normal rate before unloading. The decrement rate becomes very slow after unloading.

  $ bpftrace -e 'kprobe:kcs_event {printf("kcs->ibftimeout : %d\n",
      *(arg0+584));}'

Message-Id: <[email protected]>

---
 drivers/char/ipmi/ipmi_si_intf.c |   27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)
drivers/char/ipmi/ipmi_si_intf.c +19 -8
@@ -2152,6 +2152,20 @@ skip_fallback_noirq:
 }
 module_init(init_ipmi_si);
 
+static void wait_msg_processed(struct smi_info *smi_info)
+{
+	unsigned long jiffies_now;
+	long time_diff;
+
+	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
+		jiffies_now = jiffies;
+		time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
+		     * SI_USEC_PER_JIFFY);
+		smi_event_handler(smi_info, time_diff);
+		schedule_timeout_uninterruptible(1);
+	}
+}
+
 static void shutdown_smi(void *send_info)
 {
 	struct smi_info *smi_info = send_info;
@@ -2186,16 +2200,13 @@ static void shutdown_smi(void *send_info
 	 * in the BMC.  Note that timers and CPU interrupts are off,
 	 * so no need for locks.
 	 */
-	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
-		poll(smi_info);
-		schedule_timeout_uninterruptible(1);
-	}
+	wait_msg_processed(smi_info);
+
 	if (smi_info->handlers)
 		disable_si_irq(smi_info);
-	while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) {
-		poll(smi_info);
-		schedule_timeout_uninterruptible(1);
-	}
+
+	wait_msg_processed(smi_info);
+
 	if (smi_info->handlers)
 		smi_info->handlers->cleanup(smi_info->si_sm);
 
author maintainer
#123 lore raw

PATCH 120/290 mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type()

In reply to Greg Kroah-Hartman

From: Alexander Sverdlin <[email protected]>

commit 2ebc336be08160debfe27f87660cf550d710f3e9 upstream.

Erase can be zeroed in spi_nor_parse_4bait() or spi_nor_init_non_uniform_erase_map(). In practice it happened with mt25qu256a, which supports 4K, 32K, 64K erases with 3b address commands, but only 4K and 64K erase with 4b address commands.

Fixes dc92843159a7 ("mtd: spi-nor: fix erase_type array to indicate current map conf")
---
 drivers/mtd/spi-nor/core.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/mtd/spi-nor/core.c +2 -0
@@ -1409,6 +1409,8 @@ spi_nor_find_best_erase_type(const struc
 			continue;
 
 		erase = &map->erase_type[i];
+		if (!erase->size)
+			continue;
 
 		/* Alignment is not mandatory for overlaid regions */
 		if (region->offset & SNOR_OVERLAID_REGION &&
author maintainer
#124 lore raw

PATCH 121/290 ima: Fix a potential NULL pointer access in ima_restore_measurement_list

In reply to Greg Kroah-Hartman

From: Huaxin Lu <[email protected]>

commit 11220db412edae8dba58853238f53258268bdb88 upstream.

In restore_template_fmt, when kstrdup fails, a non-NULL value will still be returned, which causes a NULL pointer access in template_desc_init_fields.

Fixes c7d09367702e ("ima: support restoring multiple template formats")
---
 security/integrity/ima/ima_template.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
security/integrity/ima/ima_template.c +4 -1
@@ -336,8 +336,11 @@ static struct ima_template_desc *restore
 
 	template_desc->name = "";
 	template_desc->fmt = kstrdup(template_name, GFP_KERNEL);
-	if (!template_desc->fmt)
+	if (!template_desc->fmt) {
+		kfree(template_desc);
+		template_desc = NULL;
 		goto out;
+	}
 
 	spin_lock(&template_list);
 	list_add_tail_rcu(&template_desc->list, &defined_templates);
author maintainer
#125 lore raw

PATCH 122/290 ipmi: fix use after free in _ipmi_destroy_user()

In reply to Greg Kroah-Hartman

From: Dan Carpenter <[email protected]>

commit a92ce570c81dc0feaeb12a429b4bc65686d17967 upstream.

The intf_free() function frees the "intf" pointer so we cannot dereference it again on the next line.

Fixes cbb79863fc31 ("ipmi: Don't allow device module unload when in use")

Message-Id: <Y3M8xa1drZv4CToE@kili>

---
 drivers/char/ipmi/ipmi_msghandler.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/char/ipmi/ipmi_msghandler.c +3 -1
@@ -1273,6 +1273,7 @@ static void _ipmi_destroy_user(struct ip
 	unsigned long    flags;
 	struct cmd_rcvr  *rcvr;
 	struct cmd_rcvr  *rcvrs = NULL;
+	struct module    *owner;
 
 	if (!acquire_ipmi_user(user, &i)) {
 		/*
@@ -1334,8 +1335,9 @@ static void _ipmi_destroy_user(struct ip
 		kfree(rcvr);
 	}
 
+	owner = intf->owner;
 	kref_put(&intf->refcount, intf_free);
-	module_put(intf->owner);
+	module_put(owner);
 }
 
 int ipmi_destroy_user(struct ipmi_user *user)
author maintainer
#126 lore raw

PATCH 123/290 PCI: Fix pci_device_is_present() for VFs by checking PF

In reply to Greg Kroah-Hartman

From: Michael S. Tsirkin <[email protected]>

commit 98b04dd0b4577894520493d96bc4623387767445 upstream.

pci_device_is_present() previously didn't work for VFs because it reads the Vendor and Device ID, which are 0xffff for VFs, which looks like they aren't present. Check the PF instead.

Wei Gong reported that if virtio I/O is in progress when the driver is unbound or "0" is written to /sys/.../sriov_numvfs, the virtio I/O operation hangs, which may result in output like this:

task:bash state:D stack: 0 pid: 1773 ppid: 1241 flags:0x00004002

  Call Trace:
   schedule+0x4f/0xc0
   blk_mq_freeze_queue_wait+0x69/0xa0
   blk_mq_freeze_queue+0x1b/0x20
   blk_cleanup_queue+0x3d/0xd0
   virtblk_remove+0x3c/0xb0 [virtio_blk]
   virtio_dev_remove+0x4b/0x80
   ...
   device_unregister+0x1b/0x60
   unregister_virtio_device+0x18/0x30
   virtio_pci_remove+0x41/0x80
   pci_device_remove+0x3e/0xb0

This happened because pci_device_is_present(VF) returned "false" in virtio_pci_remove(), so it called virtio_break_device(). The broken vq meant that vring_interrupt() skipped the vq.callback() that would have completed the virtio I/O operation via virtblk_done().

---
 drivers/pci/pci.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/pci/pci.c +2 -0
@@ -6383,6 +6383,8 @@ bool pci_device_is_present(struct pci_de
 {
 	u32 v;
 
+	/* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */
+	pdev = pci_physfn(pdev);
 	if (pci_dev_is_disconnected(pdev))
 		return false;
 	return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0);
author maintainer
#127 lore raw

PATCH 124/290 PCI/sysfs: Fix double free in error path

In reply to Greg Kroah-Hartman

From: Sascha Hauer <[email protected]>

commit aa382ffa705bea9931ec92b6f3c70e1fdb372195 upstream.

When pci_create_attr() fails, pci_remove_resource_files() is called which will iterate over the res_attr[_wc] arrays and frees every non NULL entry. To avoid a double free here set the array entry only after it's clear we successfully initialized it.

Fixes b562ec8f74e4 ("PCI: Don't leak memory if sysfs_create_bin_file() fails")
---
 drivers/pci/pci-sysfs.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/pci/pci-sysfs.c +9 -4
@@ -1179,11 +1179,9 @@ static int pci_create_attr(struct pci_de
 
 	sysfs_bin_attr_init(res_attr);
 	if (write_combine) {
-		pdev->res_attr_wc[num] = res_attr;
 		sprintf(res_attr_name, "resource%d_wc", num);
 		res_attr->mmap = pci_mmap_resource_wc;
 	} else {
-		pdev->res_attr[num] = res_attr;
 		sprintf(res_attr_name, "resource%d", num);
 		if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
 			res_attr->read = pci_read_resource_io;
@@ -1201,10 +1199,17 @@ static int pci_create_attr(struct pci_de
 	res_attr->size = pci_resource_len(pdev, num);
 	res_attr->private = (void *)(unsigned long)num;
 	retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
-	if (retval)
+	if (retval) {
 		kfree(res_attr);
+		return retval;
+	}
+
+	if (write_combine)
+		pdev->res_attr_wc[num] = res_attr;
+	else
+		pdev->res_attr[num] = res_attr;
 
-	return retval;
+	return 0;
 }
 
 /**
author maintainer
#128 lore raw

PATCH 125/290 riscv: stacktrace: Fixup ftrace_graph_ret_addr retp argument

In reply to Greg Kroah-Hartman

From: Guo Ren <[email protected]>

commit 5c3022e4a616d800cf5f4c3a981d7992179e44a1 upstream.

The 'retp' is a pointer to the return address on the stack, so we must pass the current return address pointer as the 'retp' argument to ftrace_push_return_trace(). Not parent function's return address on the stack.

Fixes b785ec129bd9 ("riscv/ftrace: Add HAVE_FUNCTION_GRAPH_RET_ADDR_PTR support")
---
 arch/riscv/kernel/stacktrace.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/stacktrace.c +1 -1
@@ -60,7 +60,7 @@ void notrace walk_stackframe(struct task
 		} else {
 			fp = frame->fp;
 			pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
-						   (unsigned long *)(fp - 8));
+						   &frame->ra);
 		}
 
 	}
author maintainer
#129 lore raw

PATCH 126/290 riscv: mm: notify remote harts about mmu cache updates

In reply to Greg Kroah-Hartman

From: Sergey Matyukevich <[email protected]>

commit 4bd1d80efb5af640f99157f39b50fb11326ce641 upstream.

Current implementation of update_mmu_cache function performs local TLB flush. It does not take into account ASID information. Besides, it does not take into account other harts currently running the same mm context or possible migration of the running context to other harts. Meanwhile TLB flush is not performed for every context switch if ASID support is enabled.

Patch [1] proposed to add ASID support to update_mmu_cache to avoid flushing local TLB entirely. This patch takes into account other harts currently running the same mm context as well as possible migration of this context to other harts.

For this purpose the approach from flush_icache_mm is reused. Remote harts currently running the same mm context are informed via SBI calls that they need to flush their local TLBs. All the other harts are marked as needing a deferred TLB flush when this mm context runs on them.

[1] https://lore.kernel.org/linux-riscv/[email protected]/

---
 arch/riscv/include/asm/mmu.h      |    2 ++
 arch/riscv/include/asm/pgtable.h  |    2 +-
 arch/riscv/include/asm/tlbflush.h |   18 ++++++++++++++++++
 arch/riscv/mm/context.c           |   10 ++++++++++
 arch/riscv/mm/tlbflush.c          |   28 +++++++++++-----------------
 5 files changed, 42 insertions(+), 18 deletions(-)
arch/riscv/include/asm/mmu.h +2 -0
@@ -19,6 +19,8 @@ typedef struct {
 #ifdef CONFIG_SMP
 	/* A local icache flush is needed before user execution can resume. */
 	cpumask_t icache_stale_mask;
+	/* A local tlb flush is needed before user execution can resume. */
+	cpumask_t tlb_stale_mask;
 #endif
 } mm_context_t;
 
arch/riscv/include/asm/pgtable.h +1 -1
@@ -386,7 +386,7 @@ static inline void update_mmu_cache(stru
 	 * Relying on flush_tlb_fix_spurious_fault would suffice, but
 	 * the extra traps reduce performance.  So, eagerly SFENCE.VMA.
 	 */
-	local_flush_tlb_page(address);
+	flush_tlb_page(vma, address);
 }
 
 static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
arch/riscv/include/asm/tlbflush.h +18 -0
@@ -22,6 +22,24 @@ static inline void local_flush_tlb_page(
 {
 	ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
 }
+
+static inline void local_flush_tlb_all_asid(unsigned long asid)
+{
+	__asm__ __volatile__ ("sfence.vma x0, %0"
+			:
+			: "r" (asid)
+			: "memory");
+}
+
+static inline void local_flush_tlb_page_asid(unsigned long addr,
+		unsigned long asid)
+{
+	__asm__ __volatile__ ("sfence.vma %0, %1"
+			:
+			: "r" (addr), "r" (asid)
+			: "memory");
+}
+
 #else /* CONFIG_MMU */
 #define local_flush_tlb_all()			do { } while (0)
 #define local_flush_tlb_page(addr)		do { } while (0)
arch/riscv/mm/context.c +10 -0
@@ -196,6 +196,16 @@ switch_mm_fast:
 
 	if (need_flush_tlb)
 		local_flush_tlb_all();
+#ifdef CONFIG_SMP
+	else {
+		cpumask_t *mask = &mm->context.tlb_stale_mask;
+
+		if (cpumask_test_cpu(cpu, mask)) {
+			cpumask_clear_cpu(cpu, mask);
+			local_flush_tlb_all_asid(cntx & asid_mask);
+		}
+	}
+#endif
 }
 
 static void set_mm_noasid(struct mm_struct *mm)
arch/riscv/mm/tlbflush.c +11 -17
@@ -5,23 +5,7 @@
 #include <linux/sched.h>
 #include <asm/sbi.h>
 #include <asm/mmu_context.h>
-
-static inline void local_flush_tlb_all_asid(unsigned long asid)
-{
-	__asm__ __volatile__ ("sfence.vma x0, %0"
-			:
-			: "r" (asid)
-			: "memory");
-}
-
-static inline void local_flush_tlb_page_asid(unsigned long addr,
-		unsigned long asid)
-{
-	__asm__ __volatile__ ("sfence.vma %0, %1"
-			:
-			: "r" (addr), "r" (asid)
-			: "memory");
-}
+#include <asm/tlbflush.h>
 
 void flush_tlb_all(void)
 {
@@ -31,6 +15,7 @@ void flush_tlb_all(void)
 static void __sbi_tlb_flush_range(struct mm_struct *mm, unsigned long start,
 				  unsigned long size, unsigned long stride)
 {
+	struct cpumask *pmask = &mm->context.tlb_stale_mask;
 	struct cpumask *cmask = mm_cpumask(mm);
 	struct cpumask hmask;
 	unsigned int cpuid;
@@ -45,6 +30,15 @@ static void __sbi_tlb_flush_range(struct
 	if (static_branch_unlikely(&use_asid_allocator)) {
 		unsigned long asid = atomic_long_read(&mm->context.id);
 
+		/*
+		 * TLB will be immediately flushed on harts concurrently
+		 * executing this MM context. TLB flush on other harts
+		 * is deferred until this MM context migrates there.
+		 */
+		cpumask_setall(pmask);
+		cpumask_clear_cpu(cpuid, pmask);
+		cpumask_andnot(pmask, pmask, cmask);
+
 		if (broadcast) {
 			riscv_cpuid_to_hartid_mask(cmask, &hmask);
 			sbi_remote_sfence_vma_asid(cpumask_bits(&hmask),
author maintainer
#130 lore raw

PATCH 127/290 crypto: n2 - add missing hash statesize

In reply to Greg Kroah-Hartman

From: Corentin Labbe <[email protected]>

commit 76a4e874593543a2dff91d249c95bac728df2774 upstream.

Add missing statesize to hash templates.
This is mandatory otherwise no algorithms can be registered as the core requires statesize to be set.

Fixes 0a625fd2abaa ("crypto: n2 - Add Niagara2 crypto driver")
---
 drivers/crypto/n2_core.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/crypto/n2_core.c +6 -0
@@ -1229,6 +1229,7 @@ struct n2_hash_tmpl {
 	const u8	*hash_init;
 	u8		hw_op_hashsz;
 	u8		digest_size;
+	u8		statesize;
 	u8		block_size;
 	u8		auth_type;
 	u8		hmac_type;
@@ -1260,6 +1261,7 @@ static const struct n2_hash_tmpl hash_tm
 	  .hmac_type	= AUTH_TYPE_HMAC_MD5,
 	  .hw_op_hashsz	= MD5_DIGEST_SIZE,
 	  .digest_size	= MD5_DIGEST_SIZE,
+	  .statesize	= sizeof(struct md5_state),
 	  .block_size	= MD5_HMAC_BLOCK_SIZE },
 	{ .name		= "sha1",
 	  .hash_zero	= sha1_zero_message_hash,
@@ -1268,6 +1270,7 @@ static const struct n2_hash_tmpl hash_tm
 	  .hmac_type	= AUTH_TYPE_HMAC_SHA1,
 	  .hw_op_hashsz	= SHA1_DIGEST_SIZE,
 	  .digest_size	= SHA1_DIGEST_SIZE,
+	  .statesize	= sizeof(struct sha1_state),
 	  .block_size	= SHA1_BLOCK_SIZE },
 	{ .name		= "sha256",
 	  .hash_zero	= sha256_zero_message_hash,
@@ -1276,6 +1279,7 @@ static const struct n2_hash_tmpl hash_tm
 	  .hmac_type	= AUTH_TYPE_HMAC_SHA256,
 	  .hw_op_hashsz	= SHA256_DIGEST_SIZE,
 	  .digest_size	= SHA256_DIGEST_SIZE,
+	  .statesize	= sizeof(struct sha256_state),
 	  .block_size	= SHA256_BLOCK_SIZE },
 	{ .name		= "sha224",
 	  .hash_zero	= sha224_zero_message_hash,
@@ -1284,6 +1288,7 @@ static const struct n2_hash_tmpl hash_tm
 	  .hmac_type	= AUTH_TYPE_RESERVED,
 	  .hw_op_hashsz	= SHA256_DIGEST_SIZE,
 	  .digest_size	= SHA224_DIGEST_SIZE,
+	  .statesize	= sizeof(struct sha256_state),
 	  .block_size	= SHA224_BLOCK_SIZE },
 };
 #define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls)
@@ -1424,6 +1429,7 @@ static int __n2_register_one_ahash(const
 
 	halg = &ahash->halg;
 	halg->digestsize = tmpl->digest_size;
+	halg->statesize = tmpl->statesize;
 
 	base = &halg->base;
 	snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name);
author maintainer
#131 lore raw

PATCH 128/290 crypto: ccp - Add support for TEE for PCI ID 0x14CA

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

commit 10da230a4df1dfe32a58eb09246f5ffe82346f27 upstream.

SoCs containing 0x14CA are present both in datacenter parts that support SEV as well as client parts that support TEE.

---
 drivers/crypto/ccp/sp-pci.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/crypto/ccp/sp-pci.c +10 -1
@@ -320,6 +320,15 @@ static const struct psp_vdata pspv3 = {
 	.inten_reg		= 0x10690,
 	.intsts_reg		= 0x10694,
 };
+
+static const struct psp_vdata pspv4 = {
+	.sev			= &sevv2,
+	.tee			= &teev1,
+	.feature_reg		= 0x109fc,
+	.inten_reg		= 0x10690,
+	.intsts_reg		= 0x10694,
+};
+
 #endif
 
 static const struct sp_dev_vdata dev_vdata[] = {
@@ -365,7 +374,7 @@ static const struct sp_dev_vdata dev_vda
 	{	/* 5 */
 		.bar = 2,
 #ifdef CONFIG_CRYPTO_DEV_SP_PSP
-		.psp_vdata = &pspv2,
+		.psp_vdata = &pspv4,
 #endif
 	},
 };
author maintainer
#132 lore raw

PATCH 129/290 driver core: Fix bus_type.match() error handling in __driver_attach()

In reply to Greg Kroah-Hartman

From: Isaac J. Manjarres <[email protected]>

commit 27c0d217340e47ec995557f61423ef415afba987 upstream.

When a driver registers with a bus, it will attempt to match with every device on the bus through the __driver_attach() function. Currently, if the bus_type.match() function encounters an error that is not -EPROBE_DEFER, __driver_attach() will return a negative error code, which causes the driver registration logic to stop trying to match with the remaining devices on the bus.

This behavior is not correct; a failure while matching a driver to a device does not mean that the driver won't be able to match and bind with other devices on the bus. Update the logic in __driver_attach() to reflect this.

Fixes 656b8035b0ee ("ARM: 8524/1: driver cohandle -EPROBE_DEFER from bus_type.match()")
Cc Saravana Kannan <[email protected]>
---
 drivers/base/dd.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/base/dd.c +5 -1
@@ -1127,7 +1127,11 @@ static int __driver_attach(struct device
 		return 0;
 	} else if (ret < 0) {
 		dev_dbg(dev, "Bus failed to match device: %d\n", ret);
-		return ret;
+		/*
+		 * Driver could not match with device, but may match with
+		 * another device on the bus.
+		 */
+		return 0;
 	} /* ret > 0 means positive match */
 
 	if (driver_allows_async_probing(drv)) {
author maintainer
#133 lore raw

PATCH 130/290 phy: qcom-qmp-combo: fix sc8180x reset

In reply to Greg Kroah-Hartman

From: Johan Hovold <[email protected]>

commit 910dd4883d757af5faac92590f33f0f7da963032 upstream.

The SC8180X has two resets but the DP configuration erroneously described only one.

In case the DP part of the PHY is initialised before the USB part (e.g. depending on probe order), then only the first reset would be asserted.

---
 drivers/phy/qualcomm/phy-qcom-qmp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/phy/qualcomm/phy-qcom-qmp.c +2 -2
@@ -3417,8 +3417,8 @@ static const struct qmp_phy_cfg sc7180_d
 
 	.clk_list		= qmp_v3_phy_clk_l,
 	.num_clks		= ARRAY_SIZE(qmp_v3_phy_clk_l),
-	.reset_list		= sc7180_usb3phy_reset_l,
-	.num_resets		= ARRAY_SIZE(sc7180_usb3phy_reset_l),
+	.reset_list		= msm8996_usb3phy_reset_l,
+	.num_resets		= ARRAY_SIZE(msm8996_usb3phy_reset_l),
 	.vreg_list		= qmp_phy_vreg_l,
 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
 	.regs			= qmp_v3_usb3phy_regs_layout,
author maintainer
#134 lore raw

PATCH 131/290 iommu/amd: Fix ivrs_acpihid cmdline parsing code

In reply to Greg Kroah-Hartman

From: Kim Phillips <[email protected]>

commit 5f18e9f8868c6d4eae71678e7ebd4977b7d8c8cf upstream.

The second (UID) strcmp in acpi_dev_hid_uid_match considers "0" and "00" different, which can prevent device registration.

Have the AMD IOMMU driver's ivrs_acpihid parsing code remove any leading zeroes to make the UID strcmp succeed. Now users can safely specify "AMDxxxxx:00" or "AMDxxxxx:0" and expect the same behaviour.

Fixes ca3bf5d47cec ("iommu/amd: Introduces ivrs_acpihid kernel parameter")
Cc Suravee Suthikulpanit <[email protected]>
Cc Joerg Roedel <[email protected]>
---
 drivers/iommu/amd/init.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/iommu/amd/init.c +7 -0
@@ -3226,6 +3226,13 @@ static int __init parse_ivrs_acpihid(cha
 		return 1;
 	}
 
+	/*
+	 * Ignore leading zeroes after ':', so e.g., AMDI0095:00
+	 * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match
+	 */
+	while (*uid == '0' && *(uid + 1))
+		uid++;
+
 	i = early_acpihid_map_size++;
 	memcpy(early_acpihid_map[i].hid, hid, strlen(hid));
 	memcpy(early_acpihid_map[i].uid, uid, strlen(uid));
author maintainer
#135 lore raw

PATCH 132/290 remoteproc: core: Do pm_relax when in RPROC_OFFLINE state

In reply to Greg Kroah-Hartman

From: Maria Yu <[email protected]>

commit 11c7f9e3131ad14b27a957496088fa488b153a48 upstream.

Make sure that pm_relax() happens even when the remoteproc is stopped before the crash handler work is scheduled.

Cc stable <[email protected]>
Fixes a781e5aa5911 ("remoteproc: core: Prevent system suspend during remoteproc recovery")
---
 drivers/remoteproc/remoteproc_core.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/remoteproc/remoteproc_core.c +8 -1
@@ -1955,12 +1955,18 @@ static void rproc_crash_handler_work(str
 
 	mutex_lock(&rproc->lock);
 
-	if (rproc->state == RPROC_CRASHED || rproc->state == RPROC_OFFLINE) {
+	if (rproc->state == RPROC_CRASHED) {
 		/* handle only the first crash detected */
 		mutex_unlock(&rproc->lock);
 		return;
 	}
 
+	if (rproc->state == RPROC_OFFLINE) {
+		/* Don't recover if the remote processor was stopped */
+		mutex_unlock(&rproc->lock);
+		goto out;
+	}
+
 	rproc->state = RPROC_CRASHED;
 	dev_err(dev, "handling crash #%u in %s\n", ++rproc->crash_cnt,
 		rproc->name);
@@ -1970,6 +1976,7 @@ static void rproc_crash_handler_work(str
 	if (!rproc->recovery_disabled)
 		rproc_trigger_recovery(rproc);
 
+out:
 	pm_relax(rproc->dev.parent);
 }
 
author maintainer
#136 lore raw

PATCH 133/290 parisc: led: Fix potential null-ptr-deref in start_task()

In reply to Greg Kroah-Hartman

From: Shang XiaoJing <[email protected]>

commit 41f563ab3c33698bdfc3403c7c2e6c94e73681e4 upstream.

start_task() calls create_singlethread_workqueue() and not checked the ret value, which may return NULL. And a null-ptr-deref may happen:

start_task()
create_singlethread_workqueue() # failed, led_wq is NULL queue_delayed_work()
queue_delayed_work_on()
__queue_delayed_work() # warning here, but continue
__queue_work() # access wq->flags, null-ptr-deref

Check the ret value and return -ENOMEM if it is NULL.

Fixes 3499495205a6 ("[PARISC] Use work queue in LED/LCD driver instead of tasklet.")
---
 drivers/parisc/led.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/parisc/led.c +3 -0
@@ -137,6 +137,9 @@ static int start_task(void)
 
 	/* Create the work queue and queue the LED task */
 	led_wq = create_singlethread_workqueue("led_wq");	
+	if (!led_wq)
+		return -ENOMEM;
+
 	queue_delayed_work(led_wq, &led_task, 0);
 
 	return 0;
author maintainer
#137 lore raw

PATCH 134/290 device_cgroup: Roll back to original exceptions after copy failure

In reply to Greg Kroah-Hartman

From: Wang Weiyang <[email protected]>

commit e68bfbd3b3c3a0ec3cf8c230996ad8cabe90322f upstream.

When add the 'a *:* rwm' entry to devcgroup A's whitelist, at first A's exceptions will be cleaned and A's behavior is changed to DEVCG_DEFAULT_ALLOW. Then parent's exceptions will be copyed to A's whitelist. If copy failure occurs, just return leaving A to grant permissions to all devices. And A may grant more permissions than parent.

Backup A's whitelist and recover original exceptions after copy failure.

Fixes 4cef7299b478 ("device_cgroup: add proper checking when changing default behavior")
---
 security/device_cgroup.c |   33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)
security/device_cgroup.c +29 -4
@@ -81,6 +81,17 @@ free_and_exit:
 	return -ENOMEM;
 }
 
+static void dev_exceptions_move(struct list_head *dest, struct list_head *orig)
+{
+	struct dev_exception_item *ex, *tmp;
+
+	lockdep_assert_held(&devcgroup_mutex);
+
+	list_for_each_entry_safe(ex, tmp, orig, list) {
+		list_move_tail(&ex->list, dest);
+	}
+}
+
 /*
  * called under devcgroup_mutex
  */
@@ -603,11 +614,13 @@ static int devcgroup_update_access(struc
 	int count, rc = 0;
 	struct dev_exception_item ex;
 	struct dev_cgroup *parent = css_to_devcgroup(devcgroup->css.parent);
+	struct dev_cgroup tmp_devcgrp;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	memset(&ex, 0, sizeof(ex));
+	memset(&tmp_devcgrp, 0, sizeof(tmp_devcgrp));
 	b = buffer;
 
 	switch (*b) {
@@ -619,15 +632,27 @@ static int devcgroup_update_access(struc
 
 			if (!may_allow_all(parent))
 				return -EPERM;
-			dev_exception_clean(devcgroup);
-			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
-			if (!parent)
+			if (!parent) {
+				devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+				dev_exception_clean(devcgroup);
 				break;
+			}
 
+			INIT_LIST_HEAD(&tmp_devcgrp.exceptions);
+			rc = dev_exceptions_copy(&tmp_devcgrp.exceptions,
+						 &devcgroup->exceptions);
+			if (rc)
+				return rc;
+			dev_exception_clean(devcgroup);
 			rc = dev_exceptions_copy(&devcgroup->exceptions,
 						 &parent->exceptions);
-			if (rc)
+			if (rc) {
+				dev_exceptions_move(&devcgroup->exceptions,
+						    &tmp_devcgrp.exceptions);
 				return rc;
+			}
+			devcgroup->behavior = DEVCG_DEFAULT_ALLOW;
+			dev_exception_clean(&tmp_devcgrp);
 			break;
 		case DEVCG_DENY:
 			if (css_has_online_children(&devcgroup->css))
author maintainer
#138 lore raw

PATCH 135/290 drm/connector: send hotplug uevent on connector cleanup

In reply to Greg Kroah-Hartman

From: Simon Ser <[email protected]>

commit 6fdc2d490ea1369d17afd7e6eb66fecc5b7209bc upstream.

A typical DP-MST unplug removes a KMS connector. However care must be taken to properly synchronize with user-space. The expected sequence of events is the following:

1. The kernel notices that the DP-MST port is gone.
2. The kernel marks the connector as disconnected, then sends a uevent to make user-space re-scan the connector list.
3. User-space notices the connector goes from connected to disconnected, disables it.
4. Kernel handles the IOCTL disabling the connector. On success, the very last reference to the struct drm_connector is dropped and drm_connector_cleanup() is called.
5. The connector is removed from the list, and a uevent is sent to tell user-space that the connector disappeared.

The very last step was missing. As a result, user-space thought the connector still existed and could try to disable it again. Since the kernel no longer knows about the connector, that would end up with EINVAL and confused user-space.

Fix this by sending a hotplug uevent from drm_connector_cleanup().

---
 drivers/gpu/drm/drm_connector.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/drm_connector.c +3 -0
@@ -487,6 +487,9 @@ void drm_connector_cleanup(struct drm_co
 	mutex_destroy(&connector->mutex);
 
 	memset(connector, 0, sizeof(*connector));
+
+	if (dev->registered)
+		drm_sysfs_hotplug_event(dev);
 }
 EXPORT_SYMBOL(drm_connector_cleanup);
 
author maintainer
#139 lore raw

PATCH 136/290 drm/vmwgfx: Validate the box size for the snooped cursor

In reply to Greg Kroah-Hartman

From: Zack Rusin <[email protected]>

commit 4cf949c7fafe21e085a4ee386bb2dade9067316e upstream.

Invalid userspace dma surface copies could potentially overflow the memcpy from the surface to the snooped image leading to crashes. To fix it the dimensions of the copybox have to be validated against the expected size of the snooped cursor.

---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +2 -1
@@ -186,7 +186,8 @@ void vmw_kms_cursor_snoop(struct vmw_sur
 	if (cmd->dma.guest.ptr.offset % PAGE_SIZE ||
 	    box->x != 0    || box->y != 0    || box->z != 0    ||
 	    box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
-	    box->d != 1    || box_count != 1) {
+	    box->d != 1    || box_count != 1 ||
+	    box->w > 64 || box->h > 64) {
 		/* TODO handle none page aligned offsets */
 		/* TODO handle more dst & src != 0 */
 		/* TODO handle more then one copy */
author maintainer
#140 lore raw

PATCH 137/290 drm/i915/dsi: fix VBT send packet port selection for dual link DSI

In reply to Greg Kroah-Hartman

From: Mikko Kovanen <[email protected]>

commit f9cdf4130671d767071607d0a7568c9bd36a68d0 upstream.

intel_dsi->ports contains bitmask of enabled ports and correspondingly logic for selecting port for VBT packet sending must use port specific bitmask when deciding appropriate port.

Fixes 08c59dde71b7 ("drm/i915/dsi: fix VBT send packet port selection for ICL+")
(cherry picked from commit 8d58bb7991c45f6b60710cc04c9498c6ea96db90)
---
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/intel_dsi_vbt.c +2 -2
@@ -133,9 +133,9 @@ static enum port intel_dsi_seq_port_to_p
 		return ffs(intel_dsi->ports) - 1;
 
 	if (seq_port) {
-		if (intel_dsi->ports & PORT_B)
+		if (intel_dsi->ports & BIT(PORT_B))
 			return PORT_B;
-		else if (intel_dsi->ports & PORT_C)
+		else if (intel_dsi->ports & BIT(PORT_C))
 			return PORT_C;
 	}
 
author maintainer
#141 lore raw

PATCH 138/290 drm/ingenic: Fix missing platform_driver_unregister() call in ingenic_drm_init()

In reply to Greg Kroah-Hartman

From: Yuan Can <[email protected]>

commit 47078311b8efebdefd5b3b2f87e2b02b14f49c66 upstream.

A problem about modprobe ingenic-drm failed is triggered with the following log given:

 [  303.561088] Error: Driver 'ingenic-ipu' is already registered, aborting...
 modprobe: ERROR: could not insert 'ingenic_drm': Device or resource busy

The reason is that ingenic_drm_init() returns platform_driver_register() directly without checking its return value, if platform_driver_register() failed, it returns without unregistering ingenic_ipu_driver_ptr, resulting the ingenic-drm can never be installed later.
A simple call graph is shown as below:

ingenic_drm_init()
platform_driver_register() # ingenic_ipu_driver_ptr are registered platform_driver_register()
driver_register()
bus_add_driver()
priv = kzalloc(...) # OOM happened

   # return without unregister ingenic_ipu_driver_ptr

Fixing this problem by checking the return value of platform_driver_register() and do platform_unregister_drivers() if error happened.

---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/gpu/drm/ingenic/ingenic-drm-drv.c +5 -1
@@ -1326,7 +1326,11 @@ static int ingenic_drm_init(void)
 			return err;
 	}
 
-	return platform_driver_register(&ingenic_drm_driver);
+	err = platform_driver_register(&ingenic_drm_driver);
+	if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && err)
+		platform_driver_unregister(ingenic_ipu_driver_ptr);
+
+	return err;
 }
 module_init(ingenic_drm_init);
 
author maintainer
#142 lore raw

PATCH 139/290 ext4: silence the warning when evicting inode with dioread_nolock

In reply to Greg Kroah-Hartman

From: Zhang Yi <[email protected]>

commit bc12ac98ea2e1b70adc6478c8b473a0003b659d3 upstream.

When evicting an inode with default dioread_nolock, it could be raced by the unwritten extents converting kworker after writeback some new allocated dirty blocks. It convert unwritten extents to written, the extents could be merged to upper level and free extent blocks, so it could mark the inode dirty again even this inode has been marked I_FREEING. But the inode->i_io_list check and warning in ext4_evict_inode() missing this corner case. Fortunately, ext4_evict_inode() will wait all extents converting finished before this check, so it will not lead to inode use-after-free problem, every thing is OK besides this warning. The WARN_ON_ONCE was originally designed for finding inode use-after-free issues in advance, but if we add current dioread_nolock case in, it will become not quite useful, so fix this warning by just remove this check.

======

 WARNING: CPU: 7 PID: 1092 at fs/ext4/inode.c:227
 ext4_evict_inode+0x875/0xc60
 ...
 RIP: 0010:ext4_evict_inode+0x875/0xc60
 ...
 Call Trace:
  <TASK>
  evict+0x11c/0x2b0
  iput+0x236/0x3a0
  do_unlinkat+0x1b4/0x490
  __x64_sys_unlinkat+0x4c/0xb0
  do_syscall_64+0x3b/0x90
  entry_SYSCALL_64_after_hwframe+0x46/0xb0
 RIP: 0033:0x7fa933c1115b
 ======

rm kworker

                            ext4_end_io_end()
vfs_unlink()
 ext4_unlink()
                             ext4_convert_unwritten_io_end_vec()
                              ext4_convert_unwritten_extents()
                               ext4_map_blocks()
                                ext4_ext_map_blocks()
                                 ext4_ext_try_to_merge_up()
                                  __mark_inode_dirty()
                                   check !I_FREEING
                                   locked_inode_to_wb_and_lock_list()
 iput()
  iput_final()
   evict()
    ext4_evict_inode()
     truncate_inode_pages_final() //wait release io_end
                                    inode_io_list_move_locked()
                             ext4_release_io_end()
     trigger WARN_ON_ONCE()
---
 fs/ext4/inode.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
fs/ext4/inode.c +5 -5
@@ -225,13 +225,13 @@ void ext4_evict_inode(struct inode *inod
 
 	/*
 	 * For inodes with journalled data, transaction commit could have
-	 * dirtied the inode. Flush worker is ignoring it because of I_FREEING
-	 * flag but we still need to remove the inode from the writeback lists.
+	 * dirtied the inode. And for inodes with dioread_nolock, unwritten
+	 * extents converting worker could merge extents and also have dirtied
+	 * the inode. Flush worker is ignoring it because of I_FREEING flag but
+	 * we still need to remove the inode from the writeback lists.
 	 */
-	if (!list_empty_careful(&inode->i_io_list)) {
-		WARN_ON_ONCE(!ext4_should_journal_data(inode));
+	if (!list_empty_careful(&inode->i_io_list))
 		inode_io_list_del(inode);
-	}
 
 	/*
 	 * Protect us against freezing - iput() caller didn't have to have any