5.15.87-rc1 review
Subsystems (4)
Greg Kroah-Hartman
maintainercover 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(-)
Greg Kroah-Hartman
maintainerPATCH 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.
--- drivers/usb/dwc3/dwc3-qcom.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/usb/dwc3/dwc3-qcom.c +10 -3
@@ -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
Greg Kroah-Hartman
maintainerPATCH 2/290 cifs: fix oops during encryption
In reply to Greg Kroah-HartmanFrom: 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/0x7c0This 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
@@ -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
@@ -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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 3/290 Revert "selftests/bpf: Add test for unstable CT lookup API"
In reply to Greg Kroah-HartmanThis 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 4/290 nvme-pci: fix doorbell buffer value endianness
In reply to Greg Kroah-HartmanFrom: 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]/
--- drivers/nvme/host/pci.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/nvme/host/pci.c +13 -12
@@ -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
Greg Kroah-Hartman
maintainerPATCH 5/290 nvme-pci: fix mempool alloc size
In reply to Greg Kroah-HartmanFrom: 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.
--- drivers/nvme/host/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/host/pci.c +2 -2
@@ -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
Greg Kroah-Hartman
maintainerPATCH 6/290 nvme-pci: fix page size checks
In reply to Greg Kroah-HartmanFrom: 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.
--- drivers/nvme/host/pci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/nvme/host/pci.c +4 -4
@@ -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
Greg Kroah-Hartman
maintainerPATCH 7/290 ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 8/290 ACPI: resource: do IRQ override on LENOVO IdeaPad
In reply to Greg Kroah-HartmanFrom: 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.
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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 9/290 ACPI: resource: do IRQ override on XMG Core 15
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 10/290 ACPI: resource: do IRQ override on Lenovo 14ALC7
In reply to Greg Kroah-HartmanFrom: 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.
--- drivers/acpi/resource.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/acpi/resource.c +10 -3
@@ -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
Greg Kroah-Hartman
maintainerPATCH 11/290 block, bfq: fix uaf for bfqq in bfq_exit_icq_bfqq
In reply to Greg Kroah-HartmanFrom: 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().
--- block/bfq-iosched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
block/bfq-iosched.c +1 -1
@@ -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
Greg Kroah-Hartman
maintainerPATCH 12/290 ata: ahci: Fix PCS quirk application for suspend
In reply to Greg Kroah-HartmanFrom: 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.
--- drivers/ata/ahci.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-)
drivers/ata/ahci.c +23 -9
@@ -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
Greg Kroah-Hartman
maintainerPATCH 13/290 nvme: fix the NVME_CMD_EFFECTS_CSE_MASK definition
In reply to Greg Kroah-HartmanFrom: 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.
--- include/linux/nvme.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/nvme.h +2 -1
@@ -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
Greg Kroah-Hartman
maintainerPATCH 14/290 nvmet: dont defer passthrough commands with trivial effects to the workqueue
In reply to Greg Kroah-HartmanFrom: 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.
--- drivers/nvme/target/passthru.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/nvme/target/passthru.c +5 -6
@@ -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
Greg Kroah-Hartman
maintainerPATCH 15/290 fs/ntfs3: Validate BOOT record_size
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 16/290 fs/ntfs3: Add overflow check for attribute size
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 17/290 fs/ntfs3: Validate data run offset
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 18/290 fs/ntfs3: Add null pointer check to attr_load_runs_vcn
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 19/290 fs/ntfs3: Fix memory leak on ntfs_fill_super() error path
In reply to Greg Kroah-HartmanFrom: 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/0xcdThis 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 20/290 fs/ntfs3: Add null pointer check for inode operations
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 21/290 fs/ntfs3: Validate attribute name offset
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 22/290 fs/ntfs3: Validate buffer length while parsing index
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 23/290 fs/ntfs3: Validate resident attribute name
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 24/290 fs/ntfs3: Fix slab-out-of-bounds read in run_unpack
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 25/290 soundwire: dmi-quirks: add quirk variant for LAPBC710 NUC15
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 26/290 fs/ntfs3: Validate index root when initialize NTFS security
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 27/290 fs/ntfs3: Use __GFP_NOWARN allocation at wnd_init()
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 28/290 fs/ntfs3: Use __GFP_NOWARN allocation at ntfs_fill_super()
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 29/290 fs/ntfs3: Delete duplicate condition in ntfs_read_mft()
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 30/290 fs/ntfs3: Fix slab-out-of-bounds in r_page
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 31/290 objtool: Fix SEGFAULT
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 32/290 powerpc/rtas: avoid device tree lookups in rtas_os_term()
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 33/290 powerpc/rtas: avoid scheduling in rtas_os_term()
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 34/290 HID: multitouch: fix Asus ExpertBook P2 P2451FA trackpoint
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 35/290 HID: plantronics: Additional PIDs for double volume key presses quirk
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 36/290 pstore: Properly assign mem_type property
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 );
Greg Kroah-Hartman
maintainerPATCH 37/290 pstore/zone: Use GFP_ATOMIC to allocate zone buffer
In reply to Greg Kroah-HartmanFrom: 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 ;
Greg Kroah-Hartman
maintainerPATCH 38/290 hfsplus: fix bug causing custom uid and gid being unable to be assigned with mount
In reply to Greg Kroah-HartmanFrom: 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 7static 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, sif (!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, sif (!gid_valid (sbi->gid)) {pr_err ("invalid gid specified\n" );return 0 ; + }else { +set_bit (HFSPLUS_SB_GID , &sbi->flags); }break ;case opt_part:
Greg Kroah-Hartman
maintainerPATCH 39/290 binfmt: Fix error return code in load_elf_fdpic_binary()
In reply to Greg Kroah-HartmanFrom: 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);
Greg Kroah-Hartman
maintainerPATCH 40/290 ovl: Use ovl mounters fsuid and fsgid in ovl_link()
In reply to Greg Kroah-HartmanFrom: 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/lnkfileThen 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;
Greg Kroah-Hartman
maintainerPATCH 41/290 ALSA: line6: correct midi status byte when receiving data from podxt
In reply to Greg Kroah-HartmanFrom: 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 ufor (;;) { 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 sfor (;;) { 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(structextern 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,
Greg Kroah-Hartman
maintainerPATCH 42/290 ALSA: line6: fix stack overflow in line6_midi_transmit
In reply to Greg Kroah-HartmanFrom: 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 sint 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 )
Greg Kroah-Hartman
maintainerPATCH 43/290 pnode: terminate at peers of source
In reply to Greg Kroah-HartmanFrom: 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:218After 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:218will 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
---
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))
Greg Kroah-Hartman
maintainerPATCH 44/290 mfd: mt6360: Add bounds checking in Regmap read/write call-backs
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 *contstruct 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 *contu8 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 (®_addr, val_size);
@@ -453,13 +458,18 @@ static int mt6360_regmap_write(void *construct 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 (®_addr, val_size -MT6360_REGMAP_REG_BYTE_SIZE );
Greg Kroah-Hartman
maintainerPATCH 45/290 md: fix a crash in mempool_free
In reply to Greg Kroah-HartmanFrom: 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 *biostruct 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,
Greg Kroah-Hartman
maintainerPATCH 46/290 mm, compaction: fix fast_isolate_around() to stay within boundaries
In reply to Greg Kroah-HartmanFrom: 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".
--- 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_contrif (!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_coreturn 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; }
Greg Kroah-Hartman
maintainerPATCH 47/290 f2fs: should put a page when checking the summary info
In reply to Greg Kroah-HartmanFrom: Pavel Machek <[email protected]>
commit c3db3c2fd9992c08f49aa93752d3c103c3a4f6aa upstream.
The commit introduces another bug.
--- 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_infoif (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; }
Greg Kroah-Hartman
maintainerPATCH 48/290 f2fs: allow to read node block after shutdown
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 *preturn 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 ; }
Greg Kroah-Hartman
maintainerPATCH 49/290 mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING
In reply to Greg Kroah-HartmanFrom: 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(strucreturn ;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(strucvub300_queue_poll_work (vub300,0 ); }mutex_unlock (&vub300->irq_mutex); +set_current_state (TASK_INTERRUPTIBLE ); }else { vub300->irq_enabled =0 ; }
Greg Kroah-Hartman
maintainerPATCH 50/290 tpm: acpi: Call acpi_put_table() to fix memory leak
In reply to Greg Kroah-HartmanFrom: 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().
--- 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 *creturn -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 *cbreak ; } +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; - }
Greg Kroah-Hartman
maintainerPATCH 51/290 tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak
In reply to Greg Kroah-HartmanFrom: 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_deviFW_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)
Greg Kroah-Hartman
maintainerPATCH 52/290 tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 deviceconst 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)
Greg Kroah-Hartman
maintainerPATCH 53/290 SUNRPC: Dont leak netobj memory when gss_read_proxy_verf() fails
In reply to Greg Kroah-HartmanFrom: Chuck Lever <[email protected]>
commit da522b5fe1a5f8b7c20a0023e87b52a150e53bf5 upstream.
--- 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 svreturn 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 ; }
Greg Kroah-Hartman
maintainerPATCH 54/290 kcsan: Instrument memcpy/memset/memmove with newer Clang
In reply to Greg Kroah-HartmanFrom: 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.
--- 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_fencevoid __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);
Greg Kroah-Hartman
maintainerPATCH 55/290 ASoC: Intel/SOF: use set_stream() instead of set_tdm_slots() for HDAudio
In reply to Greg Kroah-HartmanFrom: 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 sndif (!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);
Greg Kroah-Hartman
maintainerPATCH 56/290 ASoC/SoundWire: dai: expand stream concept beyond SoundWire
In reply to Greg Kroah-HartmanFrom: 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(strstatic 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_drstatic 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_drstatic 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 sndstatic 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(structstatic 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(structstatic 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(structstatic 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(strint 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 sswitch (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; }
Greg Kroah-Hartman
maintainerPATCH 57/290 rcu-tasks: Simplify trc_read_check_handler() atomic operations
In reply to Greg Kroah-HartmanFrom: 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(struif (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); - } } } }
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
96017bf9039763a2e02dcc6adaa18592cd73a39dupstream.
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 thetrc_n_readers_need_endcounter before sending the IPI invokingtrc_read_check_handler(). All failure paths out oftrc_read_check_handler()and also from thesmp_call_function_single()withintrc_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.Signed-off-by Paul E. McKenney <[email protected]>Cc Joel Fernandes <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- 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(struif (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); - } } } }
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
96017bf9039763a2e02dcc6adaa18592cd73a39dupstream.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...
Greg Kroah-Hartman
maintainerRe: [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
96017bf9039763a2e02dcc6adaa18592cd73a39dupstream.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 :)
Greg Kroah-Hartman
maintainerPATCH 58/290 net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO
In reply to Greg Kroah-HartmanFrom: 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 *socvirtio_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 )
Greg Kroah-Hartman
maintainerPATCH 59/290 net/af_packet: make sure to pull mac header
In reply to Greg Kroah-HartmanFrom: 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>
--- 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 ) &ð_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); }
Greg Kroah-Hartman
maintainerPATCH 60/290 media: stv0288: use explicitly signed char
In reply to Greg Kroah-HartmanFrom: 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 dstruct 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__);
Greg Kroah-Hartman
maintainerPATCH 61/290 soc: qcom: Select REMAP_MMIO for LLCC driver
In reply to Greg Kroah-HartmanFrom: 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,
Greg Kroah-Hartman
maintainerPATCH 62/290 kest.pl: Fix grub2 menu handling for rebooting
In reply to Greg Kroah-HartmanFrom: 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) {
Greg Kroah-Hartman
maintainerPATCH 63/290 ktest.pl minconfig: Unset configs instead of just removing them
In reply to Greg Kroah-HartmanFrom: 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.
--- 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;
Greg Kroah-Hartman
maintainerPATCH 64/290 jbd2: use the correct print format
In reply to Greg Kroah-HartmanFrom: 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 0Use the correct print format for transaction, head and tid.
--- 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),
Greg Kroah-Hartman
maintainerPATCH 65/290 perf/x86/intel/uncore: Disable I/O stacks to PMU mapping on ICX-D
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 istatic 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); }
Greg Kroah-Hartman
maintainerPATCH 66/290 perf/x86/intel/uncore: Clear attr_update properly
In reply to Greg Kroah-HartmanFrom: 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.
--- 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; }
Greg Kroah-Hartman
maintainerPATCH 67/290 arm64: dts: qcom: sdm845-db845c: correct SPI2 pins drive strength
In reply to Greg Kroah-HartmanFrom: 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{
Greg Kroah-Hartman
maintainerPATCH 68/290 mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 ); + } } }
Greg Kroah-Hartman
maintainerPATCH 69/290 btrfs: fix resolving backrefs for inline extent followed by prealloc
In reply to Greg Kroah-HartmanFrom: 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);
Greg Kroah-Hartman
maintainerPATCH 70/290 ARM: ux500: do not directly dereference __iomem
In reply to Greg Kroah-HartmanFrom: 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; }
Greg Kroah-Hartman
maintainerPATCH 71/290 arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength
In reply to Greg Kroah-HartmanFrom: 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 {
Greg Kroah-Hartman
maintainerPATCH 72/290 selftests: Use optional USERCFLAGS and USERLDFLAGS
In reply to Greg Kroah-HartmanFrom: 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. #
Greg Kroah-Hartman
maintainerPATCH 73/290 PM/devfreq: governor: Add a private governor_data for governor
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 devint 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 deviint 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 devfreif (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;
Greg Kroah-Hartman
maintainerPATCH 74/290 cpufreq: Init completion before kobject_init_and_add()
In reply to Greg Kroah-HartmanFrom: 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
--- 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_poif (!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_poinit_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;
Greg Kroah-Hartman
maintainerPATCH 75/290 ALSA: patch_realtek: Fix Dell Inspiron Plus 16
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 76/290 ALSA: hda/realtek: Apply dual codec fixup for Dell Latitude laptops
In reply to Greg Kroah-HartmanFrom: 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
@@ -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
Greg Kroah-Hartman
maintainerPATCH 77/290 fs: dlm: fix sock release if listen fails
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 ();
Greg Kroah-Hartman
maintainerPATCH 78/290 fs: dlm: retry accept() until -EAGAIN or error returns
In reply to Greg Kroah-HartmanFrom: 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").
--- 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(structstatic 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)
Greg Kroah-Hartman
maintainerPATCH 79/290 mptcp: mark ops structures as ro_after_init
In reply to Greg Kroah-HartmanFrom: 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 smptcp_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);
Greg Kroah-Hartman
maintainerPATCH 80/290 mptcp: remove MPTCP ifdef in TCP SYN cookies
In reply to Greg Kroah-HartmanFrom: 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 *seqint 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_alstruct 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)
Greg Kroah-Hartman
maintainerPATCH 81/290 dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort
In reply to Greg Kroah-HartmanFrom: 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.
--- 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_objereturn 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_cmutex_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(structint 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; }
Greg Kroah-Hartman
maintainerPATCH 82/290 dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata
In reply to Greg Kroah-HartmanFrom: 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].
--- 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_objereturn 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_flaint 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; }
Greg Kroah-Hartman
maintainerPATCH 83/290 dm thin: Use last transactions pmd->root when commit failed
In reply to Greg Kroah-HartmanFrom: 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
--- 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);
Greg Kroah-Hartman
maintainerPATCH 84/290 dm thin: resume even if in FAIL mode
In reply to Greg Kroah-HartmanFrom: 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().
--- 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)
Greg Kroah-Hartman
maintainerPATCH 85/290 dm thin: Fix UAF in run_timer_softirq()
In reply to Greg Kroah-HartmanFrom: 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().
--- 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);
Greg Kroah-Hartman
maintainerPATCH 86/290 dm integrity: Fix UAF in dm_integrity_dtr()
In reply to Greg Kroah-HartmanFrom: 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().
--- 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_tBUG_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)
Greg Kroah-Hartman
maintainerPATCH 87/290 dm clone: Fix UAF in clone_dtr()
In reply to Greg Kroah-HartmanFrom: 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().
--- 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);
Greg Kroah-Hartman
maintainerPATCH 88/290 dm cache: Fix UAF in destroy()
In reply to Greg Kroah-HartmanFrom: 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().
--- 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);
Greg Kroah-Hartman
maintainerPATCH 89/290 dm cache: set needs_check flag after aborting metadata
In reply to Greg Kroah-HartmanFrom: 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).
--- 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 cacif (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)
Greg Kroah-Hartman
maintainerPATCH 90/290 tracing/hist: Fix out-of-bound write on action_data.var_ref_idx
In reply to Greg Kroah-HartmanFrom: 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
--- 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_refreturn 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 hilockdep_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
Greg Kroah-Hartman
maintainerPATCH 91/290 perf/core: Call LSM hook after copying perf_event_attr
In reply to Greg Kroah-HartmanFrom: 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;
Greg Kroah-Hartman
maintainerPATCH 92/290 of/kexec: Fix reading 32-bit "linux,initrd-{start,end}" values
In reply to Greg Kroah-HartmanFrom: 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
Greg Kroah-Hartman
maintainerPATCH 93/290 KVM: VMX: Resume guest immediately when injecting #GP on ECREATE
In reply to Greg Kroah-HartmanFrom: 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.
--- 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:
Greg Kroah-Hartman
maintainerPATCH 94/290 KVM: nVMX: Inject #GP, not #UD, if "generic" VMXON CR0/CR4 check fails
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 );
Greg Kroah-Hartman
maintainerPATCH 95/290 KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1
In reply to Greg Kroah-HartmanFrom: 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.
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 nSECONDARY_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
Greg Kroah-Hartman
maintainerPATCH 96/290 x86/microcode/intel: Do not retry microcode reloading on the APs
In reply to Greg Kroah-HartmanFrom: 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)
Greg Kroah-Hartman
maintainerPATCH 97/290 ftrace/x86: Add back ftrace_expected for ftrace bug reports
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 ; } }
Greg Kroah-Hartman
maintainerPATCH 98/290 x86/kprobes: Fix kprobes instruction boudary check with CONFIG_RETHUNK
In reply to Greg Kroah-HartmanFrom: 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 paddrif (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; }
Greg Kroah-Hartman
maintainerPATCH 99/290 x86/kprobes: Fix optprobe optimization check with CONFIG_RETHUNK
In reply to Greg Kroah-HartmanFrom: 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(structreturn 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);
Greg Kroah-Hartman
maintainerPATCH 100/290 tracing: Fix race where eprobes can be called before the event
In reply to Greg Kroah-HartmanFrom: 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 eif (unlikely (!rec))return ; +if (unlikely (!rec)) +return ; +__eprobe_trace_func (edata, rec); }
Greg Kroah-Hartman
maintainerPATCH 101/290 tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE
In reply to Greg Kroah-HartmanFrom: 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, string_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);
Greg Kroah-Hartman
maintainerPATCH 102/290 tracing/hist: Fix wrong return value in parse_action_params()
In reply to Greg Kroah-HartmanFrom: Zheng Yejian <[email protected]>
commit 2cc6a528882d0e0ccbc1bca5f95b8c963cedac54 upstream.
When number of synth fields is more than SYNTH_FIELDS_MAX, parse_action_params() should return -EINVAL.
--- 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 trwhile (params) {if (data->n_params >=SYNTH_FIELDS_MAX ) {hist_err (tr,HIST_ERR_TOO_MANY_PARAMS ,0 ); + ret = -EINVAL ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 103/290 tracing/probes: Handle system names with hyphens
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 chreturn -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 ; }
Greg Kroah-Hartman
maintainerPATCH 104/290 tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 ; }
Greg Kroah-Hartman
maintainerPATCH 105/290 staging: media: tegra-video: fix chan->mipi value on error
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 {
Greg Kroah-Hartman
maintainerPATCH 106/290 staging: media: tegra-video: fix device_node use after free
In reply to Greg Kroah-HartmanFrom: 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.
--- 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(strucfor (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(smedia_entity_cleanup (&subdev->entity); } +of_node_put (chan->of_node);list_del (&chan->list);kfree (chan); }
Greg Kroah-Hartman
maintainerPATCH 107/290 ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod
In reply to Greg Kroah-HartmanFrom: 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
Greg Kroah-Hartman
maintainerPATCH 108/290 media: dvb-core: Fix double free in dvb_register_device()
In reply to Greg Kroah-HartmanFrom: 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 ; } }
Greg Kroah-Hartman
maintainerPATCH 109/290 media: dvb-core: Fix UAF due to refcount races at releasing
In reply to Greg Kroah-HartmanFrom: 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 );
Greg Kroah-Hartman
maintainerPATCH 110/290 cifs: fix confusing debug message
In reply to Greg Kroah-HartmanFrom: 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_contexstruct 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_Inforeturn ses; } + rc = -ENOMEM ; +cifs_dbg (FYI ,"Existing smb sess not found\n" ); ses =sesInfoAlloc ();if (ses ==NULL )
Greg Kroah-Hartman
maintainerPATCH 111/290 cifs: fix missing display of three mount options
In reply to Greg Kroah-HartmanFrom: 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, stseq_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);
Greg Kroah-Hartman
maintainerPATCH 112/290 rtc: ds1347: fix value written to century register
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 devicereturn 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;
Greg Kroah-Hartman
maintainerPATCH 113/290 block: mq-deadline: Do not break sequential write streams to zoned HDDs
In reply to Greg Kroah-HartmanFrom: 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=65536results 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);
Greg Kroah-Hartman
maintainerPATCH 114/290 md/bitmap: Fix bitmap chunk size overflow issues
In reply to Greg Kroah-HartmanFrom: 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 *bpr_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, conif (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; }
Greg Kroah-Hartman
maintainerPATCH 115/290 efi: Add iMac Pro 2017 to uefi skip cert quirk
In reply to Greg Kroah-HartmanFrom: 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.
--- 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") }, { } };
Greg Kroah-Hartman
maintainerPATCH 116/290 wifi: wilc1000: sdio: fix module autoloading
In reply to Greg Kroah-HartmanFrom: 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
Greg Kroah-Hartman
maintainerPATCH 117/290 ASoC: jz4740-i2s: Handle independent FIFO flush bits
In reply to Greg Kroah-HartmanFrom: 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(conswritel (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 = {
Greg Kroah-Hartman
maintainerPATCH 118/290 ipu3-imgu: Fix NULL pointer dereference in imgu_subdev_set_selection()
In reply to Greg Kroah-HartmanFrom: 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().
--- drivers/staging/media/ipu3/ipu3-v4l2.c | 57 +++++++++++++++----------- 1 file changed, 34 insertions(+), 23 deletions(-)
drivers/staging/media/ipu3/ipu3-v4l2.c +34 -23
@@ -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
Greg Kroah-Hartman
maintainerPATCH 119/290 ipmi: fix long wait in unload when IPMI disconnect
In reply to Greg Kroah-HartmanFrom: 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);
Greg Kroah-Hartman
maintainerPATCH 120/290 mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type()
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 struccontinue ; erase = &map->erase_type[i]; +if (!erase->size) +continue ;/* Alignment is not mandatory for overlaid regions */ if (region->offset & SNOR_OVERLAID_REGION &&
Greg Kroah-Hartman
maintainerPATCH 121/290 ima: Fix a potential NULL pointer access in ima_restore_measurement_list
In reply to Greg Kroah-HartmanFrom: 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.
--- 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);
Greg Kroah-Hartman
maintainerPATCH 122/290 ipmi: fix use after free in _ipmi_destroy_user()
In reply to Greg Kroah-HartmanFrom: 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.
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 ipunsigned 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 ipkfree (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)
Greg Kroah-Hartman
maintainerPATCH 123/290 PCI: Fix pci_device_is_present() for VFs by checking PF
In reply to Greg Kroah-HartmanFrom: 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 );
Greg Kroah-Hartman
maintainerPATCH 124/290 PCI/sysfs: Fix double free in error path
In reply to Greg Kroah-HartmanFrom: 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.
--- 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_desysfs_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 ; }/**
Greg Kroah-Hartman
maintainerPATCH 125/290 riscv: stacktrace: Fixup ftrace_graph_ret_addr retp argument
In reply to Greg Kroah-HartmanFrom: 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.
--- 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); } }
Greg Kroah-Hartman
maintainerPATCH 126/290 riscv: mm: notify remote harts about mmu cache updates
In reply to Greg Kroah-HartmanFrom: 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(structif (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),
Greg Kroah-Hartman
maintainerPATCH 127/290 crypto: n2 - add missing hash statesize
In reply to Greg Kroah-HartmanFrom: 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.
--- 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);
Greg Kroah-Hartman
maintainerPATCH 128/290 crypto: ccp - Add support for TEE for PCI ID 0x14CA
In reply to Greg Kroah-HartmanFrom: 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 }, };
Greg Kroah-Hartman
maintainerPATCH 129/290 driver core: Fix bus_type.match() error handling in __driver_attach()
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 devicereturn 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)) {
Greg Kroah-Hartman
maintainerPATCH 130/290 phy: qcom-qmp-combo: fix sc8180x reset
In reply to Greg Kroah-HartmanFrom: 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,
Greg Kroah-Hartman
maintainerPATCH 131/290 iommu/amd: Fix ivrs_acpihid cmdline parsing code
In reply to Greg Kroah-HartmanFrom: 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.
--- 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(chareturn 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));
Greg Kroah-Hartman
maintainerPATCH 132/290 remoteproc: core: Do pm_relax when in RPROC_OFFLINE state
In reply to Greg Kroah-HartmanFrom: 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.
--- 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(strmutex_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(strif (!rproc->recovery_disabled)rproc_trigger_recovery (rproc); +out:pm_relax (rproc->dev.parent); }
Greg Kroah-Hartman
maintainerPATCH 133/290 parisc: led: Fix potential null-ptr-deref in start_task()
In reply to Greg Kroah-HartmanFrom: 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.
--- 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 ;
Greg Kroah-Hartman
maintainerPATCH 134/290 device_cgroup: Roll back to original exceptions after copy failure
In reply to Greg Kroah-HartmanFrom: 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.
--- 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(strucint 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(strucif (!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))
Greg Kroah-Hartman
maintainerPATCH 135/290 drm/connector: send hotplug uevent on connector cleanup
In reply to Greg Kroah-HartmanFrom: 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_comutex_destroy (&connector->mutex);memset (connector,0 ,sizeof (*connector)); + +if (dev->registered) +drm_sysfs_hotplug_event (dev); }EXPORT_SYMBOL (drm_connector_cleanup);
Greg Kroah-Hartman
maintainerPATCH 136/290 drm/vmwgfx: Validate the box size for the snooped cursor
In reply to Greg Kroah-HartmanFrom: 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_surif (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 */
Greg Kroah-Hartman
maintainerPATCH 137/290 drm/i915/dsi: fix VBT send packet port selection for dual link DSI
In reply to Greg Kroah-HartmanFrom: 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.
--- 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_preturn 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 ; }
Greg Kroah-Hartman
maintainerPATCH 138/290 drm/ingenic: Fix missing platform_driver_unregister() call in ingenic_drm_init()
In reply to Greg Kroah-HartmanFrom: 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);
Greg Kroah-Hartman
maintainerPATCH 139/290 ext4: silence the warning when evicting inode with dioread_nolock
In reply to Greg Kroah-HartmanFrom: 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