5.4.244-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainercover 5.4.244-rc1 review
This is the start of the stable review cycle for the 5.4.244 release. There are 161 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 Tue, 30 May 2023 19:08:13 +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.4.244-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.4.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.4.244-rc1
Christophe JAILLET <[email protected]>
3c589_cs: Fix an error handling path in tc589_probe()
Shay Drory <[email protected]>
net/mlx5: Devcom, fix error flow in mlx5_devcom_register_device
Roi Dayan <[email protected]>
net/mlx5: Fix error message when failing to allocate device memory
Christophe JAILLET <[email protected]>
forcedeth: Fix an error handling path in nv_probe()
Cezary Rojewski <[email protected]>
ASoC: Intel: Skylake: Fix declaration of enum skl_ch_cfg
Vernon Lovejoy <[email protected]>
x86/show_trace_log_lvl: Ensure stack pointer is aligned, again
Dan Carpenter <[email protected]>
xen/pvcalls-back: fix double frees with pvcalls_new_active_socket()
Dan Carpenter <[email protected]>
coresight: Fix signedness bug in tmc_etr_buf_insert_barrier_packet()
Daisuke Nojiri <[email protected]>
power: supply: sbs-charger: Fix INHIBITED bit for Status reg
Hans de Goede <[email protected]>
power: supply: bq27xxx: Fix poll_interval handling and races on remove
Hans de Goede <[email protected]>
power: supply: bq27xxx: Fix I2C IRQ race on remove
Hans de Goede <[email protected]>
power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition
Hans de Goede <[email protected]>
power: supply: leds: Fix blink to LED on transition
Gavrilov Ilia <[email protected]>
ipv6: Fix out-of-bounds access in ipv6_find_tlv()
Will Deacon <[email protected]>
bpf: Fix mask generation for 32-bit narrow loads of 64-bit fields
Po-Hsu Lin <[email protected]>
selftests: fib_tests: mute cleanup error message
Pratyush Yadav <[email protected]>
net: fix skb leak in __skb_tstamp_tx()
Alan Stern <[email protected]>
media: radio-shark: Add endpoint checks
Alan Stern <[email protected]>
USB: sisusbvga: Add endpoint checks
Alan Stern <[email protected]>
USB: core: Add routines for endpoint checks in old drivers
Kuniyuki Iwashima <[email protected]>
udplite: Fix NULL pointer dereference in __sk_mem_raise_allocated().
Taehee Yoo <[email protected]>
net: fix stack overflow when LRO is disabled for virtual interfaces
Alan Stern <[email protected]>
fbdev: udlfb: Fix endpoint check
Tetsuo Handa <[email protected]>
debugobjects: Don't wake up kswapd from fill_pool()
Zhang Rui <[email protected]>
x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms
Helge Deller <[email protected]>
parisc: Fix flush_dcache_page() for usage from irq context
Hardik Garg <[email protected]>
selftests/memfd: Fix unknown type name build failure
Dave Hansen <[email protected]>
x86/mm: Avoid incomplete Global INVLPG flushes
Josef Bacik <[email protected]>
btrfs: use nofs when cleaning up aborted transactions
Zev Weiss <[email protected]>
gpio: mockup: Fix mode of debugfs files
Helge Deller <[email protected]>
parisc: Allow to reboot machine after system halt
Helge Deller <[email protected]>
parisc: Handle kgdb breakpoints only in kernel context
Finn Thain <[email protected]>
m68k: Move signal frame following exception on 68020/030
Bin Li <[email protected]>
ALSA: hda/realtek: Enable headset onLenovo M70/M90
Adam Stylinski <[email protected]>
ALSA: hda/ca0132: add quirk for EVGA X299 DARK
Pablo Greco <[email protected]>
mt76: mt7615: Fix build with older compilers
Christophe Leroy <[email protected]>
spi: fsl-cpm: Use 16 bit mode for large transfers with even size
Christophe Leroy <[email protected]>
spi: fsl-spi: Re-organise transfer bits_per_word adaptation
Gregory Oakes <[email protected]>
watchdog: sp5100_tco: Immediately trigger upon starting.
Heiko Carstens <[email protected]>
s390/qdio: fix do_sqbs() inline assembly constraint
Heiko Carstens <[email protected]>
s390/qdio: get rid of register asm
George Kennedy <[email protected]>
vc_screen: reload load of struct vc_data pointer in vcs_write() to avoid UAF
Jiri Slaby <[email protected]>
vc_screen: rewrite vcs_size to accept vc, not inode
Konrad Gräfe <[email protected]>
usb: gadget: u_ether: Fix host MAC address case
Jon Hunter <[email protected]>
usb: gadget: u_ether: Convert prints to device prints
Vadim Pasternak <[email protected]>
lib/string_helpers: Introduce string_upper() and string_lower() helpers
Ping Cheng <[email protected]>
HID: wacom: add three styli to wacom_intuos_get_tool_type
Ping Cheng <[email protected]>
HID: wacom: Add new Intuos Pro Small (PTH-460) device IDs
Jason Gerecke <[email protected]>
HID: wacom: Force pen out of prox if no events have been received in a while
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: hold mutex on netns pre_exit path
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT flag
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: stricter validation of element data
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: allow up to 64 bytes in the set element data area
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: add nft_setelem_parse_key()
Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: validate registers coming from userspace.
Pablo Neira Ayuso <[email protected]>
netfilter: nftables: statify nft_parse_register()
Pablo Neira Ayuso <[email protected]>
netfilter: nftables: add nft_parse_register_store() and use it
Pablo Neira Ayuso <[email protected]>
netfilter: nftables: add nft_parse_register_load() and use it
Ryusuke Konishi <[email protected]>
nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode()
Michael Ellerman <[email protected]>
powerpc/64s/radix: Fix soft dirty tracking
Jerry Snitselaar <[email protected]>
tpm/tpm_tis: Disable interrupts for more Lenovo devices
Xiubo Li <[email protected]>
ceph: force updating the msg pointer in non-split case
Vitaliy Tomin <[email protected]>
serial: Add support for Advantech PCI-1611U card
Ilya Leoshkevich <[email protected]>
statfs: enforce statfs[64] structure initialization
Paolo Bonzini <[email protected]>
KVM: x86: do not report a vCPU as preempted outside instruction boundaries
Jimmy Assarsson <[email protected]>
can: kvaser_pciefd: Disable interrupts in probe error path
Jimmy Assarsson <[email protected]>
can: kvaser_pciefd: Do not send EFLUSH command on TFD interrupt
Jimmy Assarsson <[email protected]>
can: kvaser_pciefd: Clear listen-only bit if not explicitly requested
Jimmy Assarsson <[email protected]>
can: kvaser_pciefd: Empty SRB buffer in probe
Jimmy Assarsson <[email protected]>
can: kvaser_pciefd: Call request_irq() before enabling interrupts
Jimmy Assarsson <[email protected]>
can: kvaser_pciefd: Set CAN_STATE_STOPPED in kvaser_pciefd_stop()
Oliver Hartkopp <[email protected]>
can: j1939: recvmsg(): allow MSG_CMSG_COMPAT flag
Luke D. Jones <[email protected]>
ALSA: hda/realtek: Add quirk for 2nd ASUS GU603
Ai Chao <[email protected]>
ALSA: hda/realtek: Add a quirk for HP EliteDesk 805
Nikhil Mahale <[email protected]>
ALSA: hda: Add NVIDIA codec IDs a3 through a7 to patch table
Takashi Iwai <[email protected]>
ALSA: hda: Fix Oops by 9.1 surround channel names
Badhri Jagan Sridharan <[email protected]>
usb: typec: altmodes/displayport: fix pin_assignment_show
Udipto Goswami <[email protected]>
usb: dwc3: debugfs: Resume dwc3 before accessing registers
Weitao Wang <[email protected]>
USB: UHCI: adjust zhaoxin UHCI controllers OverCurrent bit value
Maxime Bizon <[email protected]>
usb-storage: fix deadlock when a scsi command timeouts more than once
Alan Stern <[email protected]>
USB: usbtmc: Fix direction for 0-length ioctl control messages
Eric Dumazet <[email protected]>
vlan: fix a potential uninit-value in vlan_dev_hard_start_xmit()
Aleksandr Loktionov <[email protected]>
igb: fix bit_shift to be in [1..8] range
Christophe JAILLET <[email protected]>
cassini: Fix a memory leak in the error handling path of cas_init_one()
Johannes Berg <[email protected]>
wifi: iwlwifi: mvm: don't trust firmware n_channels
Florian Fainelli <[email protected]>
net: bcmgenet: Restore phy_stop() depending upon suspend/close
Florian Fainelli <[email protected]>
net: bcmgenet: Remove phy_stop() from bcmgenet_netif_stop()
Dong Chenchen <[email protected]>
net: nsh: Use correct mac_offset to unwind gso skb in nsh_gso_segment()
Arnd Bergmann <[email protected]>
drm/exynos: fix g2d_open/close helper function definitions
Duoming Zhou <[email protected]>
media: netup_unidvb: fix use-after-free at del_timer()
Jie Wang <[email protected]>
net: hns3: fix reset delay time to avoid configuration timeout
Jijie Shao <[email protected]>
net: hns3: fix sending pfc frames after reset issue
Xin Long <[email protected]>
erspan: get the proto with the md version for collect_md
Peilin Ye <[email protected]>
ip_gre, ip6_gre: Fix race condition on o_seqno in collect_md mode
Peilin Ye <[email protected]>
ip6_gre: Make o_seqno start from 0 in native mode
Peilin Ye <[email protected]>
ip6_gre: Fix skb_under_panic in __gre6_xmit()
Ke Zhang <[email protected]>
serial: arc_uart: fix of_iomap leak in arc_serial_probe
Zhuang Shengen <[email protected]>
vsock: avoid to close connected socket after the timeout
Dan Carpenter <[email protected]>
ALSA: firewire-digi00x: prevent potential use after free
Uwe Kleine-König <[email protected]>
net: fec: Better handle pm_runtime_get() failing in .remove()
Tobias Brunner <[email protected]>
af_key: Reject optional tunnel/BEET mode templates in outbound policies
Wyes Karny <[email protected]>
cpupower: Make TSC read per CPU for Mperf monitor
Shengjiu Wang <[email protected]>
ASoC: fsl_micfil: register platform component before registering cpu dai
Filipe Manana <[email protected]>
btrfs: fix space cache inconsistency after error loading it from disk
Nikolay Borisov <[email protected]>
btrfs: replace calls to btrfs_find_free_ino with btrfs_find_free_objectid
Qiang Ning <[email protected]>
mfd: dln2: Fix memory leak in dln2_probe()
Alain Volmat <[email protected]>
phy: st: miphy28lp: use _poll_timeout functions for waits
Vicki Pfau <[email protected]>
Input: xpad - add constants for GIP interface numbers
Tomas Krcka <[email protected]>
iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any
Arnd Bergmann <[email protected]>
clk: tegra20: fix gcc-7 constant overflow warning
Gustavo A. R. Silva <[email protected]>
RDMA/core: Fix multiple -Warray-bounds warnings
Hao Zeng <[email protected]>
recordmcount: Fix memory leaks in the uwrite function
Josh Poimboeuf <[email protected]>
sched: Fix KCSAN noinstr violation
Rodríguez Barbarin, José Javier <[email protected]>
mcb-pci: Reallocate memory region to avoid memory overlapping
Tony Lindgren <[email protected]>
serial: 8250: Reinit port->pm on port specific driver unbind
Frank Wang <[email protected]>
usb: typec: tcpm: fix multiple times discover svids error
Jason Gerecke <[email protected]>
HID: wacom: generic: Set battery quirk only when we see battery data
Kevin Groeneveld <[email protected]>
spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3
Bastien Nocera <[email protected]>
HID: logitech-hidpp: Reconcile USB and Unifying serials
Bastien Nocera <[email protected]>
HID: logitech-hidpp: Don't use the USB serial for USB devices
Philipp Hortmann <[email protected]>
staging: rtl8192e: Replace macro RTL_PCI_DEVICE with PCI_DEVICE
Min Li <[email protected]>
Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp
Hans de Goede <[email protected]>
wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write backtrace
Hyunwoo Kim <[email protected]>
wifi: iwlwifi: pcie: Fix integer overflow in iwl_write_to_user_buf
Daniel Gabay <[email protected]>
wifi: iwlwifi: pcie: fix possible NULL pointer dereference
Hao Zeng <[email protected]>
samples/bpf: Fix fout leak in hbm's run_bpf_prog
Chao Yu <[email protected]>
f2fs: fix to drop all dirty pages during umount() if cp_error is set
Ojaswin Mujoo <[email protected]>
ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa()
Kemeng Shi <[email protected]>
ext4: set goal start correctly in ext4_mb_normalize_request
Andreas Gruenbacher <[email protected]>
gfs2: Fix inode height consistency check
Zheng Wang <[email protected]>
scsi: message: mptlan: Fix use after free bug in mptlan_remove() due to race condition
Eli Cohen <[email protected]>
lib: cpu_rmap: Avoid use after free on rmap->obj array entries
Dmitry Bogdanov <[email protected]>
scsi: target: iscsit: Free cmds before session free
Nick Child <[email protected]>
net: Catch invalid index in XPS mapping
Nathan Chancellor <[email protected]>
net: pasemi: Fix return type of pasemi_mac_start_tx()
Justin Tee <[email protected]>
scsi: lpfc: Prevent lpfc_debugfs_lockstat_write() buffer overflow
Jan Kara <[email protected]>
ext2: Check block size validity during mount
Hector Martin <[email protected]>
wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex
void0red <[email protected]>
ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in acpi_db_display_objects
Tamir Duberstein <[email protected]>
ACPICA: Avoid undefined behavior: applying zero offset to null pointer
Nur Hussein <[email protected]>
drm/tegra: Avoid potential 32-bit integer overflow
Armin Wolf <[email protected]>
ACPI: EC: Fix oops when removing custom query handlers
Pierre Gondois <[email protected]>
firmware: arm_sdei: Fix sleep from invalid context BUG
Zheng Wang <[email protected]>
memstick: r592: Fix UAF bug in r592_remove due to race condition
Alexander Stein <[email protected]>
regmap: cache: Return error in cache sync operations for REGCACHE_NONE
Rodrigo Siqueira <[email protected]>
drm/amd/display: Use DC_LOG_DC in the trasform pixel function
Tetsuo Handa <[email protected]>
fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode()
Kuniyuki Iwashima <[email protected]>
af_unix: Fix data races around sk->sk_shutdown.
Kuniyuki Iwashima <[email protected]>
af_unix: Fix a data race of sk->sk_receive_queue->qlen.
Eric Dumazet <[email protected]>
net: datagram: fix data-races in datagram_poll()
t.feng <[email protected]>
ipvlan:Fix out-of-bounds caused by unclear skb->cb
Eric Dumazet <[email protected]>
net: add vlan_get_protocol_and_depth() helper
Menglong Dong <[email protected]>
net: tap: check vlan with eth_type_vlan() method
Eric Dumazet <[email protected]>
net: annotate sk->sk_err write from do_recvmmsg()
Eric Dumazet <[email protected]>
netlink: annotate accesses to nlk->cb_running
Florian Westphal <[email protected]>
netfilter: conntrack: fix possible bug_on with enable_hooks=1
Kuniyuki Iwashima <[email protected]>
net: Fix load-tearing on sk->sk_stamp in sock_recv_cmsgs().
Roy Novich <[email protected]>
linux/dim: Do nothing if no time delta between samples
Randy Dunlap <[email protected]>
ARM: 9296/1: HP Jornada 7XX: fix kernel-doc warnings
Saravana Kannan <[email protected]>
drm/mipi-dsi: Set the fwnode for mipi_dsi_device
Ioana Ciornei <[email protected]>
driver core: add a helper to setup both the of_node and fwnode of a device
-------------
Diffstat:
Makefile | 4 +- arch/arm/mach-sa1100/jornada720_ssp.c | 5 +- arch/m68k/kernel/signal.c | 14 +- arch/parisc/include/asm/cacheflush.h | 5 + arch/parisc/kernel/cache.c | 5 +- arch/parisc/kernel/process.c | 11 +- arch/parisc/kernel/traps.c | 4 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 4 +- arch/x86/include/asm/intel-family.h | 5 + arch/x86/include/asm/kvm_host.h | 3 + arch/x86/kernel/cpu/topology.c | 5 +- arch/x86/kernel/dumpstack.c | 7 +- arch/x86/kvm/svm.c | 3 +- arch/x86/kvm/vmx/vmx.c | 1 + arch/x86/kvm/x86.c | 22 ++ arch/x86/mm/init.c | 25 +++ drivers/acpi/acpica/dbnames.c | 3 + drivers/acpi/acpica/dswstate.c | 11 +- drivers/acpi/ec.c | 1 + drivers/base/core.c | 7 + drivers/base/regmap/regcache.c | 6 + drivers/char/tpm/tpm_tis.c | 16 ++ drivers/clk/tegra/clk-tegra20.c | 28 +-- drivers/firmware/arm_sdei.c | 37 ++-- drivers/gpio/gpio-mockup.c | 2 +- drivers/gpu/drm/amd/display/dc/dce/dce_transform.c | 5 +- drivers/gpu/drm/drm_mipi_dsi.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_g2d.h | 4 +- drivers/gpu/drm/tegra/sor.c | 2 +- drivers/hid/hid-logitech-hidpp.c | 53 ++++- drivers/hid/wacom.h | 3 + drivers/hid/wacom_sys.c | 2 + drivers/hid/wacom_wac.c | 80 ++++++-- drivers/hwtracing/coresight/coresight-tmc-etr.c | 2 +- drivers/infiniband/core/user_mad.c | 23 ++- drivers/input/joystick/xpad.c | 5 +- drivers/iommu/arm-smmu-v3.c | 19 +- drivers/mcb/mcb-pci.c | 27 ++- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 2 +- drivers/media/radio/radio-shark.c | 10 + drivers/media/radio/radio-shark2.c | 10 + drivers/memstick/host/r592.c | 2 +- drivers/message/fusion/mptlan.c | 2 + drivers/mfd/dln2.c | 1 + drivers/net/bonding/bond_main.c | 8 +- drivers/net/can/kvaser_pciefd.c | 51 +++-- drivers/net/ethernet/3com/3c589_cs.c | 11 +- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 9 +- drivers/net/ethernet/freescale/fec_main.c | 13 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 15 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 4 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 5 + .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 +- drivers/net/ethernet/intel/igb/e1000_mac.c | 4 +- .../net/ethernet/mellanox/mlx5/core/lib/devcom.c | 3 +- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- drivers/net/ethernet/nvidia/forcedeth.c | 1 + drivers/net/ethernet/pasemi/pasemi_mac.c | 2 +- drivers/net/ethernet/sun/cassini.c | 2 + drivers/net/ipvlan/ipvlan_core.c | 6 + drivers/net/tap.c | 10 +- drivers/net/team/team.c | 7 +- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 13 +- drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 5 +- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 10 + drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 5 +- drivers/phy/st/phy-miphy28lp.c | 42 +--- drivers/power/supply/bq27xxx_battery.c | 41 ++-- drivers/power/supply/bq27xxx_battery_i2c.c | 3 +- drivers/power/supply/power_supply_leds.c | 5 +- drivers/power/supply/sbs-charger.c | 2 +- drivers/s390/cio/qdio.h | 25 +-- drivers/s390/cio/qdio_main.c | 62 +++--- drivers/scsi/lpfc/lpfc_debugfs.c | 7 +- drivers/spi/spi-fsl-cpm.c | 23 +++ drivers/spi/spi-fsl-spi.c | 53 +++-- drivers/spi/spi-imx.c | 24 ++- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 6 +- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 5 - drivers/target/iscsi/iscsi_target.c | 6 +- drivers/tty/serial/8250/8250_core.c | 1 + drivers/tty/serial/8250/8250_pci.c | 5 + drivers/tty/serial/arc_uart.c | 7 +- drivers/tty/vt/vc_screen.c | 57 ++++-- drivers/usb/class/usbtmc.c | 2 + drivers/usb/core/usb.c | 76 +++++++ drivers/usb/dwc3/debugfs.c | 109 ++++++++++ drivers/usb/gadget/function/u_ether.c | 39 +--- drivers/usb/host/uhci-pci.c | 10 +- drivers/usb/misc/sisusbvga/sisusb.c | 14 ++ drivers/usb/storage/scsiglue.c | 28 ++- drivers/usb/typec/altmodes/displayport.c | 4 + drivers/usb/typec/tcpm/tcpm.c | 16 +- drivers/video/fbdev/udlfb.c | 13 +- drivers/watchdog/sp5100_tco.c | 4 + drivers/xen/pvcalls-back.c | 9 +- fs/btrfs/disk-io.c | 9 + fs/btrfs/free-space-cache.c | 7 +- fs/btrfs/inode.c | 12 +- fs/ceph/snap.c | 13 ++ fs/ext2/ext2.h | 1 + fs/ext2/super.c | 7 + fs/ext4/mballoc.c | 65 +++--- fs/f2fs/checkpoint.c | 12 +- fs/f2fs/data.c | 3 +- fs/gfs2/glops.c | 3 +- fs/hfsplus/inode.c | 28 ++- fs/nilfs2/inode.c | 18 ++ fs/statfs.c | 4 +- include/linux/cpuhotplug.h | 1 - include/linux/device.h | 1 + include/linux/dim.h | 3 +- include/linux/if_team.h | 1 + include/linux/if_vlan.h | 17 ++ include/linux/power/bq27xxx_battery.h | 1 + include/linux/sched/task_stack.h | 2 +- include/linux/string_helpers.h | 15 ++ include/linux/usb.h | 5 + include/net/bonding.h | 1 + include/net/ip6_tunnel.h | 2 +- include/net/ip_tunnels.h | 2 +- include/net/netfilter/nf_tables.h | 15 +- include/net/netfilter/nf_tables_core.h | 8 +- include/net/netfilter/nft_fib.h | 2 +- include/net/netfilter/nft_meta.h | 4 +- include/net/sock.h | 2 +- include/uapi/sound/skl-tplg-interface.h | 3 +- kernel/bpf/verifier.c | 2 +- lib/cpu_rmap.c | 5 +- lib/debugobjects.c | 2 +- lib/dim/dim.c | 5 +- lib/dim/net_dim.c | 3 +- lib/dim/rdma_dim.c | 3 +- net/8021q/vlan_dev.c | 4 +- net/bluetooth/l2cap_core.c | 1 - net/bridge/br_forward.c | 2 +- net/bridge/netfilter/nft_meta_bridge.c | 5 +- net/can/j1939/socket.c | 2 +- net/core/datagram.c | 15 +- net/core/dev.c | 4 +- net/core/skbuff.c | 4 +- net/ipv4/ip_gre.c | 6 +- net/ipv4/netfilter/nft_dup_ipv4.c | 18 +- net/ipv4/udplite.c | 2 + net/ipv6/exthdrs_core.c | 2 + net/ipv6/ip6_gre.c | 36 ++-- net/ipv6/netfilter/nft_dup_ipv6.c | 18 +- net/ipv6/udplite.c | 2 + net/key/af_key.c | 12 +- net/netfilter/core.c | 6 +- net/netfilter/nf_conntrack_standalone.c | 3 +- net/netfilter/nf_tables_api.c | 228 +++++++++++++-------- net/netfilter/nft_bitwise.c | 14 +- net/netfilter/nft_byteorder.c | 14 +- net/netfilter/nft_cmp.c | 8 +- net/netfilter/nft_ct.c | 12 +- net/netfilter/nft_dup_netdev.c | 6 +- net/netfilter/nft_dynset.c | 12 +- net/netfilter/nft_exthdr.c | 14 +- net/netfilter/nft_fib.c | 5 +- net/netfilter/nft_fwd_netdev.c | 18 +- net/netfilter/nft_hash.c | 25 ++- net/netfilter/nft_immediate.c | 6 +- net/netfilter/nft_lookup.c | 14 +- net/netfilter/nft_masq.c | 18 +- net/netfilter/nft_meta.c | 8 +- net/netfilter/nft_nat.c | 35 ++-- net/netfilter/nft_numgen.c | 15 +- net/netfilter/nft_objref.c | 6 +- net/netfilter/nft_osf.c | 8 +- net/netfilter/nft_payload.c | 10 +- net/netfilter/nft_queue.c | 12 +- net/netfilter/nft_range.c | 6 +- net/netfilter/nft_redir.c | 18 +- net/netfilter/nft_rt.c | 7 +- net/netfilter/nft_socket.c | 7 +- net/netfilter/nft_tproxy.c | 14 +- net/netfilter/nft_tunnel.c | 8 +- net/netfilter/nft_xfrm.c | 7 +- net/netlink/af_netlink.c | 8 +- net/nsh/nsh.c | 8 +- net/packet/af_packet.c | 6 +- net/socket.c | 2 +- net/unix/af_unix.c | 22 +- net/vmw_vsock/af_vsock.c | 2 +- samples/bpf/hbm.c | 1 + scripts/recordmcount.c | 6 +- sound/firewire/digi00x/digi00x-stream.c | 4 +- sound/pci/hda/hda_generic.c | 7 +- sound/pci/hda/patch_ca0132.c | 1 + sound/pci/hda/patch_hdmi.c | 5 + sound/pci/hda/patch_realtek.c | 4 + sound/soc/fsl/fsl_micfil.c | 15 +- .../cpupower/utils/idle_monitor/mperf_monitor.c | 31 ++- tools/testing/selftests/memfd/fuse_test.c | 1 + tools/testing/selftests/net/fib_tests.sh | 2 +- 198 files changed, 1658 insertions(+), 833 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/161 driver core: add a helper to setup both the of_node and fwnode of a device
From: Ioana Ciornei <[email protected]>
[ Upstream commit 43e76d463c09a0272b84775bcc727c1eb8b384b2 ]
There are many places where both the fwnode_handle and the of_node of a device need to be populated. Add a function which does both so that we have consistency.
Stable-dep-of: a26cc2934331 ("drm/mipi-dsi: Set the fwnode for mipi_dsi_device")
--- drivers/base/core.c | 7 +++++++ include/linux/device.h | 1 + 2 files changed, 8 insertions(+)
drivers/base/core.c +7 -0
@@ -3474,6 +3474,13 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2) }EXPORT_SYMBOL_GPL (device_set_of_node_from_dev); +void device_set_node (struct device *dev,struct fwnode_handle *fwnode) +{ + dev->fwnode = fwnode; + dev->of_node =to_of_node (fwnode); +} +EXPORT_SYMBOL_GPL (device_set_node); +int device_match_name (struct device *dev,const void *name) {return sysfs_streq (dev_name (dev), name);
include/linux/device.h +1 -0
@@ -1528,6 +1528,7 @@ extern int device_online(struct device *dev);extern void set_primary_fwnode (struct device *dev,struct fwnode_handle *fwnode);extern void set_secondary_fwnode (struct device *dev,struct fwnode_handle *fwnode);void device_set_of_node_from_dev (struct device *dev,const struct device *dev2); +void device_set_node (struct device *dev,struct fwnode_handle *fwnode);static inline int dev_num_vf (struct device *dev) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 2/161 drm/mipi-dsi: Set the fwnode for mipi_dsi_device
In reply to Greg Kroah-HartmanFrom: Saravana Kannan <[email protected]>
[ Upstream commit a26cc2934331b57b5a7164bff344f0a2ec245fc0 ]
After commit 3fb16866b51d ("driver core: fw_devlink: Make cycle detection more robust"), fw_devlink prints an error when consumer devices don't have their fwnode set. This used to be ignored silently.
Set the fwnode mipi_dsi_device so fw_devlink can find them and properly track their dependencies.
This fixes errors like this:
[ 0.334054] nwl-dsi 30a00000.mipi-dsi: Failed to create device link with regulator-lcd-1v8 [ 0.346964] nwl-dsi 30a00000.mipi-dsi: Failed to create device link with backlight-dsi
--- drivers/gpu/drm/drm_mipi_dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/drm_mipi_dsi.c +1 -1
@@ -221,7 +221,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host,return dsi; } - dsi->dev.of_node = info->node; +device_set_node (&dsi->dev,of_fwnode_handle (info->node)); dsi->channel = info->channel;strlcpy (dsi->name, info->type,sizeof (dsi->name));
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 3/161 ARM: 9296/1: HP Jornada 7XX: fix kernel-doc warnings
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
[ Upstream commit 46dd6078dbc7e363a8bb01209da67015a1538929 ]
Fix kernel-doc warnings from the kernel test robot:
jornada720_ssp.c:24: warning: Function parameter or member 'jornada_ssp_lock' not described in 'DEFINE_SPINLOCK' jornada720_ssp.c:24: warning: expecting prototype for arch/arm/mac(). Prototype was for DEFINE_SPINLOCK() instead jornada720_ssp.c:34: warning: Function parameter or member 'byte' not described in 'jornada_ssp_reverse' jornada720_ssp.c:57: warning: Function parameter or member 'byte' not described in 'jornada_ssp_byte' jornada720_ssp.c:85: warning: Function parameter or member 'byte' not described in 'jornada_ssp_inout'
--- arch/arm/mach-sa1100/jornada720_ssp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/mach-sa1100/jornada720_ssp.c +4 -1
@@ -1,5 +1,5 @@// SPDX-License-Identifier: GPL-2.0-only -/** +/* * arch/arm/mac-sa1100/jornada720_ssp.c * * Copyright (C) 2006/2007 Kristoffer Ericson <[email protected]>
@@ -26,6 +26,7 @@ static unsigned long jornada_ssp_flags;/** * jornada_ssp_reverse - reverses input byte +* @byte: input byte to reverse * * we need to reverse all data we receive from the mcu due to its physical location * returns : 01110111 -> 11101110
@@ -46,6 +47,7 @@ EXPORT_SYMBOL(jornada_ssp_reverse);/** * jornada_ssp_byte - waits for ready ssp bus and sends byte +* @byte: input byte to transmit * * waits for fifo buffer to clear and then transmits, if it doesn't then we will * timeout after <timeout> rounds. Needs mcu running before its called.
@@ -77,6 +79,7 @@ EXPORT_SYMBOL(jornada_ssp_byte);/** * jornada_ssp_inout - decide if input is command or trading byte +* @byte: input byte to send (may be %TXDUMMY) * * returns : (jornada_ssp_byte(byte)) on success * : %-ETIMEDOUT on timeout failure
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 4/161 linux/dim: Do nothing if no time delta between samples
In reply to Greg Kroah-HartmanFrom: Roy Novich <[email protected]>
[ Upstream commit 162bd18eb55adf464a0fa2b4144b8d61c75ff7c2 ]
Add return value for dim_calc_stats. This is an indication for the caller if curr_stats was assigned by the function. Avoid using curr_stats uninitialized over {rdma/net}_dim, when no time delta between samples. Coverity reported this potential use of an uninitialized variable.
--- include/linux/dim.h | 3 ++- lib/dim/dim.c | 5 +++-- lib/dim/net_dim.c | 3 ++- lib/dim/rdma_dim.c | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-)
include/linux/dim.h +2 -1
@@ -233,8 +233,9 @@ void dim_park_tired(struct dim *dim);* * Calculate the delta between two samples (in data rates). * Takes into consideration counter wrap-around. +* Returned boolean indicates whether curr_stats are reliable. */ -void dim_calc_stats (struct dim_sample *start,struct dim_sample *end, +bool dim_calc_stats (struct dim_sample *start,struct dim_sample *end,struct dim_stats *curr_stats);/**
lib/dim/dim.c +3 -2
@@ -54,7 +54,7 @@ void dim_park_tired(struct dim *dim) }EXPORT_SYMBOL (dim_park_tired); -void dim_calc_stats (struct dim_sample *start,struct dim_sample *end, +bool dim_calc_stats (struct dim_sample *start,struct dim_sample *end,struct dim_stats *curr_stats) {/* u32 holds up to 71 minutes, should be enough */
@@ -66,7 +66,7 @@ void dim_calc_stats(struct dim_sample *start, struct dim_sample *end, start->comp_ctr);if (!delta_us) -return ; +return false; curr_stats->ppms =DIV_ROUND_UP (npkts *USEC_PER_MSEC , delta_us); curr_stats->bpms =DIV_ROUND_UP (nbytes *USEC_PER_MSEC , delta_us);
@@ -79,5 +79,6 @@ void dim_calc_stats(struct dim_sample *start, struct dim_sample *end,else curr_stats->cpe_ratio =0 ; +return true; }EXPORT_SYMBOL (dim_calc_stats);
lib/dim/net_dim.c +2 -1
@@ -227,7 +227,8 @@ void net_dim(struct dim *dim, struct dim_sample end_sample) dim->start_sample.event_ctr);if (nevents <DIM_NEVENTS )break ; -dim_calc_stats (&dim->start_sample, &end_sample, &curr_stats); +if (!dim_calc_stats (&dim->start_sample, &end_sample, &curr_stats)) +break ;if (net_dim_decision (&curr_stats, dim)) { dim->state =DIM_APPLY_NEW_PROFILE ;schedule_work (&dim->work);
lib/dim/rdma_dim.c +2 -1
@@ -88,7 +88,8 @@ void rdma_dim(struct dim *dim, u64 completions) nevents = curr_sample->event_ctr - dim->start_sample.event_ctr;if (nevents <DIM_NEVENTS )break ; -dim_calc_stats (&dim->start_sample, curr_sample, &curr_stats); +if (!dim_calc_stats (&dim->start_sample, curr_sample, &curr_stats)) +break ;if (rdma_dim_decision (&curr_stats, dim)) { dim->state =DIM_APPLY_NEW_PROFILE ;schedule_work (&dim->work);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 5/161 net: Fix load-tearing on sk->sk_stamp in sock_recv_cmsgs().
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit dfd9248c071a3710c24365897459538551cb7167 ]
KCSAN found a data race in sock_recv_cmsgs() where the read access to sk->sk_stamp needs READ_ONCE().
BUG: KCSAN: data-race in packet_recvmsg / packet_recvmsg
write (marked) to 0xffff88803c81f258 of 8 bytes by task 19171 on cpu 0:
sock_write_timestamp include/net/sock.h:2670 [inline] sock_recv_cmsgs include/net/sock.h:2722 [inline] packet_recvmsg+0xb97/0xd00 net/packet/af_packet.c:3489 sock_recvmsg_nosec net/socket.c:1019 [inline] sock_recvmsg+0x11a/0x130 net/socket.c:1040 sock_read_iter+0x176/0x220 net/socket.c:1118 call_read_iter include/linux/fs.h:1845 [inline] new_sync_read fs/read_write.c:389 [inline] vfs_read+0x5e0/0x630 fs/read_write.c:470 ksys_read+0x163/0x1a0 fs/read_write.c:613 __do_sys_read fs/read_write.c:623 [inline] __se_sys_read fs/read_write.c:621 [inline] __x64_sys_read+0x41/0x50 fs/read_write.c:621 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
read to 0xffff88803c81f258 of 8 bytes by task 19183 on cpu 1:
sock_recv_cmsgs include/net/sock.h:2721 [inline] packet_recvmsg+0xb64/0xd00 net/packet/af_packet.c:3489 sock_recvmsg_nosec net/socket.c:1019 [inline] sock_recvmsg+0x11a/0x130 net/socket.c:1040 sock_read_iter+0x176/0x220 net/socket.c:1118 call_read_iter include/linux/fs.h:1845 [inline] new_sync_read fs/read_write.c:389 [inline] vfs_read+0x5e0/0x630 fs/read_write.c:470 ksys_read+0x163/0x1a0 fs/read_write.c:613 __do_sys_read fs/read_write.c:623 [inline] __se_sys_read fs/read_write.c:621 [inline] __x64_sys_read+0x41/0x50 fs/read_write.c:621 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
value changed: 0xffffffffc4653600 -> 0x0000000000000000
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 PID: 19183 Comm: syz-executor.5 Not tainted 6.3.0-rc7-02330-gca6270c12e20 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
--- include/net/sock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/net/sock.h +1 -1
@@ -2448,7 +2448,7 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,__sock_recv_ts_and_drops (msg, sk, skb); else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) sock_write_timestamp(sk, skb->tstamp); - else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP)) + else if (unlikely(sock_read_timestamp(sk) == SK_DEFAULT_STAMP)) sock_write_timestamp(sk, 0); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 6/161 netfilter: conntrack: fix possible bug_on with enable_hooks=1
In reply to Greg Kroah-HartmanFrom: Florian Westphal <[email protected]>
[ Upstream commit e72eeab542dbf4f544e389e64fa13b82a1b6d003 ]
I received a bug report (no reproducer so far) where we trip over
712 rcu_read_lock(); 713 ct_hook = rcu_dereference(nf_ct_hook); 714 BUG_ON(ct_hook == NULL); // here
In nf_conntrack_destroy().
First turn this BUG_ON into a WARN. I think it was triggered via enable_hooks=1 flag.
When this flag is turned on, the conntrack hooks are registered before nf_ct_hook pointer gets assigned.
This opens a short window where packets enter the conntrack machinery, can have skb->_nfct set up and a subsequent kfree_skb might occur before nf_ct_hook is set.
Call nf_conntrack_init_end() to set nf_ct_hook before we register the pernet ops.
--- net/netfilter/core.c | 6 ++++-- net/netfilter/nf_conntrack_standalone.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-)
net/netfilter/core.c +4 -2
@@ -577,9 +577,11 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)rcu_read_lock (); ct_hook =rcu_dereference (nf_ct_hook); -BUG_ON (ct_hook ==NULL ); - ct_hook->destroy (nfct); +if (ct_hook) + ct_hook->destroy (nfct);rcu_read_unlock (); + +WARN_ON (!ct_hook); }EXPORT_SYMBOL (nf_conntrack_destroy);
net/netfilter/nf_conntrack_standalone.c +2 -1
@@ -1180,11 +1180,12 @@ static int __init nf_conntrack_standalone_init(void) nf_conntrack_htable_size_user = nf_conntrack_htable_size;#endif +nf_conntrack_init_end (); + ret =register_pernet_subsys (&nf_conntrack_net_ops);if (ret <0 ) goto out_pernet; -nf_conntrack_init_end ();return 0 ; out_pernet:
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 7/161 netlink: annotate accesses to nlk->cb_running
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit a939d14919b799e6fff8a9c80296ca229ba2f8a4 ]
Both netlink_recvmsg() and netlink_native_seq_show() read nlk->cb_running locklessly. Use READ_ONCE() there.
Add corresponding WRITE_ONCE() to netlink_dump() and __netlink_dump_start()
syzbot reported:
BUG: KCSAN: data-race in __netlink_dump_start / netlink_recvmsg
write to 0xffff88813ea4db59 of 1 bytes by task 28219 on cpu 0:
__netlink_dump_start+0x3af/0x4d0 net/netlink/af_netlink.c:2399 netlink_dump_start include/linux/netlink.h:308 [inline] rtnetlink_rcv_msg+0x70f/0x8c0 net/core/rtnetlink.c:6130 netlink_rcv_skb+0x126/0x220 net/netlink/af_netlink.c:2577 rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:6192 netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline] netlink_unicast+0x56f/0x640 net/netlink/af_netlink.c:1365 netlink_sendmsg+0x665/0x770 net/netlink/af_netlink.c:1942 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] sock_write_iter+0x1aa/0x230 net/socket.c:1138 call_write_iter include/linux/fs.h:1851 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x463/0x760 fs/read_write.c:584 ksys_write+0xeb/0x1a0 fs/read_write.c:637 __do_sys_write fs/read_write.c:649 [inline] __se_sys_write fs/read_write.c:646 [inline] __x64_sys_write+0x42/0x50 fs/read_write.c:646 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
read to 0xffff88813ea4db59 of 1 bytes by task 28222 on cpu 1:
netlink_recvmsg+0x3b4/0x730 net/netlink/af_netlink.c:2022 sock_recvmsg_nosec+0x4c/0x80 net/socket.c:1017 ____sys_recvmsg+0x2db/0x310 net/socket.c:2718 ___sys_recvmsg net/socket.c:2762 [inline] do_recvmmsg+0x2e5/0x710 net/socket.c:2856 __sys_recvmmsg net/socket.c:2935 [inline] __do_sys_recvmmsg net/socket.c:2958 [inline] __se_sys_recvmmsg net/socket.c:2951 [inline] __x64_sys_recvmmsg+0xe2/0x160 net/socket.c:2951 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
value changed: 0x00 -> 0x01
--- net/netlink/af_netlink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/netlink/af_netlink.c +4 -4
@@ -1991,7 +1991,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,skb_free_datagram (sk, skb); -if (nlk->cb_running && +if (READ_ONCE (nlk->cb_running) &&atomic_read (&sk->sk_rmem_alloc) <= sk->sk_rcvbuf /2 ) { ret =netlink_dump (sk);if (ret) {
@@ -2284,7 +2284,7 @@ static int netlink_dump(struct sock *sk)if (cb->done) cb->done (cb); - nlk->cb_running = false; +WRITE_ONCE (nlk->cb_running, false); module = cb->module; skb = cb->skb;mutex_unlock (nlk->cb_mutex);
@@ -2347,7 +2347,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, goto error_put; } - nlk->cb_running = true; +WRITE_ONCE (nlk->cb_running, true); nlk->dump_done_errno =INT_MAX ;mutex_unlock (nlk->cb_mutex);
@@ -2636,7 +2636,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) nlk->groups ? (u32 )nlk->groups[0 ] :0 ,sk_rmem_alloc_get (s),sk_wmem_alloc_get (s), - nlk->cb_running, +READ_ONCE (nlk->cb_running),refcount_read (&s->sk_refcnt),atomic_read (&s->sk_drops),sock_i_ino (s)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 8/161 net: annotate sk->sk_err write from do_recvmmsg()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit e05a5f510f26607616fecdd4ac136310c8bea56b ]
do_recvmmsg() can write to sk->sk_err from multiple threads.
As said before, many other points reading or writing sk_err need annotations.
--- net/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/socket.c +1 -1
@@ -2723,7 +2723,7 @@ static int do_recvmmsg(int fd, struct mmsghdr __user *mmsg,* error to return on the next call or if the * app asks about it using getsockopt(SO_ERROR). */ - sock->sk->sk_err = -err; +WRITE_ONCE (sock->sk->sk_err, -err); } out_put:fput_light (sock->file, fput_needed);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 9/161 net: tap: check vlan with eth_type_vlan() method
In reply to Greg Kroah-HartmanFrom: Menglong Dong <[email protected]>
[ Upstream commit b69df2608281b71575fbb3b9f426dbcc4be8a700 ]
Replace some checks for ETH_P_8021Q and ETH_P_8021AD in drivers/net/tap.c with eth_type_vlan.
Stable-dep-of: 4063384ef762 ("net: add vlan_get_protocol_and_depth() helper")
--- drivers/net/tap.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/tap.c +2 -4
@@ -715,8 +715,7 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,skb_probe_transport_header (skb);/* Move network header to the right position for VLAN tagged packets */ -if ((skb->protocol ==htons (ETH_P_8021Q ) || - skb->protocol ==htons (ETH_P_8021AD )) && +if (eth_type_vlan (skb->protocol) &&__vlan_get_protocol (skb, skb->protocol, &depth) !=0 )skb_set_network_header (skb, depth);
@@ -1177,8 +1176,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp) }/* Move network header to the right position for VLAN tagged packets */ -if ((skb->protocol ==htons (ETH_P_8021Q ) || - skb->protocol ==htons (ETH_P_8021AD )) && +if (eth_type_vlan (skb->protocol) &&__vlan_get_protocol (skb, skb->protocol, &depth) !=0 )skb_set_network_header (skb, depth);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 10/161 net: add vlan_get_protocol_and_depth() helper
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 4063384ef762cc5946fc7a3f89879e76c6ec51e2 ]
Before blamed commit, pskb_may_pull() was used instead of skb_header_pointer() in __vlan_get_protocol() and friends.
Few callers depended on skb->head being populated with MAC header, syzbot caught one of them (skb_mac_gso_segment())
Add vlan_get_protocol_and_depth() to make the intent clearer and use it where sensible.
This is a more generic fix than commit e9d3f80935b6 ("net/af_packet: make sure to pull mac header") which was dealing with a similar issue.
kernel BUG at include/linux/skbuff.h:2655 !
invalid opcode: 0000 [#1] SMP KASAN
CPU: 0 PID: 1441 Comm: syz-executor199 Not tainted 6.1.24-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/14/2023 RIP: 0010:__skb_pull include/linux/skbuff.h:2655 [inline] RIP: 0010:skb_mac_gso_segment+0x68f/0x6a0 net/core/gro.c:136 Code: fd 48 8b 5c 24 10 44 89 6b 70 48 c7 c7 c0 ae 0d 86 44 89 e6 e8 a1 91 d0 00 48 c7 c7 00 af 0d 86 48 89 de 31 d2 e8 d1 4a e9 ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 41 RSP: 0018:ffffc90001bd7520 EFLAGS: 00010286 RAX: ffffffff8469736a RBX: ffff88810f31dac0 RCX: ffff888115a18b00 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffffc90001bd75e8 R08: ffffffff84697183 R09: fffff5200037adf9 R10: 0000000000000000 R11: dffffc0000000001 R12: 0000000000000012 R13: 000000000000fee5 R14: 0000000000005865 R15: 000000000000fed7 FS: 000055555633f300(0000) GS:ffff8881f6a00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000020000000 CR3: 0000000116fea000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> [<ffffffff847018dd>] __skb_gso_segment+0x32d/0x4c0 net/core/dev.c:3419 [<ffffffff8470398a>] skb_gso_segment include/linux/netdevice.h:4819 [inline] [<ffffffff8470398a>] validate_xmit_skb+0x3aa/0xee0 net/core/dev.c:3725 [<ffffffff84707042>] __dev_queue_xmit+0x1332/0x3300 net/core/dev.c:4313 [<ffffffff851a9ec7>] dev_queue_xmit+0x17/0x20 include/linux/netdevice.h:3029 [<ffffffff851b4a82>] packet_snd net/packet/af_packet.c:3111 [inline] [<ffffffff851b4a82>] packet_sendmsg+0x49d2/0x6470 net/packet/af_packet.c:3142 [<ffffffff84669a12>] sock_sendmsg_nosec net/socket.c:716 [inline] [<ffffffff84669a12>] sock_sendmsg net/socket.c:736 [inline] [<ffffffff84669a12>] __sys_sendto+0x472/0x5f0 net/socket.c:2139 [<ffffffff84669c75>] __do_sys_sendto net/socket.c:2151 [inline] [<ffffffff84669c75>] __se_sys_sendto net/socket.c:2147 [inline] [<ffffffff84669c75>] __x64_sys_sendto+0xe5/0x100 net/socket.c:2147 [<ffffffff8551d40f>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] [<ffffffff8551d40f>] do_syscall_64+0x2f/0x50 arch/x86/entry/common.c:80 [<ffffffff85600087>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
--- drivers/net/tap.c | 4 ++-- include/linux/if_vlan.h | 17 +++++++++++++++++ net/bridge/br_forward.c | 2 +- net/core/dev.c | 2 +- net/packet/af_packet.c | 6 ++---- 5 files changed, 23 insertions(+), 8 deletions(-)
drivers/net/tap.c +2 -2
@@ -716,7 +716,7 @@ static ssize_t tap_get_user(struct tap_queue *q, void *msg_control,/* Move network header to the right position for VLAN tagged packets */ if (eth_type_vlan (skb->protocol) && -__vlan_get_protocol (skb, skb->protocol, &depth) !=0 ) +vlan_get_protocol_and_depth (skb, skb->protocol, &depth) !=0 )skb_set_network_header (skb, depth);rcu_read_lock ();
@@ -1177,7 +1177,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)/* Move network header to the right position for VLAN tagged packets */ if (eth_type_vlan (skb->protocol) && -__vlan_get_protocol (skb, skb->protocol, &depth) !=0 ) +vlan_get_protocol_and_depth (skb, skb->protocol, &depth) !=0 )skb_set_network_header (skb, depth);rcu_read_lock ();
include/linux/if_vlan.h +17 -0
@@ -626,6 +626,23 @@ static inline __be16 vlan_get_protocol(const struct sk_buff *skb)return __vlan_get_protocol (skb, skb->protocol,NULL ); } +/* This version of __vlan_get_protocol() also pulls mac header in skb->head */ +static inline __be16 vlan_get_protocol_and_depth (struct sk_buff *skb, +__be16 type,int *depth) +{ +int maclen; + + type =__vlan_get_protocol (skb, type, &maclen); + +if (type) { +if (!pskb_may_pull (skb, maclen)) + type =0 ; +else if (depth) + *depth = maclen; + } +return type; +} +/* A getter for the SKB protocol field which will handle VLAN tags consistently * whether VLAN acceleration is enabled or not. */
net/bridge/br_forward.c +1 -1
@@ -43,7 +43,7 @@ int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb skb->protocol == htons(ETH_P_8021AD))) {int depth; -if (!__vlan_get_protocol (skb, skb->protocol, &depth)) +if (!vlan_get_protocol_and_depth (skb, skb->protocol, &depth)) goto drop;skb_set_network_header (skb, depth);
net/core/dev.c +1 -1
@@ -2936,7 +2936,7 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth) type = eth->h_proto; } -return __vlan_get_protocol (skb, type, depth); +return vlan_get_protocol_and_depth (skb, type, depth); }/**
net/packet/af_packet.c +2 -4
@@ -1876,10 +1876,8 @@ static void packet_parse_headers(struct sk_buff *skb, struct socket *sock)/* 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 ) { -if (pskb_may_pull (skb, depth)) -skb_set_network_header (skb, depth); - } +vlan_get_protocol_and_depth (skb, skb->protocol, &depth) !=0 ) +skb_set_network_header (skb, depth);skb_probe_transport_header (skb); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 11/161 ipvlan:Fix out-of-bounds caused by unclear skb->cb
In reply to Greg Kroah-HartmanFrom: t.feng <[email protected]>
[ Upstream commit 90cbed5247439a966b645b34eb0a2e037836ea8e ]
If skb enqueue the qdisc, fq_skb_cb(skb)->time_to_send is changed which is actually skb->cb, and IPCB(skb_in)->opt will be used in __ip_options_echo. It is possible that memcpy is out of bounds and lead to stack overflow.
We should clear skb->cb before ip_local_out or ip6_local_out.
v2:
1. clean the stack info
2. use IPCB/IP6CB instead of skb->cb
crash on stable-5.10(reproduce in kasan kernel).
Stack info:
[ 2203.651571] BUG: KASAN: stack-out-of-bounds in __ip_options_echo+0x589/0x800 [ 2203.653327] Write of size 4 at addr ffff88811a388f27 by task swapper/3/0 [ 2203.655460] CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Not tainted 5.10.0-60.18.0.50.h856.kasan.eulerosv2r11.x86_64 #1 [ 2203.655466] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.10.2-0-g5f4c7b1-20181220_000000-szxrtosci10000 04/01/2014 [ 2203.655475] Call Trace: [ 2203.655481] <IRQ> [ 2203.655501] dump_stack+0x9c/0xd3 [ 2203.655514] print_address_description.constprop.0+0x19/0x170 [ 2203.655530] __kasan_report.cold+0x6c/0x84 [ 2203.655586] kasan_report+0x3a/0x50 [ 2203.655594] check_memory_region+0xfd/0x1f0 [ 2203.655601] memcpy+0x39/0x60 [ 2203.655608] __ip_options_echo+0x589/0x800 [ 2203.655654] __icmp_send+0x59a/0x960 [ 2203.655755] nf_send_unreach+0x129/0x3d0 [nf_reject_ipv4] [ 2203.655763] reject_tg+0x77/0x1bf [ipt_REJECT] [ 2203.655772] ipt_do_table+0x691/0xa40 [ip_tables] [ 2203.655821] nf_hook_slow+0x69/0x100 [ 2203.655828] __ip_local_out+0x21e/0x2b0 [ 2203.655857] ip_local_out+0x28/0x90 [ 2203.655868] ipvlan_process_v4_outbound+0x21e/0x260 [ipvlan] [ 2203.655931] ipvlan_xmit_mode_l3+0x3bd/0x400 [ipvlan] [ 2203.655967] ipvlan_queue_xmit+0xb3/0x190 [ipvlan] [ 2203.655977] ipvlan_start_xmit+0x2e/0xb0 [ipvlan] [ 2203.655984] xmit_one.constprop.0+0xe1/0x280 [ 2203.655992] dev_hard_start_xmit+0x62/0x100 [ 2203.656000] sch_direct_xmit+0x215/0x640 [ 2203.656028] __qdisc_run+0x153/0x1f0 [ 2203.656069] __dev_queue_xmit+0x77f/0x1030 [ 2203.656173] ip_finish_output2+0x59b/0xc20 [ 2203.656244] __ip_finish_output.part.0+0x318/0x3d0 [ 2203.656312] ip_finish_output+0x168/0x190 [ 2203.656320] ip_output+0x12d/0x220 [ 2203.656357] __ip_queue_xmit+0x392/0x880 [ 2203.656380] __tcp_transmit_skb+0x1088/0x11c0 [ 2203.656436] __tcp_retransmit_skb+0x475/0xa30 [ 2203.656505] tcp_retransmit_skb+0x2d/0x190 [ 2203.656512] tcp_retransmit_timer+0x3af/0x9a0 [ 2203.656519] tcp_write_timer_handler+0x3ba/0x510 [ 2203.656529] tcp_write_timer+0x55/0x180 [ 2203.656542] call_timer_fn+0x3f/0x1d0 [ 2203.656555] expire_timers+0x160/0x200 [ 2203.656562] run_timer_softirq+0x1f4/0x480 [ 2203.656606] __do_softirq+0xfd/0x402 [ 2203.656613] asm_call_irq_on_stack+0x12/0x20 [ 2203.656617] </IRQ> [ 2203.656623] do_softirq_own_stack+0x37/0x50 [ 2203.656631] irq_exit_rcu+0x134/0x1a0 [ 2203.656639] sysvec_apic_timer_interrupt+0x36/0x80 [ 2203.656646] asm_sysvec_apic_timer_interrupt+0x12/0x20 [ 2203.656654] RIP: 0010:default_idle+0x13/0x20 [ 2203.656663] Code: 89 f0 5d 41 5c 41 5d 41 5e c3 cc cc cc cc cc cc cc cc cc cc cc cc cc 0f 1f 44 00 00 0f 1f 44 00 00 0f 00 2d 9f 32 57 00 fb f4 <c3> cc cc cc cc 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 54 be 08 [ 2203.656668] RSP: 0018:ffff88810036fe78 EFLAGS: 00000256 [ 2203.656676] RAX: ffffffffaf2a87f0 RBX: ffff888100360000 RCX: ffffffffaf290191 [ 2203.656681] RDX: 0000000000098b5e RSI: 0000000000000004 RDI: ffff88811a3c4f60 [ 2203.656686] RBP: 0000000000000000 R08: 0000000000000001 R09: ffff88811a3c4f63 [ 2203.656690] R10: ffffed10234789ec R11: 0000000000000001 R12: 0000000000000003 [ 2203.656695] R13: ffff888100360000 R14: 0000000000000000 R15: 0000000000000000 [ 2203.656729] default_idle_call+0x5a/0x150 [ 2203.656735] cpuidle_idle_call+0x1c6/0x220 [ 2203.656780] do_idle+0xab/0x100 [ 2203.656786] cpu_startup_entry+0x19/0x20 [ 2203.656793] secondary_startup_64_no_verify+0xc2/0xcb
[ 2203.657409] The buggy address belongs to the page: [ 2203.658648] page:0000000027a9842f refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x11a388 [ 2203.658665] flags: 0x17ffffc0001000(reserved|node=0|zone=2|lastcpupid=0x1fffff) [ 2203.658675] raw: 0017ffffc0001000 ffffea000468e208 ffffea000468e208 0000000000000000 [ 2203.658682] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000 [ 2203.658686] page dumped because: kasan: bad access detected
To reproduce(ipvlan with IPVLAN_MODE_L3):
Env setting:
=======================================================
modprobe ipvlan ipvlan_default_mode=1
sysctl net.ipv4.conf.eth0.forwarding=1
iptables -t nat -A POSTROUTING -s 20.0.0.0/255.255.255.0 -o eth0 -j MASQUERADE
ip link add gw link eth0 type ipvlan
ip -4 addr add 20.0.0.254/24 dev gw
ip netns add net1
ip link add ipv1 link eth0 type ipvlan
ip link set ipv1 netns net1
ip netns exec net1 ip link set ipv1 up
ip netns exec net1 ip -4 addr add 20.0.0.4/24 dev ipv1
ip netns exec net1 route add default gw 20.0.0.254
ip netns exec net1 tc qdisc add dev ipv1 root netem loss 10% ifconfig gw up
iptables -t filter -A OUTPUT -p tcp --dport 8888 -j REJECT --reject-with icmp-port-unreachable
=======================================================
And then excute the shell(curl any address of eth0 can reach):
for((i=1;i<=100000;i++))
do
ip netns exec net1 curl x.x.x.x:8888
done
=======================================================
--- drivers/net/ipvlan/ipvlan_core.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/ipvlan/ipvlan_core.c +6 -0
@@ -437,6 +437,9 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) goto err; }skb_dst_set (skb, &rt->dst); + +memset (IPCB (skb),0 ,sizeof (*IPCB (skb))); + err =ip_local_out (net, skb->sk, skb);if (unlikely (net_xmit_eval (err))) dev->stats.tx_errors++;
@@ -475,6 +478,9 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) goto err; }skb_dst_set (skb, dst); + +memset (IP6CB (skb),0 ,sizeof (*IP6CB (skb))); + err =ip6_local_out (net, skb->sk, skb);if (unlikely (net_xmit_eval (err))) dev->stats.tx_errors++;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 12/161 net: datagram: fix data-races in datagram_poll()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit 5bca1d081f44c9443e61841842ce4e9179d327b6 ]
datagram_poll() runs locklessly, we should add READ_ONCE() annotations while reading sk->sk_err, sk->sk_shutdown and sk->sk_state.
--- net/core/datagram.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
net/core/datagram.c +10 -5
@@ -778,18 +778,21 @@ __poll_t datagram_poll(struct file *file, struct socket *sock, {struct sock *sk = sock->sk;__poll_t mask; +u8 shutdown;sock_poll_wait (file, sock, wait); mask =0 ;/* exceptional events? */ -if (sk->sk_err || !skb_queue_empty_lockless (&sk->sk_error_queue)) +if (READ_ONCE (sk->sk_err) || + !skb_queue_empty_lockless (&sk->sk_error_queue)) mask |=EPOLLERR | (sock_flag (sk,SOCK_SELECT_ERR_QUEUE ) ?EPOLLPRI :0 ); -if (sk->sk_shutdown &RCV_SHUTDOWN ) + shutdown =READ_ONCE (sk->sk_shutdown); +if (shutdown &RCV_SHUTDOWN ) mask |=EPOLLRDHUP |EPOLLIN |EPOLLRDNORM ; -if (sk->sk_shutdown ==SHUTDOWN_MASK ) +if (shutdown ==SHUTDOWN_MASK ) mask |=EPOLLHUP ;/* readable? */
@@ -798,10 +801,12 @@ __poll_t datagram_poll(struct file *file, struct socket *sock,/* Connection-based need to check for termination and startup */ if (connection_based (sk)) { -if (sk->sk_state ==TCP_CLOSE ) +int state =READ_ONCE (sk->sk_state); + +if (state ==TCP_CLOSE ) mask |=EPOLLHUP ;/* connection hasn't started yet? */ -if (sk->sk_state ==TCP_SYN_SENT ) +if (state ==TCP_SYN_SENT )return mask; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 13/161 af_unix: Fix a data race of sk->sk_receive_queue->qlen.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 679ed006d416ea0cecfe24a99d365d1dea69c683 ]
KCSAN found a data race of sk->sk_receive_queue->qlen where recvmsg() updates qlen under the queue lock and sendmsg() checks qlen under unix_state_sock(), not the queue lock, so the reader side needs READ_ONCE().
BUG: KCSAN: data-race in __skb_try_recv_from_queue / unix_wait_for_peer
write (marked) to 0xffff888019fe7c68 of 4 bytes by task 49792 on cpu 0:
__skb_unlink include/linux/skbuff.h:2347 [inline] __skb_try_recv_from_queue+0x3de/0x470 net/core/datagram.c:197 __skb_try_recv_datagram+0xf7/0x390 net/core/datagram.c:263 __unix_dgram_recvmsg+0x109/0x8a0 net/unix/af_unix.c:2452 unix_dgram_recvmsg+0x94/0xa0 net/unix/af_unix.c:2549 sock_recvmsg_nosec net/socket.c:1019 [inline] ____sys_recvmsg+0x3a3/0x3b0 net/socket.c:2720 ___sys_recvmsg+0xc8/0x150 net/socket.c:2764 do_recvmmsg+0x182/0x560 net/socket.c:2858 __sys_recvmmsg net/socket.c:2937 [inline] __do_sys_recvmmsg net/socket.c:2960 [inline] __se_sys_recvmmsg net/socket.c:2953 [inline] __x64_sys_recvmmsg+0x153/0x170 net/socket.c:2953 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
read to 0xffff888019fe7c68 of 4 bytes by task 49793 on cpu 1:
skb_queue_len include/linux/skbuff.h:2127 [inline] unix_recvq_full net/unix/af_unix.c:229 [inline] unix_wait_for_peer+0x154/0x1a0 net/unix/af_unix.c:1445 unix_dgram_sendmsg+0x13bc/0x14b0 net/unix/af_unix.c:2048 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x148/0x160 net/socket.c:747 ____sys_sendmsg+0x20e/0x620 net/socket.c:2503 ___sys_sendmsg+0xc6/0x140 net/socket.c:2557 __sys_sendmmsg+0x11d/0x370 net/socket.c:2643 __do_sys_sendmmsg net/socket.c:2672 [inline] __se_sys_sendmmsg net/socket.c:2669 [inline] __x64_sys_sendmmsg+0x58/0x70 net/socket.c:2669 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
value changed: 0x0000000b -> 0x00000001
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 PID: 49793 Comm: syz-executor.0 Not tainted 6.3.0-rc7-02330-gca6270c12e20 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
--- net/unix/af_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
@@ -1227,7 +1227,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) sched = !sock_flag (other,SOCK_DEAD ) && !(other->sk_shutdown &RCV_SHUTDOWN ) && -unix_recvq_full (other); +unix_recvq_full_lockless (other);unix_state_unlock (other);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 14/161 af_unix: Fix data races around sk->sk_shutdown.
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
[ Upstream commit e1d09c2c2f5793474556b60f83900e088d0d366d ]
KCSAN found a data race around sk->sk_shutdown where unix_release_sock() and unix_shutdown() update it under unix_state_lock(), OTOH unix_poll() and unix_dgram_poll() read it locklessly.
We need to annotate the writes and reads with WRITE_ONCE() and READ_ONCE().
BUG: KCSAN: data-race in unix_poll / unix_release_sock
write to 0xffff88800d0f8aec of 1 bytes by task 264 on cpu 0:
unix_release_sock+0x75c/0x910 net/unix/af_unix.c:631 unix_release+0x59/0x80 net/unix/af_unix.c:1042 __sock_release+0x7d/0x170 net/socket.c:653 sock_close+0x19/0x30 net/socket.c:1397 __fput+0x179/0x5e0 fs/file_table.c:321 ____fput+0x15/0x20 fs/file_table.c:349 task_work_run+0x116/0x1a0 kernel/task_work.c:179 resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x174/0x180 kernel/entry/common.c:204 __syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline] syscall_exit_to_user_mode+0x1a/0x30 kernel/entry/common.c:297 do_syscall_64+0x4b/0x90 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x72/0xdc
read to 0xffff88800d0f8aec of 1 bytes by task 222 on cpu 1:
unix_poll+0xa3/0x2a0 net/unix/af_unix.c:3170 sock_poll+0xcf/0x2b0 net/socket.c:1385 vfs_poll include/linux/poll.h:88 [inline] ep_item_poll.isra.0+0x78/0xc0 fs/eventpoll.c:855 ep_send_events fs/eventpoll.c:1694 [inline] ep_poll fs/eventpoll.c:1823 [inline] do_epoll_wait+0x6c4/0xea0 fs/eventpoll.c:2258 __do_sys_epoll_wait fs/eventpoll.c:2270 [inline] __se_sys_epoll_wait fs/eventpoll.c:2265 [inline] __x64_sys_epoll_wait+0xcc/0x190 fs/eventpoll.c:2265 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
value changed: 0x00 -> 0x03
Reported by Kernel Concurrency Sanitizer on:
CPU: 1 PID: 222 Comm: dbus-broker Not tainted 6.3.0-rc7-02330-gca6270c12e20 #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
--- net/unix/af_unix.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
net/unix/af_unix.c +12 -8
@@ -531,7 +531,7 @@ static void unix_release_sock(struct sock *sk, int embrion)/* Clear state */ unix_state_lock (sk);sock_orphan (sk); - sk->sk_shutdown =SHUTDOWN_MASK ; +WRITE_ONCE (sk->sk_shutdown,SHUTDOWN_MASK ); path = u->path; u->path.dentry =NULL ; u->path.mnt =NULL ;
@@ -549,7 +549,7 @@ static void unix_release_sock(struct sock *sk, int embrion)if (sk->sk_type ==SOCK_STREAM || sk->sk_type ==SOCK_SEQPACKET ) {unix_state_lock (skpair);/* No more writes */ - skpair->sk_shutdown =SHUTDOWN_MASK ; +WRITE_ONCE (skpair->sk_shutdown,SHUTDOWN_MASK );if (!skb_queue_empty (&sk->sk_receive_queue) || embrion) skpair->sk_err =ECONNRESET ;unix_state_unlock (skpair);
@@ -2546,7 +2546,7 @@ static int unix_shutdown(struct socket *sock, int mode) ++mode;unix_state_lock (sk); - sk->sk_shutdown |= mode; +WRITE_ONCE (sk->sk_shutdown, sk->sk_shutdown | mode); other =unix_peer (sk);if (other)sock_hold (other);
@@ -2563,7 +2563,7 @@ static int unix_shutdown(struct socket *sock, int mode)if (mode&SEND_SHUTDOWN ) peer_mode |=RCV_SHUTDOWN ;unix_state_lock (other); - other->sk_shutdown |= peer_mode; +WRITE_ONCE (other->sk_shutdown, other->sk_shutdown | peer_mode);unix_state_unlock (other); other->sk_state_change (other);if (peer_mode ==SHUTDOWN_MASK )
@@ -2682,16 +2682,18 @@ static __poll_t unix_poll(struct file *file, struct socket *sock, poll_table *wa {struct sock *sk = sock->sk;__poll_t mask; +u8 shutdown;sock_poll_wait (file, sock, wait); mask =0 ; + shutdown =READ_ONCE (sk->sk_shutdown);/* exceptional events? */ if (sk->sk_err) mask |=EPOLLERR ; -if (sk->sk_shutdown ==SHUTDOWN_MASK ) +if (shutdown ==SHUTDOWN_MASK ) mask |=EPOLLHUP ; -if (sk->sk_shutdown &RCV_SHUTDOWN ) +if (shutdown &RCV_SHUTDOWN ) mask |=EPOLLRDHUP |EPOLLIN |EPOLLRDNORM ;/* readable? */
@@ -2719,18 +2721,20 @@ static __poll_t unix_dgram_poll(struct file *file, struct socket *sock,struct sock *sk = sock->sk, *other;unsigned int writable;__poll_t mask; +u8 shutdown;sock_poll_wait (file, sock, wait); mask =0 ; + shutdown =READ_ONCE (sk->sk_shutdown);/* exceptional events? */ if (sk->sk_err || !skb_queue_empty_lockless (&sk->sk_error_queue)) mask |=EPOLLERR | (sock_flag (sk,SOCK_SELECT_ERR_QUEUE ) ?EPOLLPRI :0 ); -if (sk->sk_shutdown &RCV_SHUTDOWN ) +if (shutdown &RCV_SHUTDOWN ) mask |=EPOLLRDHUP |EPOLLIN |EPOLLRDNORM ; -if (sk->sk_shutdown ==SHUTDOWN_MASK ) +if (shutdown ==SHUTDOWN_MASK ) mask |=EPOLLHUP ;/* readable? */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 15/161 fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
[ Upstream commit 81b21c0f0138ff5a499eafc3eb0578ad2a99622c ]
syzbot is hitting WARN_ON() in hfsplus_cat_{read,write}_inode(), for crafted filesystem image can contain bogus length. There conditions are not kernel bugs that can justify kernel to panic.
Message-Id: <[email protected]>
--- fs/hfsplus/inode.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
fs/hfsplus/inode.c +23 -5
@@ -497,7 +497,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)if (type ==HFSPLUS_FOLDER ) {struct hfsplus_cat_folder *folder = &entry.folder; -WARN_ON (fd->entrylength <sizeof (struct hfsplus_cat_folder )); +if (fd->entrylength <sizeof (struct hfsplus_cat_folder )) { +pr_err ("bad catalog folder entry\n" ); + res = -EIO ; + goto out; + }hfs_bnode_read (fd->bnode, &entry, fd->entryoffset,sizeof (struct hfsplus_cat_folder ));hfsplus_get_perms (inode, &folder->permissions,1 );
@@ -517,7 +521,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) }else if (type ==HFSPLUS_FILE ) {struct hfsplus_cat_file *file = &entry.file; -WARN_ON (fd->entrylength <sizeof (struct hfsplus_cat_file )); +if (fd->entrylength <sizeof (struct hfsplus_cat_file )) { +pr_err ("bad catalog file entry\n" ); + res = -EIO ; + goto out; + }hfs_bnode_read (fd->bnode, &entry, fd->entryoffset,sizeof (struct hfsplus_cat_file ));
@@ -548,6 +556,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)pr_err ("bad catalog entry used to create inode\n" ); res = -EIO ; } +out:return res; }
@@ -556,6 +565,7 @@ int hfsplus_cat_write_inode(struct inode *inode)struct inode *main_inode = inode;struct hfs_find_data fd;hfsplus_cat_entry entry; +int res =0 ;if (HFSPLUS_IS_RSRC (inode)) main_inode =HFSPLUS_I (inode)->rsrc_inode;
@@ -574,7 +584,11 @@ int hfsplus_cat_write_inode(struct inode *inode)if (S_ISDIR (main_inode->i_mode)) {struct hfsplus_cat_folder *folder = &entry.folder; -WARN_ON (fd.entrylength <sizeof (struct hfsplus_cat_folder )); +if (fd.entrylength <sizeof (struct hfsplus_cat_folder )) { +pr_err ("bad catalog folder entry\n" ); + res = -EIO ; + goto out; + }hfs_bnode_read (fd.bnode, &entry, fd.entryoffset,sizeof (struct hfsplus_cat_folder ));/* simple node checks? */
@@ -599,7 +613,11 @@ int hfsplus_cat_write_inode(struct inode *inode) }else {struct hfsplus_cat_file *file = &entry.file; -WARN_ON (fd.entrylength <sizeof (struct hfsplus_cat_file )); +if (fd.entrylength <sizeof (struct hfsplus_cat_file )) { +pr_err ("bad catalog file entry\n" ); + res = -EIO ; + goto out; + }hfs_bnode_read (fd.bnode, &entry, fd.entryoffset,sizeof (struct hfsplus_cat_file ));hfsplus_inode_write_fork (inode, &file->data_fork);
@@ -620,5 +638,5 @@ int hfsplus_cat_write_inode(struct inode *inode)set_bit (HFSPLUS_I_CAT_DIRTY , &HFSPLUS_I (inode)->flags); out:hfs_find_exit (&fd); -return 0 ; +return res; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 16/161 drm/amd/display: Use DC_LOG_DC in the trasform pixel function
In reply to Greg Kroah-HartmanFrom: Rodrigo Siqueira <[email protected]>
[ Upstream commit 7222f5841ff49709ca666b05ff336776e0664a20 ]
[Why & How]
DC now uses a new commit sequence which is more robust since it addresses cases where we need to reorganize pipes based on planes and other parameters. As a result, this new commit sequence reset the DC state by cleaning plane states and re-creating them accordingly with the need. For this reason, the dce_transform_set_pixel_storage_depth can be invoked after a plane state is destroyed and before its re-creation. In this situation and on DCE devices, DC will hit a condition that will trigger a dmesg log that looks like this:
Console: switching to colour frame buffer device 240x67
------------[ cut here ]------------ [..] Hardware name: System manufacturer System Product Name/PRIME X370-PRO, BIOS 5603 07/28/2020 RIP: 0010:dce_transform_set_pixel_storage_depth+0x3f8/0x480 [amdgpu] [..] RSP: 0018:ffffc9000202b850 EFLAGS: 00010293 RAX: ffffffffa081d100 RBX: ffff888110790000 RCX: 000000000000000c RDX: ffff888100bedbf8 RSI: 0000000000001a50 RDI: ffff88810463c900 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000007 R10: 0000000000000001 R11: 0000000000000f00 R12: ffff88810f500010 R13: ffff888100bedbf8 R14: ffff88810f515688 R15: 0000000000000000 FS: 00007ff0159249c0(0000) GS:ffff88840e940000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ff01528e550 CR3: 0000000002a10000 CR4: 00000000003506e0 Call Trace: <TASK> ? dm_write_reg_func+0x21/0x80 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] dc_stream_set_dither_option+0xfb/0x130 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] amdgpu_dm_crtc_configure_crc_source+0x10b/0x190 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] amdgpu_dm_atomic_commit_tail+0x20a8/0x2a90 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] ? free_unref_page_commit+0x98/0x170 ? free_unref_page+0xcc/0x150 commit_tail+0x94/0x120 drm_atomic_helper_commit+0x10f/0x140 drm_atomic_commit+0x94/0xc0 ? drm_plane_get_damage_clips.cold+0x1c/0x1c drm_client_modeset_commit_atomic+0x203/0x250 drm_client_modeset_commit_locked+0x56/0x150 drm_client_modeset_commit+0x21/0x40 drm_fb_helper_lastclose+0x42/0x70 amdgpu_driver_lastclose_kms+0xa/0x10 [amdgpu 340dadd3f7c8cf4be11cf0bdc850245e99abe0e8] drm_release+0xda/0x110 __fput+0x89/0x240 task_work_run+0x5c/0x90 do_exit+0x333/0xae0 do_group_exit+0x2d/0x90 __x64_sys_exit_group+0x14/0x20 do_syscall_64+0x5b/0x80 ? exit_to_user_mode_prepare+0x1e/0x140 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7ff016ceaca1 Code: Unable to access opcode bytes at RIP 0x7ff016ceac77. RSP: 002b:00007ffe7a2357e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 00007ff016e15a00 RCX: 00007ff016ceaca1 RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000000 RBP: 0000000000000000 R08: ffffffffffffff78 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007ff016e15a00 R13: 0000000000000000 R14: 00007ff016e1aee8 R15: 00007ff016e1af00 </TASK>
Since this issue only happens in a transition state on DC, this commit replace BREAK_TO_DEBUGGER with DC_LOG_DC.
--- drivers/gpu/drm/amd/display/dc/dce/dce_transform.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +2 -3
@@ -778,7 +778,7 @@ static void dce_transform_set_pixel_storage_depth( color_depth =COLOR_DEPTH_101010 ; pixel_depth =0 ; expan_mode =1 ; -BREAK_TO_DEBUGGER (); +DC_LOG_DC ("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead." , depth);break ; }
@@ -792,8 +792,7 @@ static void dce_transform_set_pixel_storage_depth(if (!(xfm_dce->lb_pixel_depth_supported & depth)) {/*we should use unsupported capabilities * unless it is required by w/a*/ -DC_LOG_WARNING ("%s: Capability not supported" , - __func__); +DC_LOG_DC ("%s: Capability not supported" , __func__); } }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 17/161 regmap: cache: Return error in cache sync operations for REGCACHE_NONE
In reply to Greg Kroah-HartmanFrom: Alexander Stein <[email protected]>
[ Upstream commit fd883d79e4dcd2417c2b80756f22a2ff03b0f6e0 ]
There is no sense in doing a cache sync on REGCACHE_NONE regmaps. Instead of panicking the kernel due to missing cache_ops, return an error to client driver.
--- drivers/base/regmap/regcache.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/base/regmap/regcache.c +6 -0
@@ -343,6 +343,9 @@ int regcache_sync(struct regmap *map)const char *name;bool bypass; +if (WARN_ON (map->cache_type ==REGCACHE_NONE )) +return -EINVAL ; +BUG_ON (!map->cache_ops); map->lock (map->lock_arg);
@@ -412,6 +415,9 @@ int regcache_sync_region(struct regmap *map, unsigned int min,const char *name;bool bypass; +if (WARN_ON (map->cache_type ==REGCACHE_NONE )) +return -EINVAL ; +BUG_ON (!map->cache_ops); map->lock (map->lock_arg);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 18/161 memstick: r592: Fix UAF bug in r592_remove due to race condition
In reply to Greg Kroah-HartmanFrom: Zheng Wang <[email protected]>
[ Upstream commit 63264422785021704c39b38f65a78ab9e4a186d7 ]
In r592_probe, dev->detect_timer was bound with r592_detect_timer. In r592_irq function, the timer function will be invoked by mod_timer.
If we remove the module which will call hantro_release to make cleanup, there may be a unfinished work. The possible sequence is as follows, which will cause a typical UAF bug.
Fix it by canceling the work before cleanup in r592_remove.
CPU0 CPU1
|r592_detect_timer
r592_remove |
memstick_free_host|
put_device; |
kfree(host); |
|
| queue_work
| &host->media_checker //use--- drivers/memstick/host/r592.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/memstick/host/r592.c +1 -1
@@ -828,7 +828,7 @@ static void r592_remove(struct pci_dev *pdev)/* Stop the processing thread. That ensures that we won't take any more requests */ kthread_stop (dev->io_thread); - +del_timer_sync (&dev->detect_timer);r592_enable_device (dev, false);while (!error && dev->req) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 19/161 firmware: arm_sdei: Fix sleep from invalid context BUG
In reply to Greg Kroah-HartmanFrom: Pierre Gondois <[email protected]>
[ Upstream commit d2c48b2387eb89e0bf2a2e06e30987cf410acad4 ]
Running a preempt-rt (v6.2-rc3-rt1) based kernel on an Ampere Altra triggers:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46
in_atomic(): 0, irqs_disabled(): 128, non_block: 0, pid: 24, name: cpuhp/0
preempt_count: 0, expected: 0
RCU nest depth: 0, expected: 0
3 locks held by cpuhp/0/24:
#0: ffffda30217c70d0 (cpu_hotplug_lock){++++}-{0:0}, at: cpuhp_thread_fun+0x5c/0x248
#1: ffffda30217c7120 (cpuhp_state-up){+.+.}-{0:0}, at: cpuhp_thread_fun+0x5c/0x248
#2: ffffda3021c711f0 (sdei_list_lock){....}-{3:3}, at: sdei_cpuhp_up+0x3c/0x130
irq event stamp: 36
hardirqs last enabled at (35): [<ffffda301e85b7bc>] finish_task_switch+0xb4/0x2b0
hardirqs last disabled at (36): [<ffffda301e812fec>] cpuhp_thread_fun+0x21c/0x248
softirqs last enabled at (0): [<ffffda301e80b184>] copy_process+0x63c/0x1ac0
softirqs last disabled at (0): [<0000000000000000>] 0x0
CPU: 0 PID: 24 Comm: cpuhp/0 Not tainted 5.19.0-rc3-rt5-[...]
Hardware name: WIWYNN Mt.Jade Server [...]
Call trace:
dump_backtrace+0x114/0x120
show_stack+0x20/0x70
dump_stack_lvl+0x9c/0xd8
dump_stack+0x18/0x34
__might_resched+0x188/0x228
rt_spin_lock+0x70/0x120
sdei_cpuhp_up+0x3c/0x130
cpuhp_invoke_callback+0x250/0xf08
cpuhp_thread_fun+0x120/0x248
smpboot_thread_fn+0x280/0x320
kthread+0x130/0x140
ret_from_fork+0x10/0x20sdei_cpuhp_up() is called in the STARTING hotplug section, which runs with interrupts disabled. Use a CPUHP_AP_ONLINE_DYN entry instead to execute the cpuhp cb later, with preemption enabled.
SDEI originally got its own cpuhp slot to allow interacting with perf. It got superseded by pNMI and this early slot is not relevant anymore. [1]
Some SDEI calls (e.g. SDEI_1_0_FN_SDEI_PE_MASK) take actions on the calling CPU. It is checked that preemption is disabled for them. _ONLINE cpuhp cb are executed in the 'per CPU hotplug thread'. Preemption is enabled in those threads, but their cpumask is limited to 1 CPU.
Move 'WARN_ON_ONCE(preemptible())' statements so that SDEI cpuhp cb don't trigger them.
Also add a check for the SDEI_1_0_FN_SDEI_PRIVATE_RESET SDEI call which acts on the calling CPU.
[1]:
https://lore.kernel.org/all/[email protected]/
--- drivers/firmware/arm_sdei.c | 37 ++++++++++++++++++++----------------- include/linux/cpuhotplug.h | 1 - 2 files changed, 20 insertions(+), 18 deletions(-)
drivers/firmware/arm_sdei.c +20 -17
@@ -44,6 +44,8 @@ static asmlinkage void (*sdei_firmware_call)(unsigned long function_id,/* entry point from firmware to arch asm code */ static unsigned long sdei_entry_point; +static int sdei_hp_state; +struct sdei_event {/* These three are protected by the sdei_list_lock */ struct list_head list;
@@ -305,8 +307,6 @@ int sdei_mask_local_cpu(void) {int err; -WARN_ON_ONCE (preemptible ()); - err =invoke_sdei_fn (SDEI_1_0_FN_SDEI_PE_MASK ,0 ,0 ,0 ,0 ,0 ,NULL );if (err && err != -EIO ) { pr_warn_once("failed to mask CPU[%u]: %d\n",
@@ -319,6 +319,7 @@ int sdei_mask_local_cpu(void)static void _ipi_mask_cpu (void *ignored) { +WARN_ON_ONCE (preemptible ());sdei_mask_local_cpu (); }
@@ -326,8 +327,6 @@ int sdei_unmask_local_cpu(void) {int err; -WARN_ON_ONCE (preemptible ()); - err =invoke_sdei_fn (SDEI_1_0_FN_SDEI_PE_UNMASK ,0 ,0 ,0 ,0 ,0 ,NULL );if (err && err != -EIO ) { pr_warn_once("failed to unmask CPU[%u]: %d\n",
@@ -340,6 +339,7 @@ int sdei_unmask_local_cpu(void)static void _ipi_unmask_cpu (void *ignored) { +WARN_ON_ONCE (preemptible ());sdei_unmask_local_cpu (); }
@@ -347,6 +347,8 @@ static void _ipi_private_reset(void *ignored) {int err; +WARN_ON_ONCE (preemptible ()); + err =invoke_sdei_fn (SDEI_1_0_FN_SDEI_PRIVATE_RESET ,0 ,0 ,0 ,0 ,0 ,NULL );if (err && err != -EIO )
@@ -393,8 +395,6 @@ static void _local_event_enable(void *data)int err;struct sdei_crosscall_args *arg = data; -WARN_ON_ONCE (preemptible ()); - err =sdei_api_event_enable (arg->event->event_num);sdei_cross_call_return (arg, err);
@@ -485,8 +485,6 @@ static void _local_event_unregister(void *data)int err;struct sdei_crosscall_args *arg = data; -WARN_ON_ONCE (preemptible ()); - err =sdei_api_event_unregister (arg->event->event_num);sdei_cross_call_return (arg, err);
@@ -575,8 +573,6 @@ static void _local_event_register(void *data)struct sdei_registered_event *reg;struct sdei_crosscall_args *arg = data; -WARN_ON (preemptible ()); - reg =per_cpu_ptr (arg->event->private_registered,smp_processor_id ()); err =sdei_api_event_register (arg->event->event_num, sdei_entry_point, reg,0 ,0 );
@@ -756,6 +752,8 @@ static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action, {int rv; +WARN_ON_ONCE (preemptible ()); +switch (action) {case CPU_PM_ENTER : rv =sdei_mask_local_cpu ();
@@ -804,7 +802,7 @@ static int sdei_device_freeze(struct device *dev)int err;/* unregister private events */ -cpuhp_remove_state (CPUHP_AP_ARM_SDEI_STARTING ); +cpuhp_remove_state (sdei_entry_point); err =sdei_unregister_shared ();if (err)
@@ -825,12 +823,15 @@ static int sdei_device_thaw(struct device *dev)return err; } - err =cpuhp_setup_state (CPUHP_AP_ARM_SDEI_STARTING ,"SDEI" , + err =cpuhp_setup_state (CPUHP_AP_ONLINE_DYN ,"SDEI" , &sdei_cpuhp_up, &sdei_cpuhp_down); -if (err) +if (err <0 ) {pr_warn ("Failed to re-register CPU hotplug notifier...\n" ); +return err; + } -return err; + sdei_hp_state = err; +return 0 ; }static int sdei_device_restore (struct device *dev)
@@ -862,7 +863,7 @@ static int sdei_reboot_notifier(struct notifier_block *nb, unsigned long action,* We are going to reset the interface, after this there is no point * doing work when we take CPUs offline. */ -cpuhp_remove_state (CPUHP_AP_ARM_SDEI_STARTING ); +cpuhp_remove_state (sdei_hp_state);sdei_platform_reset ();
@@ -1044,13 +1045,15 @@ static int sdei_probe(struct platform_device *pdev) goto remove_cpupm; } - err =cpuhp_setup_state (CPUHP_AP_ARM_SDEI_STARTING ,"SDEI" , + err =cpuhp_setup_state (CPUHP_AP_ONLINE_DYN ,"SDEI" , &sdei_cpuhp_up, &sdei_cpuhp_down); -if (err) { +if (err <0 ) {pr_warn ("Failed to register CPU hotplug notifier...\n" ); goto remove_reboot; } + sdei_hp_state = err; +return 0 ; remove_reboot:
include/linux/cpuhotplug.h +0 -1
@@ -111,7 +111,6 @@ enum cpuhp_state {CPUHP_AP_PERF_X86_CSTATE_STARTING ,CPUHP_AP_PERF_XTENSA_STARTING ,CPUHP_AP_MIPS_OP_LOONGSON3_STARTING , -CPUHP_AP_ARM_SDEI_STARTING ,CPUHP_AP_ARM_VFP_STARTING ,CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING , CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 20/161 ACPI: EC: Fix oops when removing custom query handlers
In reply to Greg Kroah-HartmanFrom: Armin Wolf <[email protected]>
[ Upstream commit e5b492c6bb900fcf9722e05f4a10924410e170c1 ]
When removing custom query handlers, the handler might still be used inside the EC query workqueue, causing a kernel oops if the module holding the callback function was already unloaded.
Fix this by flushing the EC query workqueue when removing custom query handlers.
Tested on a Acer Travelmate 4002WLMi
--- drivers/acpi/ec.c | 1 + 1 file changed, 1 insertion(+)
drivers/acpi/ec.c +1 -0
@@ -1118,6 +1118,7 @@ static void acpi_ec_remove_query_handlers(struct acpi_ec *ec,void acpi_ec_remove_query_handler (struct acpi_ec *ec,u8 query_bit) {acpi_ec_remove_query_handlers (ec, false, query_bit); +flush_workqueue (ec_query_wq); }EXPORT_SYMBOL_GPL (acpi_ec_remove_query_handler);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 21/161 drm/tegra: Avoid potential 32-bit integer overflow
In reply to Greg Kroah-HartmanFrom: Nur Hussein <[email protected]>
[ Upstream commit 2429b3c529da29d4277d519bd66d034842dcd70c ]
In tegra_sor_compute_config(), the 32-bit value mode->clock is multiplied by 1000, and assigned to the u64 variable pclk. We can avoid a potential 32-bit integer overflow by casting mode->clock to u64 before we do the arithmetic and assignment.
--- drivers/gpu/drm/tegra/sor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/tegra/sor.c +1 -1
@@ -906,7 +906,7 @@ static int tegra_sor_compute_config(struct tegra_sor *sor, struct drm_dp_link *link) {const u64 f =100000 , link_rate = link->rate *1000 ; -const u64 pclk = mode->clock *1000 ; +const u64 pclk = (u64 )mode->clock *1000 ;u64 input, output, watermark, num;struct tegra_sor_params params;u32 num_syms_per_line;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 22/161 ACPICA: Avoid undefined behavior: applying zero offset to null pointer
In reply to Greg Kroah-HartmanFrom: Tamir Duberstein <[email protected]>
[ Upstream commit 05bb0167c80b8f93c6a4e0451b7da9b96db990c2 ]
ACPICA commit 770653e3ba67c30a629ca7d12e352d83c2541b1e
Before this change we see the following UBSAN stack trace in Fuchsia:
#0 0x000021e4213b3302 in acpi_ds_init_aml_walk(struct acpi_walk_state*, union acpi_parse_object*, struct acpi_namespace_node*, u8*, u32, struct acpi_evaluate_info*, u8) ../../third_party/acpica/source/components/dispatcher/dswstate.c:682 <platform-bus-x86.so>+0x233302 #1.2 0x000020d0f660777f in ubsan_get_stack_trace() compiler-rt/lib/ubsan/ubsan_diag.cpp:41 <libclang_rt.asan.so>+0x3d77f #1.1 0x000020d0f660777f in maybe_print_stack_trace() compiler-rt/lib/ubsan/ubsan_diag.cpp:51 <libclang_rt.asan.so>+0x3d77f #1 0x000020d0f660777f in ~scoped_report() compiler-rt/lib/ubsan/ubsan_diag.cpp:387 <libclang_rt.asan.so>+0x3d77f #2 0x000020d0f660b96d in handlepointer_overflow_impl() compiler-rt/lib/ubsan/ubsan_handlers.cpp:809 <libclang_rt.asan.so>+0x4196d #3 0x000020d0f660b50d in compiler-rt/lib/ubsan/ubsan_handlers.cpp:815 <libclang_rt.asan.so>+0x4150d #4 0x000021e4213b3302 in acpi_ds_init_aml_walk(struct acpi_walk_state*, union acpi_parse_object*, struct acpi_namespace_node*, u8*, u32, struct acpi_evaluate_info*, u8) ../../third_party/acpica/source/components/dispatcher/dswstate.c:682 <platform-bus-x86.so>+0x233302 #5 0x000021e4213e2369 in acpi_ds_call_control_method(struct acpi_thread_state*, struct acpi_walk_state*, union acpi_parse_object*) ../../third_party/acpica/source/components/dispatcher/dsmethod.c:605 <platform-bus-x86.so>+0x262369 #6 0x000021e421437fac in acpi_ps_parse_aml(struct acpi_walk_state*) ../../third_party/acpica/source/components/parser/psparse.c:550 <platform-bus-x86.so>+0x2b7fac #7 0x000021e4214464d2 in acpi_ps_execute_method(struct acpi_evaluate_info*) ../../third_party/acpica/source/components/parser/psxface.c:244 <platform-bus-x86.so>+0x2c64d2 #8 0x000021e4213aa052 in acpi_ns_evaluate(struct acpi_evaluate_info*) ../../third_party/acpica/source/components/namespace/nseval.c:250 <platform-bus-x86.so>+0x22a052 #9 0x000021e421413dd8 in acpi_ns_init_one_device(acpi_handle, u32, void*, void**) ../../third_party/acpica/source/components/namespace/nsinit.c:735 <platform-bus-x86.so>+0x293dd8 #10 0x000021e421429e98 in acpi_ns_walk_namespace(acpi_object_type, acpi_handle, u32, u32, acpi_walk_callback, acpi_walk_callback, void*, void**) ../../third_party/acpica/source/components/namespace/nswalk.c:298 <platform-bus-x86.so>+0x2a9e98 #11 0x000021e4214131ac in acpi_ns_initialize_devices(u32) ../../third_party/acpica/source/components/namespace/nsinit.c:268 <platform-bus-x86.so>+0x2931ac #12 0x000021e42147c40d in acpi_initialize_objects(u32) ../../third_party/acpica/source/components/utilities/utxfinit.c:304 <platform-bus-x86.so>+0x2fc40d #13 0x000021e42126d603 in acpi::acpi_impl::initialize_acpi(acpi::acpi_impl*) ../../src/devices/board/lib/acpi/acpi-impl.cc:224 <platform-bus-x86.so>+0xed603
Add a simple check that avoids incrementing a pointer by zero, but otherwise behaves as before. Note that our findings are against ACPICA 20221020, but the same code exists on master.
--- drivers/acpi/acpica/dswstate.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/acpi/acpica/dswstate.c +8 -3
@@ -576,9 +576,14 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state,ACPI_FUNCTION_TRACE (ds_init_aml_walk); walk_state->parser_state.aml = - walk_state->parser_state.aml_start = aml_start; - walk_state->parser_state.aml_end = - walk_state->parser_state.pkg_end = aml_start + aml_length; + walk_state->parser_state.aml_start = + walk_state->parser_state.aml_end = + walk_state->parser_state.pkg_end = aml_start; +/* Avoid undefined behavior: applying zero offset to null pointer */ +if (aml_length !=0 ) { + walk_state->parser_state.aml_end += aml_length; + walk_state->parser_state.pkg_end += aml_length; + }/* The next_op of the next_walk will be the beginning of the method */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 23/161 ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in acpi_db_display_objects
In reply to Greg Kroah-HartmanFrom: void0red <[email protected]>
[ Upstream commit ae5a0eccc85fc960834dd66e3befc2728284b86c ]
ACPICA commit 0d5f467d6a0ba852ea3aad68663cbcbd43300fd4
ACPI_ALLOCATE_ZEROED may fails, object_info might be null and will cause null pointer dereference later.
--- drivers/acpi/acpica/dbnames.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/acpi/acpica/dbnames.c +3 -0
@@ -571,6 +571,9 @@ acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg) object_info =ACPI_ALLOCATE_ZEROED (sizeof (struct acpi_object_info )); +if (!object_info) +return (AE_NO_MEMORY ); +/* Walk the namespace from the root */ (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 24/161 wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex
In reply to Greg Kroah-HartmanFrom: Hector Martin <[email protected]>
[ Upstream commit 89b89e52153fda2733562776c7c9d9d3ebf8dd6d ]
Apparently the hex passphrase mechanism does not work on newer chips/firmware (e.g. BCM4387). It seems there was a simple way of passing it in binary all along, so use that and avoid the hexification.
OpenBSD has been doing it like this from the beginning, so this should work on all chips.
Also clear the structure before setting the PMK. This was leaking uninitialized stack contents to the device.
--- .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +7 -6
@@ -1269,13 +1269,14 @@ static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) {struct brcmf_pub *drvr = ifp->drvr;struct brcmf_wsec_pmk_le pmk; -int i, err; +int err; + +memset (&pmk,0 ,sizeof (pmk)); -/* convert to firmware key format */ - pmk.key_len =cpu_to_le16 (pmk_len <<1 ); - pmk.flags =cpu_to_le16 (BRCMF_WSEC_PASSPHRASE ); -for (i =0 ; i < pmk_len; i++) -snprintf (&pmk.key[2 * i],3 ,"%02x" , pmk_data[i]); +/* pass pmk directly */ + pmk.key_len =cpu_to_le16 (pmk_len); + pmk.flags =cpu_to_le16 (0 ); +memcpy (pmk.key, pmk_data, pmk_len);/* store psk in firmware */ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 25/161 ext2: Check block size validity during mount
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit 62aeb94433fcec80241754b70d0d1836d5926b0a ]
Check that log of block size stored in the superblock has sensible value. Otherwise the shift computing the block size can overflow leading to undefined behavior.
--- fs/ext2/ext2.h | 1 + fs/ext2/super.c | 7 +++++++ 2 files changed, 8 insertions(+)
fs/ext2/ext2.h +1 -0
@@ -177,6 +177,7 @@ static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb)#define EXT2_MIN_BLOCK_SIZE 1024#define EXT2_MAX_BLOCK_SIZE 4096#define EXT2_MIN_BLOCK_LOG_SIZE 10 +#define EXT2_MAX_BLOCK_LOG_SIZE 16#define EXT2_BLOCK_SIZE (s) ((s)->s_blocksize)#define EXT2_ADDR_PER_BLOCK (s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))#define EXT2_BLOCK_SIZE_BITS (s) ((s)->s_blocksize_bits)
fs/ext2/super.c +7 -0
@@ -967,6 +967,13 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount; } +if (le32_to_cpu (es->s_log_block_size) > + (EXT2_MAX_BLOCK_LOG_SIZE -BLOCK_SIZE_BITS )) { +ext2_msg (sb,KERN_ERR , +"Invalid log block size: %u" , +le32_to_cpu (es->s_log_block_size)); + goto failed_mount; + } blocksize =BLOCK_SIZE <<le32_to_cpu (sbi->s_es->s_log_block_size);if (test_opt (sb,DAX )) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 26/161 scsi: lpfc: Prevent lpfc_debugfs_lockstat_write() buffer overflow
In reply to Greg Kroah-HartmanFrom: Justin Tee <[email protected]>
[ Upstream commit c6087b82a9146826564a55c5ca0164cac40348f5 ]
A static code analysis tool flagged the possibility of buffer overflow when using copy_from_user() for a debugfs entry.
Currently, it is possible that copy_from_user() copies more bytes than what would fit in the mybuf char array. Add a min() restriction check between sizeof(mybuf) - 1 and nbytes passed from the userspace buffer to protect against buffer overflow.
--- drivers/scsi/lpfc/lpfc_debugfs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/scsi/lpfc/lpfc_debugfs.c +5 -2
@@ -2046,6 +2046,7 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,char mybuf[64 ];char *pbuf;int i; +size_t bsize;/* Protect copy from user */ if (!access_ok (buf, nbytes))
@@ -2053,7 +2054,9 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf,memset (mybuf,0 ,sizeof (mybuf)); -if (copy_from_user (mybuf, buf, nbytes)) + bsize =min (nbytes, (sizeof (mybuf) -1 )); + +if (copy_from_user (mybuf, buf, bsize))return -EFAULT ; pbuf = &mybuf[0 ];
@@ -2074,7 +2077,7 @@ lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf, qp->lock_conflict.wq_access = 0; } } -return nbytes; +return bsize; }#endif
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 27/161 net: pasemi: Fix return type of pasemi_mac_start_tx()
In reply to Greg Kroah-HartmanFrom: Nathan Chancellor <[email protected]>
[ Upstream commit c8384d4a51e7cb0e6587f3143f29099f202c5de1 ]
With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG), indirect call targets are validated against the expected function pointer prototype to make sure the call target is valid to help mitigate ROP attacks. If they are not identical, there is a failure at run time, which manifests as either a kernel panic or thread getting killed. A warning in clang aims to catch these at compile time, which reveals:
drivers/net/ethernet/pasemi/pasemi_mac.c:1665:21: error: incompatible function pointer types initializing 'netdev_tx_t (*)(struct sk_buff *, struct net_device *)' (aka 'enum netdev_tx (*)(struct sk_buff *, struct net_device *)') with an expression of type 'int (struct sk_buff *, struct net_device *)' [-Werror,-Wincompatible-function-pointer-types-strict]
.ndo_start_xmit = pasemi_mac_start_tx,
^~~~~~~~~~~~~~~~~~~
1 error generated.
->ndo_start_xmit() in 'struct net_device_ops' expects a return type of 'netdev_tx_t', not 'int'. Adjust the return type of pasemi_mac_start_tx() to match the prototype's to resolve the warning. While PowerPC does not currently implement support for kCFI, it could in the future, which means this warning becomes a fatal CFI failure at run time.
--- drivers/net/ethernet/pasemi/pasemi_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/pasemi/pasemi_mac.c +1 -1
@@ -1423,7 +1423,7 @@ static void pasemi_mac_queue_csdesc(const struct sk_buff *skb,write_dma_reg (PAS_DMA_TXCHAN_INCR (txring->chan.chno),2 ); } -static int pasemi_mac_start_tx (struct sk_buff *skb,struct net_device *dev) +static netdev_tx_t pasemi_mac_start_tx (struct sk_buff *skb,struct net_device *dev) {struct pasemi_mac *const mac =netdev_priv (dev);struct pasemi_mac_txring *const txring =tx_ring (mac);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 28/161 net: Catch invalid index in XPS mapping
In reply to Greg Kroah-HartmanFrom: Nick Child <[email protected]>
[ Upstream commit 5dd0dfd55baec0742ba8f5625a0dd064aca7db16 ]
When setting the XPS value of a TX queue, warn the user once if the index of the queue is greater than the number of allocated TX queues.
Previously, this scenario went uncaught. In the best case, it resulted in unnecessary allocations. In the worst case, it resulted in out-of-bounds memory references through calls to netdev_get_tx_queue( dev, index). Therefore, it is important to inform the user but not worth returning an error and risk downing the netdevice.
--- net/core/dev.c | 2 ++ 1 file changed, 2 insertions(+)
net/core/dev.c +2 -0
@@ -2244,6 +2244,8 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,bool active = false;unsigned int nr_ids; +WARN_ON_ONCE (index >= dev->num_tx_queues); +if (dev->num_tc) {/* Do not allow XPS on subordinate device directly */ num_tc = dev->num_tc;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 29/161 scsi: target: iscsit: Free cmds before session free
In reply to Greg Kroah-HartmanFrom: Dmitry Bogdanov <[email protected]>
[ Upstream commit d8990b5a4d065f38f35d69bcd627ec5a7f8330ca ]
Commands from recovery entries are freed after session has been closed. That leads to use-after-free at command free or NPE with such call trace:
Time2Retain timer expired for SID: 1, cleaning up iSCSI session.
BUG: kernel NULL pointer dereference, address: 0000000000000140 RIP: 0010:sbitmap_queue_clear+0x3a/0xa0 Call Trace: target_release_cmd_kref+0xd1/0x1f0 [target_core_mod] transport_generic_free_cmd+0xd1/0x180 [target_core_mod] iscsit_free_cmd+0x53/0xd0 [iscsi_target_mod] iscsit_free_connection_recovery_entries+0x29d/0x320 [iscsi_target_mod] iscsit_close_session+0x13a/0x140 [iscsi_target_mod] iscsit_check_post_dataout+0x440/0x440 [iscsi_target_mod] call_timer_fn+0x24/0x140
Move cleanup of recovery enrties to before session freeing.
--- drivers/target/iscsi/iscsi_target.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/target/iscsi/iscsi_target.c +3 -3
@@ -4385,6 +4385,9 @@ int iscsit_close_session(struct iscsi_session *sess)iscsit_stop_time2retain_timer (sess);spin_unlock_bh (&se_tpg->session_lock); +if (sess->sess_ops->ErrorRecoveryLevel ==2 ) +iscsit_free_connection_recovery_entries (sess); +/* * transport_deregister_session_configfs() will clear the * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
@@ -4413,9 +4416,6 @@ int iscsit_close_session(struct iscsi_session *sess)transport_deregister_session (sess->se_sess); -if (sess->sess_ops->ErrorRecoveryLevel ==2 ) -iscsit_free_connection_recovery_entries (sess); -iscsit_free_all_ooo_cmdsns (sess);spin_lock_bh (&se_tpg->session_lock);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 30/161 lib: cpu_rmap: Avoid use after free on rmap->obj array entries
In reply to Greg Kroah-HartmanFrom: Eli Cohen <[email protected]>
[ Upstream commit 4e0473f1060aa49621d40a113afde24818101d37 ]
When calling irq_set_affinity_notifier() with NULL at the notify argument, it will cause freeing of the glue pointer in the corresponding array entry but will leave the pointer in the array. A subsequent call to free_irq_cpu_rmap() will try to free this entry again leading to possible use after free.
Fix that by setting NULL to the array entry and checking that we have non-zero at the array entry when iterating over the array in free_irq_cpu_rmap().
The current code does not suffer from this since there are no cases where irq_set_affinity_notifier(irq, NULL) (note the NULL passed for the notify arg) is called, followed by a call to free_irq_cpu_rmap() so we don't hit and issue. Subsequent patches in this series excersize this flow, hence the required fix.
--- lib/cpu_rmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
lib/cpu_rmap.c +4 -1
@@ -232,7 +232,8 @@ void free_irq_cpu_rmap(struct cpu_rmap *rmap)for (index =0 ; index < rmap->used; index++) { glue = rmap->obj[index]; -irq_set_affinity_notifier (glue->notify.irq,NULL ); +if (glue) +irq_set_affinity_notifier (glue->notify.irq,NULL ); }cpu_rmap_put (rmap);
@@ -268,6 +269,7 @@ static void irq_cpu_rmap_release(struct kref *ref) container_of(ref, struct irq_glue, notify.kref);cpu_rmap_put (glue->rmap); + glue->rmap->obj[glue->index] =NULL ;kfree (glue); }
@@ -297,6 +299,7 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) rc =irq_set_affinity_notifier (irq, &glue->notify);if (rc) {cpu_rmap_put (glue->rmap); + rmap->obj[glue->index] =NULL ;kfree (glue); }return rc;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 31/161 scsi: message: mptlan: Fix use after free bug in mptlan_remove() due to race condition
In reply to Greg Kroah-HartmanFrom: Zheng Wang <[email protected]>
[ Upstream commit f486893288f3e9b171b836f43853a6426515d800 ]
mptlan_probe() calls mpt_register_lan_device() which initializes the &priv->post_buckets_task workqueue. A call to mpt_lan_wake_post_buckets_task() will subsequently start the work.
During driver unload in mptlan_remove() the following race may occur:
CPU0 CPU1
|mpt_lan_post_receive_buckets_work()
mptlan_remove() |
free_netdev() |
kfree(dev); |
|
| dev->mtu
| //useFix this by finishing the work prior to cleaning up in mptlan_remove().
[mkp: we really should remove mptlan instead of attempting to fix it]
--- drivers/message/fusion/mptlan.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/message/fusion/mptlan.c +2 -0
@@ -1430,7 +1430,9 @@ mptlan_remove(struct pci_dev *pdev) {MPT_ADAPTER *ioc =pci_get_drvdata (pdev);struct net_device *dev = ioc->netdev; +struct mpt_lan_priv *priv =netdev_priv (dev); +cancel_delayed_work_sync (&priv->post_buckets_task);if (dev !=NULL ) {unregister_netdev (dev);free_netdev (dev);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 32/161 gfs2: Fix inode height consistency check
In reply to Greg Kroah-HartmanFrom: Andreas Gruenbacher <[email protected]>
[ Upstream commit cfcdb5bad34f600aed7613c3c1a5e618111f77b7 ]
The maximum allowed height of an inode's metadata tree depends on the filesystem block size; it is lower for bigger-block filesystems. When reading in an inode, make sure that the height doesn't exceed the maximum allowed height.
Arrays like sd_heightsize are sized to be big enough for any filesystem block size; they will often be slightly bigger than what's needed for a specific filesystem.
--- fs/gfs2/glops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/gfs2/glops.c +2 -1
@@ -362,6 +362,7 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl)static int gfs2_dinode_in (struct gfs2_inode *ip,const void *buf) { +struct gfs2_sbd *sdp =GFS2_SB (&ip->i_inode);const struct gfs2_dinode *str = buf;struct timespec64 atime;u16 height, depth;
@@ -401,7 +402,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ gfs2_set_inode_flags (&ip->i_inode); height =be16_to_cpu (str->di_height); -if (unlikely (height >GFS2_MAX_META_HEIGHT )) +if (unlikely (height > sdp->sd_max_height)) goto corrupt; ip->i_height = (u8 )height;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 33/161 ext4: set goal start correctly in ext4_mb_normalize_request
In reply to Greg Kroah-HartmanFrom: Kemeng Shi <[email protected]>
[ Upstream commit b07ffe6927c75d99af534d685282ea188d9f71a6 ]
We need to set ac_g_ex to notify the goal start used in ext4_mb_find_by_goal. Set ac_g_ex instead of ac_f_ex in ext4_mb_normalize_request.
Besides we should assure goal start is in range [first_data_block, blocks_count) as ext4_mb_initialize_context does.
[ Added a check to make sure size is less than ar->pright; otherwise
we could end up passing an underflowed value of ar->pright - size to ext4_get_group_no_and_offset(), which will trigger a BUG_ON later on.
- TYT ]
--- fs/ext4/mballoc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
fs/ext4/mballoc.c +10 -6
@@ -3091,6 +3091,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, struct ext4_allocation_request *ar) {struct ext4_sb_info *sbi =EXT4_SB (ac->ac_sb); +struct ext4_super_block *es = sbi->s_es;int bsbits, max;ext4_lblk_t end;loff_t size, start_off;
@@ -3271,18 +3272,21 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, ac->ac_g_ex.fe_len =EXT4_NUM_B2C (sbi, size);/* define goal start in order to merge */ -if (ar->pright && (ar->lright == (start + size))) { +if (ar->pright && (ar->lright == (start + size)) && + ar->pright >= size && + ar->pright - size >=le32_to_cpu (es->s_first_data_block)) {/* merge to the right */ ext4_get_group_no_and_offset (ac->ac_sb, ar->pright - size, - &ac->ac_f_ex.fe_group, - &ac->ac_f_ex.fe_start); + &ac->ac_g_ex.fe_group, + &ac->ac_g_ex.fe_start); ac->ac_flags |=EXT4_MB_HINT_TRY_GOAL ; } -if (ar->pleft && (ar->lleft +1 == start)) { +if (ar->pleft && (ar->lleft +1 == start) && + ar->pleft +1 <ext4_blocks_count (es)) {/* merge to the left */ ext4_get_group_no_and_offset (ac->ac_sb, ar->pleft +1 , - &ac->ac_f_ex.fe_group, - &ac->ac_f_ex.fe_start); + &ac->ac_g_ex.fe_group, + &ac->ac_g_ex.fe_start); ac->ac_flags |=EXT4_MB_HINT_TRY_GOAL ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 34/161 ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa()
In reply to Greg Kroah-HartmanFrom: Ojaswin Mujoo <[email protected]>
[ Upstream commit 93cdf49f6eca5e23f6546b8f28457b2e6a6961d9 ]
When the length of best extent found is less than the length of goal extent we need to make sure that the best extent atleast covers the start of the original request. This is done by adjusting the ac_b_ex.fe_logical (logical start) of the extent.
While doing so, the current logic sometimes results in the best extent's logical range overflowing the goal extent. Since this best extent is later added to the inode preallocation list, we have a possibility of introducing overlapping preallocations. This is discussed in detail here [1].
As per Jan's suggestion, to fix this, replace the existing logic with the below logic for adjusting best extent as it keeps fragmentation in check while ensuring logical range of best extent doesn't overflow out of goal extent:
1. Check if best extent can be kept at end of goal range and still cover original start.
2. Else, check if best extent can be kept at start of goal range and still cover original start.
3. Else, keep the best extent at start of original request.
Also, add a few extra BUG_ONs that might help catch errors faster.
[1] https://lore.kernel.org/r/[email protected]
--- fs/ext4/mballoc.c | 49 ++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-)
fs/ext4/mballoc.c +31 -18
@@ -3378,6 +3378,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,BUG_ON (start < pa->pa_pstart);BUG_ON (end > pa->pa_pstart +EXT4_C2B (sbi, pa->pa_len));BUG_ON (pa->pa_free < len); +BUG_ON (ac->ac_b_ex.fe_len <=0 ); pa->pa_free -= len;mb_debug (1 ,"use %llu/%u from inode pa %p\n" , start, len, pa);
@@ -3682,10 +3683,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)return -ENOMEM ;if (ac->ac_b_ex.fe_len < ac->ac_g_ex.fe_len) { -int winl; -int wins; -int win; -int offs; +int new_bex_start; +int new_bex_end;/* we can't allocate as much as normalizer wants. * so, found space must get proper lstart
@@ -3693,26 +3692,40 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)BUG_ON (ac->ac_g_ex.fe_logical > ac->ac_o_ex.fe_logical);BUG_ON (ac->ac_g_ex.fe_len < ac->ac_o_ex.fe_len); -/* we're limited by original request in that -* logical block must be covered any way -* winl is window we can move our chunk within */ - winl = ac->ac_o_ex.fe_logical - ac->ac_g_ex.fe_logical; +/* +* Use the below logic for adjusting best extent as it keeps +* fragmentation in check while ensuring logical range of best +* extent doesn't overflow out of goal extent: +* +* 1. Check if best ex can be kept at end of goal and still +* cover original start +* 2. Else, check if best ex can be kept at start of goal and +* still cover original start +* 3. Else, keep the best ex at start of original request. +*/ + new_bex_end = ac->ac_g_ex.fe_logical + +EXT4_C2B (sbi, ac->ac_g_ex.fe_len); + new_bex_start = new_bex_end -EXT4_C2B (sbi, ac->ac_b_ex.fe_len); +if (ac->ac_o_ex.fe_logical >= new_bex_start) + goto adjust_bex; -/* also, we should cover whole original request */ - wins =EXT4_C2B (sbi, ac->ac_b_ex.fe_len - ac->ac_o_ex.fe_len); + new_bex_start = ac->ac_g_ex.fe_logical; + new_bex_end = + new_bex_start +EXT4_C2B (sbi, ac->ac_b_ex.fe_len); +if (ac->ac_o_ex.fe_logical < new_bex_end) + goto adjust_bex; -/* the smallest one defines real window */ - win =min (winl, wins); + new_bex_start = ac->ac_o_ex.fe_logical; + new_bex_end = + new_bex_start +EXT4_C2B (sbi, ac->ac_b_ex.fe_len); - offs = ac->ac_o_ex.fe_logical % -EXT4_C2B (sbi, ac->ac_b_ex.fe_len); -if (offs && offs < win) - win = offs; +adjust_bex: + ac->ac_b_ex.fe_logical = new_bex_start; - ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - -EXT4_NUM_B2C (sbi, win);BUG_ON (ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);BUG_ON (ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len); +BUG_ON (new_bex_end > (ac->ac_g_ex.fe_logical + +EXT4_C2B (sbi, ac->ac_g_ex.fe_len))); }/* preallocation can change ac_b_ex, thus we store actually
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 35/161 f2fs: fix to drop all dirty pages during umount() if cp_error is set
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
[ Upstream commit c9b3649a934d131151111354bcbb638076f03a30 ]
xfstest generic/361 reports a bug as below:
f2fs_bug_on(sbi, sbi->fsync_node_num);
kernel BUG at fs/f2fs/super.c:1627!
RIP: 0010:f2fs_put_super+0x3a8/0x3b0 Call Trace: generic_shutdown_super+0x8c/0x1b0 kill_block_super+0x2b/0x60 kill_f2fs_super+0x87/0x110 deactivate_locked_super+0x39/0x80 deactivate_super+0x46/0x50 cleanup_mnt+0x109/0x170 __cleanup_mnt+0x16/0x20 task_work_run+0x65/0xa0 exit_to_user_mode_prepare+0x175/0x190 syscall_exit_to_user_mode+0x25/0x50 do_syscall_64+0x4c/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc
During umount(), if cp_error is set, f2fs_wait_on_all_pages() should not stop waiting all F2FS_WB_CP_DATA pages to be writebacked, otherwise, fsync_node_num can be non-zero after f2fs_wait_on_all_pages() causing this bug.
In this case, to avoid deadloop in f2fs_wait_on_all_pages(), it needs to drop all dirty pages rather than redirtying them.
--- fs/f2fs/checkpoint.c | 12 ++++++++++-- fs/f2fs/data.c | 3 ++- 2 files changed, 12 insertions(+), 3 deletions(-)
fs/f2fs/checkpoint.c +10 -2
@@ -306,8 +306,15 @@ static int __f2fs_write_meta_page(struct page *page,trace_f2fs_writepage (page,META ); -if (unlikely (f2fs_cp_error (sbi))) +if (unlikely (f2fs_cp_error (sbi))) { +if (is_sbi_flag_set (sbi,SBI_IS_CLOSE )) { +ClearPageUptodate (page); +dec_page_count (sbi,F2FS_DIRTY_META ); +unlock_page (page); +return 0 ; + } goto redirty_out; + }if (unlikely (is_sbi_flag_set (sbi,SBI_POR_DOING ))) goto redirty_out;if (wbc->for_reclaim && page->index <GET_SUM_BLOCK (sbi,0 ))
@@ -1277,7 +1284,8 @@ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type)if (!get_pages (sbi, type))break ; -if (unlikely (f2fs_cp_error (sbi))) +if (unlikely (f2fs_cp_error (sbi) && + !is_sbi_flag_set (sbi,SBI_IS_CLOSE )))break ;io_schedule_timeout (HZ /50 );
fs/f2fs/data.c +2 -1
@@ -2130,7 +2130,8 @@ static int __write_data_page(struct page *page, bool *submitted,* don't drop any dirty dentry pages for keeping lastest * directory structure. */ -if (S_ISDIR (inode->i_mode)) +if (S_ISDIR (inode->i_mode) && + !is_sbi_flag_set (sbi,SBI_IS_CLOSE )) goto redirty_out; goto out; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 36/161 samples/bpf: Fix fout leak in hbms run_bpf_prog
In reply to Greg Kroah-HartmanFrom: Hao Zeng <[email protected]>
[ Upstream commit 23acb14af1914010dd0aae1bbb7fab28bf518b8e ]
Fix fout being fopen'ed but then not subsequently fclose'd. In the affected branch, fout is otherwise going out of scope.
--- samples/bpf/hbm.c | 1 + 1 file changed, 1 insertion(+)
samples/bpf/hbm.c +1 -0
@@ -307,6 +307,7 @@ static int run_bpf_prog(char *prog, int cg_id) fout =fopen (fname,"w" );fprintf (fout,"id:%d\n" , cg_id);fprintf (fout,"ERROR: Could not lookup queue_stats\n" ); +fclose (fout); }else if (stats_flag && qstats.lastPacketTime > qstats.firstPacketTime) { long long delta_us = (qstats.lastPacketTime -
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 37/161 wifi: iwlwifi: pcie: fix possible NULL pointer dereference
In reply to Greg Kroah-HartmanFrom: Daniel Gabay <[email protected]>
[ Upstream commit b655b9a9f8467684cfa8906713d33b71ea8c8f54 ]
It is possible that iwl_pci_probe() will fail and free the trans, then afterwards iwl_pci_remove() will be called and crash by trying to access trans which is already freed, fix it.
iwlwifi 0000:01:00.0: Detected crf-id 0xa5a5a5a2, cnv-id 0xa5a5a5a2
wfpm id 0xa5a5a5a2 iwlwifi 0000:01:00.0: Can't find a correct rfid for crf id 0x5a2 ... BUG: kernel NULL pointer dereference, address: 0000000000000028 ... RIP: 0010:iwl_pci_remove+0x12/0x30 [iwlwifi] pci_device_remove+0x3e/0xb0 device_release_driver_internal+0x103/0x1f0 driver_detach+0x4c/0x90 bus_remove_driver+0x5c/0xd0 driver_unregister+0x31/0x50 pci_unregister_driver+0x40/0x90 iwl_pci_unregister_driver+0x15/0x20 [iwlwifi] __exit_compat+0x9/0x98 [iwlwifi] __x64_sys_delete_module+0x147/0x260
--- drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/drv.c +3 -0
@@ -1173,6 +1173,9 @@ static void iwl_pci_remove(struct pci_dev *pdev) {struct iwl_trans *trans =pci_get_drvdata (pdev); +if (!trans) +return ; +iwl_drv_stop (trans->drv);iwl_trans_pcie_free (trans);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 38/161 wifi: iwlwifi: pcie: Fix integer overflow in iwl_write_to_user_buf
In reply to Greg Kroah-HartmanFrom: Hyunwoo Kim <[email protected]>
[ Upstream commit 58d1b717879bfeabe09b35e41ad667c79933eb2e ]
An integer overflow occurs in the iwl_write_to_user_buf() function, which is called by the iwl_dbgfs_monitor_data_read() function.
static bool iwl_write_to_user_buf(char __user *user_buf, ssize_t count,
void *buf, ssize_t *size, ssize_t *bytes_copied)
{
int buf_size_left = count - *bytes_copied;
buf_size_left = buf_size_left - (buf_size_left % sizeof(u32));
if (*size > buf_size_left)
*size = buf_size_left;If the user passes a SIZE_MAX value to the "ssize_t count" parameter, the ssize_t count parameter is assigned to "int buf_size_left". Then compare "*size" with "buf_size_left" . Here, "buf_size_left" is a negative number, so "*size" is assigned "buf_size_left" and goes into the third argument of the copy_to_user function, causing a heap overflow.
This is not a security vulnerability because iwl_dbgfs_monitor_data_read() is a debugfs operation with 0400 privileges.
--- drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/pcie/trans.c +1 -1
@@ -2832,7 +2832,7 @@ static bool iwl_write_to_user_buf(char __user *user_buf, ssize_t count, void *buf, ssize_t *size, ssize_t *bytes_copied) { - int buf_size_left = count - *bytes_copied; + ssize_t buf_size_left = count - *bytes_copied; buf_size_left = buf_size_left - (buf_size_left %sizeof (u32));if (*size > buf_size_left)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 39/161 wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write backtrace
In reply to Greg Kroah-HartmanFrom: Hans de Goede <[email protected]>
[ Upstream commit ef16799640865f937719f0771c93be5dca18adc6 ]
A received TKIP key may be up to 32 bytes because it may contain MIC rx/tx keys too. These are not used by iwl and copying these over overflows the iwl_keyinfo.key field.
Add a check to not copy more data to iwl_keyinfo.key then will fit.
This fixes backtraces like this one:
memcpy: detected field-spanning write (size 32) of single field "sta_cmd.key.key" at drivers/net/wireless/intel/iwlwifi/dvm/sta.c:1103 (size 16)
WARNING: CPU: 1 PID: 946 at drivers/net/wireless/intel/iwlwifi/dvm/sta.c:1103 iwlagn_send_sta_key+0x375/0x390 [iwldvm] <snip> Hardware name: Dell Inc. Latitude E6430/0H3MT5, BIOS A21 05/08/2017 RIP: 0010:iwlagn_send_sta_key+0x375/0x390 [iwldvm] <snip> Call Trace: <TASK> iwl_set_dynamic_key+0x1f0/0x220 [iwldvm] iwlagn_mac_set_key+0x1e4/0x280 [iwldvm] drv_set_key+0xa4/0x1b0 [mac80211] ieee80211_key_enable_hw_accel+0xa8/0x2d0 [mac80211] ieee80211_key_replace+0x22d/0x8e0 [mac80211] <snip>
--- drivers/net/wireless/intel/iwlwifi/dvm/sta.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/dvm/sta.c +4 -1
@@ -1086,6 +1086,7 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, {__le16 key_flags;struct iwl_addsta_cmd sta_cmd; +size_t to_copy;int i;spin_lock_bh (&priv->sta_lock);
@@ -1105,7 +1106,9 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32;for (i =0 ; i <5 ; i++) sta_cmd.key.tkip_rx_ttak[i] =cpu_to_le16 (tkip_p1k[i]); -memcpy (sta_cmd.key.key, keyconf->key, keyconf->keylen); +/* keyconf may contain MIC rx/tx keys which iwl does not use */ + to_copy =min_t (size_t,sizeof (sta_cmd.key.key), keyconf->keylen); +memcpy (sta_cmd.key.key, keyconf->key, to_copy);break ;case WLAN_CIPHER_SUITE_WEP104 : key_flags |=STA_KEY_FLG_KEY_SIZE_MSK ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 40/161 Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp
In reply to Greg Kroah-HartmanFrom: Min Li <[email protected]>
[ Upstream commit 25e97f7b1866e6b8503be349eeea44bb52d661ce ]
conn->chan_lock isn't acquired before l2cap_get_chan_by_scid, if l2cap_get_chan_by_scid returns NULL, then 'bad unlock balance' is triggered.
--- net/bluetooth/l2cap_core.c | 1 - 1 file changed, 1 deletion(-)
net/bluetooth/l2cap_core.c +0 -1
@@ -4410,7 +4410,6 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, chan =l2cap_get_chan_by_scid (conn, scid);if (!chan) { -mutex_unlock (&conn->chan_lock);return 0 ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 41/161 staging: rtl8192e: Replace macro RTL_PCI_DEVICE with PCI_DEVICE
In reply to Greg Kroah-HartmanFrom: Philipp Hortmann <[email protected]>
[ Upstream commit fda2093860df4812d69052a8cf4997e53853a340 ]
Replace macro RTL_PCI_DEVICE with PCI_DEVICE to get rid of rtl819xp_ops which is empty.
--- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 6 +++--- drivers/staging/rtl8192e/rtl8192e/rtl_core.h | 5 ----- 2 files changed, 3 insertions(+), 8 deletions(-)
drivers/staging/rtl8192e/rtl8192e/rtl_core.c +3 -3
@@ -50,9 +50,9 @@ static const struct rtl819x_ops rtl819xp_ops = { };static struct pci_device_id rtl8192_pci_id_tbl[] = { - {RTL_PCI_DEVICE (0x10ec ,0x8192 , rtl819xp_ops)}, - {RTL_PCI_DEVICE (0x07aa ,0x0044 , rtl819xp_ops)}, - {RTL_PCI_DEVICE (0x07aa ,0x0047 , rtl819xp_ops)}, + {PCI_DEVICE (0x10ec ,0x8192 )}, + {PCI_DEVICE (0x07aa ,0x0044 )}, + {PCI_DEVICE (0x07aa ,0x0047 )}, {} };
drivers/staging/rtl8192e/rtl8192e/rtl_core.h +0 -5
@@ -55,11 +55,6 @@#define IS_HARDWARE_TYPE_8192SE (_priv) \ (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192SE) -#define RTL_PCI_DEVICE (vend, dev, cfg) \ - .vendor = (vend), .device = (dev), \ - .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, \ - .driver_data = (kernel_ulong_t)&(cfg) -#define TOTAL_CAM_ENTRY 32#define CAM_CONTENT_COUNT 8
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 42/161 HID: logitech-hidpp: Dont use the USB serial for USB devices
In reply to Greg Kroah-HartmanFrom: Bastien Nocera <[email protected]>
[ Upstream commit 7ad1fe0da0fa91bf920b79ab05ae97bfabecc4f4 ]
For devices that support the 0x0003 feature (Device Information) version 4, set the serial based on the output of that feature, rather than relying on the usbhid code setting the USB serial.
This should allow the serial when connected through USB to (nearly) match the one when connected through a unifying receiver.
For example, on the serials on a G903 wired/wireless mouse:
- Unifying: 4067-e8-ce-cd-45
- USB before patch: 017C385C3837
- USB after patch: c086-e8-ce-cd-45
--- drivers/hid/hid-logitech-hidpp.c | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
drivers/hid/hid-logitech-hidpp.c +51 -0
@@ -903,6 +903,55 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp)return 0 ; } +/* -------------------------------------------------------------------------- */ +/* 0x0003: Device Information */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003 + +#define CMD_GET_DEVICE_INFO 0x00 + +static int hidpp_get_serial (struct hidpp_device *hidpp,u32 *serial) +{ +struct hidpp_report response; +u8 feature_type; +u8 feature_index; +int ret; + + ret =hidpp_root_get_feature (hidpp,HIDPP_PAGE_DEVICE_INFORMATION , + &feature_index, + &feature_type); +if (ret) +return ret; + + ret =hidpp_send_fap_command_sync (hidpp, feature_index, +CMD_GET_DEVICE_INFO , +NULL ,0 , &response); +if (ret) +return ret; + +/* See hidpp_unifying_get_serial() */ + *serial = *((u32 *)&response.rap.params[1 ]); +return 0 ; +} + +static int hidpp_serial_init (struct hidpp_device *hidpp) +{ +struct hid_device *hdev = hidpp->hid_dev; +u32 serial; +int ret; + + ret =hidpp_get_serial (hidpp, &serial); +if (ret) +return ret; + +snprintf (hdev->uniq,sizeof (hdev->uniq),"%04x-%4phD" , + hdev->product, &serial); +dbg_hid ("HID++ DeviceInformation: Got serial: %s\n" , hdev->uniq); + +return 0 ; +} +/* -------------------------------------------------------------------------- */ /* 0x0005: GetDeviceNameType */ /* -------------------------------------------------------------------------- */
@@ -3651,6 +3700,8 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)if (hidpp->quirks &HIDPP_QUIRK_UNIFYING )hidpp_unifying_init (hidpp); +else if (hid_is_usb (hidpp->hid_dev)) +hidpp_serial_init (hidpp); connected =hidpp_root_get_protocol_version (hidpp) ==0 ;atomic_set (&hidpp->connected, connected);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 43/161 HID: logitech-hidpp: Reconcile USB and Unifying serials
In reply to Greg Kroah-HartmanFrom: Bastien Nocera <[email protected]>
[ Upstream commit 5b3691d15e04b6d5a32c915577b8dbc5cfb56382 ]
Now that USB HID++ devices can gather a serial number that matches the one that would be gathered when connected through a Unifying receiver, remove the last difference by dropping the product ID as devices usually have different product IDs when connected through USB or Unifying.
For example, on the serials on a G903 wired/wireless mouse:
- Unifying before patch: 4067-e8-ce-cd-45
- USB before patch: c086-e8-ce-cd-45
- Unifying and USB after patch: e8-ce-cd-45
--- drivers/hid/hid-logitech-hidpp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/hid/hid-logitech-hidpp.c +2 -4
@@ -809,8 +809,7 @@ static int hidpp_unifying_init(struct hidpp_device *hidpp)if (ret)return ret; -snprintf (hdev->uniq,sizeof (hdev->uniq),"%04x-%4phD" , - hdev->product, &serial); +snprintf (hdev->uniq,sizeof (hdev->uniq),"%4phD" , &serial);dbg_hid ("HID++ Unifying: Got serial: %s\n" , hdev->uniq); name =hidpp_unifying_get_name (hidpp);
@@ -945,8 +944,7 @@ static int hidpp_serial_init(struct hidpp_device *hidpp)if (ret)return ret; -snprintf (hdev->uniq,sizeof (hdev->uniq),"%04x-%4phD" , - hdev->product, &serial); +snprintf (hdev->uniq,sizeof (hdev->uniq),"%4phD" , &serial);dbg_hid ("HID++ DeviceInformation: Got serial: %s\n" , hdev->uniq);return 0 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 44/161 spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3
In reply to Greg Kroah-HartmanFrom: Kevin Groeneveld <[email protected]>
[ Upstream commit 87c614175bbf28d3fd076dc2d166bac759e41427 ]
When using gpio based chip select the cs value can go outside the range 0 – 3. The various MX51_ECSPI_* macros did not take this into consideration resulting in possible corruption of the configuration.
For example for any cs value over 3 the SCLKPHA bits would not be set and other values in the register possibly corrupted.
One way to fix this is to just mask the cs bits to 2 bits. This still allows all 4 native chip selects to work as well as gpio chip selects (which can use any of the 4 chip select configurations).
--- drivers/spi/spi-imx.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/spi/spi-imx.c +18 -6
@@ -239,6 +239,18 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,return true; } +/* +* Note the number of natively supported chip selects for MX51 is 4. Some +* devices may have less actual SS pins but the register map supports 4. When +* using gpio chip selects the cs values passed into the macros below can go +* outside the range 0 - 3. We therefore need to limit the cs value to avoid +* corrupting bits outside the allocated locations. +* +* The simplest way to do this is to just mask the cs bits to 2 bits. This +* still allows all 4 native chip selects to work as well as gpio chip selects +* (which can use any of the 4 chip select configurations). +*/ +#define MX51_ECSPI_CTRL 0x08#define MX51_ECSPI_CTRL_ENABLE (1 << 0)#define MX51_ECSPI_CTRL_XCH (1 << 2)
@@ -247,16 +259,16 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,#define MX51_ECSPI_CTRL_DRCTL (drctl) ((drctl) << 16)#define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8#define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 -#define MX51_ECSPI_CTRL_CS (cs) ((cs) << 18) +#define MX51_ECSPI_CTRL_CS (cs) ((cs & 3) << 18)#define MX51_ECSPI_CTRL_BL_OFFSET 20#define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20)#define MX51_ECSPI_CONFIG 0x0c -#define MX51_ECSPI_CONFIG_SCLKPHA (cs) (1 << ((cs) + 0)) -#define MX51_ECSPI_CONFIG_SCLKPOL (cs) (1 << ((cs) + 4)) -#define MX51_ECSPI_CONFIG_SBBCTRL (cs) (1 << ((cs) + 8)) -#define MX51_ECSPI_CONFIG_SSBPOL (cs) (1 << ((cs) + 12)) -#define MX51_ECSPI_CONFIG_SCLKCTL (cs) (1 << ((cs) + 20)) +#define MX51_ECSPI_CONFIG_SCLKPHA (cs) (1 << ((cs & 3) + 0)) +#define MX51_ECSPI_CONFIG_SCLKPOL (cs) (1 << ((cs & 3) + 4)) +#define MX51_ECSPI_CONFIG_SBBCTRL (cs) (1 << ((cs & 3) + 8)) +#define MX51_ECSPI_CONFIG_SSBPOL (cs) (1 << ((cs & 3) + 12)) +#define MX51_ECSPI_CONFIG_SCLKCTL (cs) (1 << ((cs & 3) + 20))#define MX51_ECSPI_INT 0x10#define MX51_ECSPI_INT_TEEN (1 << 0)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 45/161 HID: wacom: generic: Set battery quirk only when we see battery data
In reply to Greg Kroah-HartmanFrom: Jason Gerecke <[email protected]>
[ Upstream commit bea407a427baa019758f29f4d31b26f008bb8cc6 ]
Some devices will include battery status usages in the HID descriptor but we won't see that battery data for one reason or another. For example, AES sensors won't send battery data unless an AES pen is in proximity. If a user does not have an AES pen but instead only interacts with the AES touchscreen with their fingers then there is no need for us to create a battery object. Similarly, if a family of peripherals shares the same HID descriptor between wired-only and wireless-capable SKUs, users of the former may never see a battery event and will not want a power_supply object created.
--- drivers/hid/wacom_wac.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-)
drivers/hid/wacom_wac.c +11 -22
@@ -1927,18 +1927,7 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,static void wacom_wac_battery_usage_mapping (struct hid_device *hdev,struct hid_field *field,struct hid_usage *usage) { -struct wacom *wacom =hid_get_drvdata (hdev); -struct wacom_wac *wacom_wac = &wacom->wacom_wac; -struct wacom_features *features = &wacom_wac->features; -unsigned equivalent_usage =wacom_equivalent_usage (usage->hid); - -switch (equivalent_usage) { -case HID_DG_BATTERYSTRENGTH : -case WACOM_HID_WD_BATTERY_LEVEL : -case WACOM_HID_WD_BATTERY_CHARGING : - features->quirks |=WACOM_QUIRK_BATTERY ; -break ; - } +return ; } static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,
@@ -1959,18 +1948,21 @@ static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *f wacom_wac->hid_data.bat_connected =1 ; wacom_wac->hid_data.bat_status =WACOM_POWER_SUPPLY_STATUS_AUTO ; } + wacom_wac->features.quirks |=WACOM_QUIRK_BATTERY ;break ;case WACOM_HID_WD_BATTERY_LEVEL : value = value *100 / (field->logical_maximum - field->logical_minimum); wacom_wac->hid_data.battery_capacity = value; wacom_wac->hid_data.bat_connected =1 ; wacom_wac->hid_data.bat_status =WACOM_POWER_SUPPLY_STATUS_AUTO ; + wacom_wac->features.quirks |=WACOM_QUIRK_BATTERY ;break ;case WACOM_HID_WD_BATTERY_CHARGING : wacom_wac->hid_data.bat_charging = value; wacom_wac->hid_data.ps_connected = value; wacom_wac->hid_data.bat_connected =1 ; wacom_wac->hid_data.bat_status =WACOM_POWER_SUPPLY_STATUS_AUTO ; + wacom_wac->features.quirks |=WACOM_QUIRK_BATTERY ;break ; } }
@@ -1986,18 +1978,15 @@ static void wacom_wac_battery_report(struct hid_device *hdev, {struct wacom *wacom =hid_get_drvdata (hdev);struct wacom_wac *wacom_wac = &wacom->wacom_wac; -struct wacom_features *features = &wacom_wac->features; -if (features->quirks &WACOM_QUIRK_BATTERY ) { -int status = wacom_wac->hid_data.bat_status; -int capacity = wacom_wac->hid_data.battery_capacity; -bool charging = wacom_wac->hid_data.bat_charging; -bool connected = wacom_wac->hid_data.bat_connected; -bool powered = wacom_wac->hid_data.ps_connected; +int status = wacom_wac->hid_data.bat_status; +int capacity = wacom_wac->hid_data.battery_capacity; +bool charging = wacom_wac->hid_data.bat_charging; +bool connected = wacom_wac->hid_data.bat_connected; +bool powered = wacom_wac->hid_data.ps_connected; -wacom_notify_battery (wacom_wac, status, capacity, charging, - connected, powered); - } +wacom_notify_battery (wacom_wac, status, capacity, charging, + connected, powered); } static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 46/161 usb: typec: tcpm: fix multiple times discover svids error
In reply to Greg Kroah-HartmanFrom: Frank Wang <[email protected]>
[ Upstream commit dac3b192107b978198e89ec0f77375738352e0c8 ]
PD3.0 Spec 6.4.4.3.2 say that only Responder supports 12 or more SVIDs, the Discover SVIDs Command Shall be executed multiple times until a Discover SVIDs VDO is returned ending either with a SVID value of 0x0000 in the last part of the last VDO or with a VDO containing two SVIDs with values of 0x0000.
In the current implementation, if the last VDO does not find that the Discover SVIDs Command would be executed multiple times even if the Responder SVIDs are less than 12, and we found some odd dockers just meet this case. So fix it.
--- drivers/usb/typec/tcpm/tcpm.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/usb/typec/tcpm/tcpm.c +15 -1
@@ -1018,7 +1018,21 @@ static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload, pmdata->svids[pmdata->nsvids++] = svid;tcpm_log (port,"SVID %d: 0x%x" , pmdata->nsvids, svid); } -return true; + +/* +* PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table +* 6-43), and can be returned maximum 6 VDOs per response (see Figure +* 6-19). If the Respondersupports 12 or more SVID then the Discover +* SVIDs Command Shall be executed multiple times until a Discover +* SVIDs VDO is returned ending either with a SVID value of 0x0000 in +* the last part of the last VDO or with a VDO containing two SVIDs +* with values of 0x0000. +* +* However, some odd dockers support SVIDs less than 12 but without +* 0x0000 in the last VDO, so we need to break the Discover SVIDs +* request and return false here. +*/ +return cnt ==7 ; abort:tcpm_log (port,"SVID_DISCOVERY_MAX(%d) too low!" ,SVID_DISCOVERY_MAX );return false;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 47/161 serial: 8250: Reinit port->pm on port specific driver unbind
In reply to Greg Kroah-HartmanFrom: Tony Lindgren <[email protected]>
[ Upstream commit 04e82793f068d2f0ffe62fcea03d007a8cdc16a7 ]
When we unbind a serial port hardware specific 8250 driver, the generic serial8250 driver takes over the port. After that we see an oops about 10 seconds later. This can produce the following at least on some TI SoCs:
Unhandled fault: imprecise external abort (0x1406)
Internal error: : 1406 [#1] SMP ARM
Turns out that we may still have the serial port hardware specific driver port->pm in use, and serial8250_pm() tries to call it after the port specific driver is gone:
serial8250_pm [8250_base] from uart_change_pm+0x54/0x8c [serial_base] uart_change_pm [serial_base] from uart_hangup+0x154/0x198 [serial_base] uart_hangup [serial_base] from __tty_hangup.part.0+0x328/0x37c __tty_hangup.part.0 from disassociate_ctty+0x154/0x20c disassociate_ctty from do_exit+0x744/0xaacdo_exit from do_group_exit+0x40/0x8cdo_group_exit from __wake_up_parent+0x0/0x1c
Let's fix the issue by calling serial8250_set_defaults() in serial8250_unregister_port(). This will set the port back to using the serial8250 default functions, and sets the port->pm to point to serial8250_pm.
--- drivers/tty/serial/8250/8250_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/tty/serial/8250/8250_core.c +1 -0
@@ -1138,6 +1138,7 @@ void serial8250_unregister_port(int line) uart->port.type =PORT_UNKNOWN ; uart->port.dev = &serial8250_isa_devs->dev; uart->capabilities =0 ; +serial8250_init_port (uart);serial8250_apply_quirks (uart);uart_add_one_port (&serial8250_reg, &uart->port); }else {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 48/161 mcb-pci: Reallocate memory region to avoid memory overlapping
In reply to Greg Kroah-HartmanFrom: Rodríguez Barbarin, José Javier <[email protected]>
[ Upstream commit 9be24faadd085c284890c3afcec7a0184642315a ]
mcb-pci requests a fixed-size memory region to parse the chameleon table, however, if the chameleon table is smaller that the allocated region, it could overlap with the IP Cores' memory regions.
After parsing the chameleon table, drop/reallocate the memory region with the actual chameleon table size.
--- drivers/mcb/mcb-pci.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
drivers/mcb/mcb-pci.c +25 -2
@@ -31,7 +31,7 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) {struct resource *res;struct priv *priv; -int ret; +int ret, table_size;unsigned long flags; priv =devm_kzalloc (&pdev->dev,sizeof (struct priv ),GFP_KERNEL );
@@ -90,7 +90,30 @@ static int mcb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (ret <0 ) goto out_mcb_bus; -dev_dbg (&pdev->dev,"Found %d cells\n" , ret); + table_size = ret; + +if (table_size <CHAM_HEADER_SIZE ) { +/* Release the previous resources */ +devm_iounmap (&pdev->dev, priv->base); +devm_release_mem_region (&pdev->dev, priv->mapbase,CHAM_HEADER_SIZE ); + +/* Then, allocate it again with the actual chameleon table size */ + res =devm_request_mem_region (&pdev->dev, priv->mapbase, + table_size, +KBUILD_MODNAME ); +if (!res) { +dev_err (&pdev->dev,"Failed to request PCI memory\n" ); + ret = -EBUSY ; + goto out_mcb_bus; + } + + priv->base =devm_ioremap (&pdev->dev, priv->mapbase, table_size); +if (!priv->base) { +dev_err (&pdev->dev,"Cannot ioremap\n" ); + ret = -ENOMEM ; + goto out_mcb_bus; + } + }mcb_bus_add_devices (priv->bus);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 49/161 sched: Fix KCSAN noinstr violation
In reply to Greg Kroah-HartmanFrom: Josh Poimboeuf <[email protected]>
[ Upstream commit e0b081d17a9f4e5c0cbb0e5fbeb1abe3de0f7e4e ]
With KCSAN enabled, end_of_stack() can get out-of-lined. Force it inline.
Fixes the following warnings:
vmlinux.o: warning: objtool: check_stackleak_irqoff+0x2b: call to end_of_stack() leaves .noinstr.text section
--- include/linux/sched/task_stack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/sched/task_stack.h +1 -1
@@ -23,7 +23,7 @@ static __always_inline void *task_stack_page(const struct task_struct *task)#define setup_thread_stack (new,old) do { } while(0) -static inline unsigned long *end_of_stack (const struct task_struct *task) +static __always_inline unsigned long *end_of_stack (const struct task_struct *task) {#ifdef CONFIG_STACK_GROWSUP return (unsigned long *)((unsigned long )task->stack +THREAD_SIZE ) -1 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 50/161 recordmcount: Fix memory leaks in the uwrite function
In reply to Greg Kroah-HartmanFrom: Hao Zeng <[email protected]>
[ Upstream commit fa359d068574d29e7d2f0fdd0ebe4c6a12b5cfb9 ]
Common realloc mistake: 'file_append' nulled but not freed upon failure
--- scripts/recordmcount.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
scripts/recordmcount.c +5 -1
@@ -102,6 +102,7 @@ static ssize_t uwrite(void const *const buf, size_t const count) {size_t cnt = count;off_t idx =0 ; +void *p =NULL ; file_updated =1 ;
@@ -109,7 +110,10 @@ static ssize_t uwrite(void const *const buf, size_t const count)off_t aoffset = (file_ptr + count) - file_end;if (aoffset > file_append_size) { - file_append =realloc (file_append, aoffset); + p =realloc (file_append, aoffset); +if (!p) +free (file_append); + file_append = p; file_append_size = aoffset; }if (!file_append) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 51/161 RDMA/core: Fix multiple -Warray-bounds warnings
In reply to Greg Kroah-HartmanFrom: Gustavo A. R. Silva <[email protected]>
[ Upstream commit aa4d540b4150052ae3b36d286b9c833a961ce291 ]
GCC-13 (and Clang)[1] does not like to access a partially allocated object, since it cannot reason about it for bounds checking.
In this case 140 bytes are allocated for an object of type struct ib_umad_packet:
packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL);
However, notice that sizeof(*packet) is only 104 bytes:
struct ib_umad_packet {
struct ib_mad_send_buf * msg; /* 0 8 */
struct ib_mad_recv_wc * recv_wc; /* 8 8 */
struct list_head list; /* 16 16 */
int length; /* 32 4 */
/* XXX 4 bytes hole, try to pack */
struct ib_user_mad mad __attribute__((__aligned__(8))); /* 40 64 */
/* size: 104, cachelines: 2, members: 5 */
/* sum members: 100, holes: 1, sum holes: 4 */
/* forced alignments: 1, forced holes: 1, sum forced holes: 4 */
/* last cacheline: 40 bytes */
} __attribute__((__aligned__(8)));and 36 bytes extra bytes are allocated for a flexible-array member in struct ib_user_mad:
include/rdma/ib_mad.h:
120 enum {
...
123 IB_MGMT_RMPP_HDR = 36,
... }
struct ib_user_mad {
struct ib_user_mad_hdr hdr; /* 0 64 */
/* --- cacheline 1 boundary (64 bytes) --- */
__u64 data[] __attribute__((__aligned__(8))); /* 64 0 */
/* size: 64, cachelines: 1, members: 2 */
/* forced alignments: 1 */
} __attribute__((__aligned__(8)));So we have sizeof(*packet) + IB_MGMT_RMPP_HDR == 140 bytes
Then the address of the flex-array member (for which only 36 bytes were allocated) is casted and copied into a pointer to struct ib_rmpp_mad, which, in turn, is of size 256 bytes:
rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
struct ib_rmpp_mad {
struct ib_mad_hdr mad_hdr; /* 0 24 */
struct ib_rmpp_hdr rmpp_hdr; /* 24 12 */
u8 data[220]; /* 36 220 *//* size: 256, cachelines: 4, members: 3 */ };
The thing is that those 36 bytes allocated for flex-array member data in struct ib_user_mad onlly account for the size of both struct ib_mad_hdr and struct ib_rmpp_hdr, but nothing is left for array u8 data[220]. So, the compiler is legitimately complaining about accessing an object for which not enough memory was allocated.
Apparently, the only members of struct ib_rmpp_mad that are relevant (that are actually being used) in function ib_umad_write() are mad_hdr and rmpp_hdr. So, instead of casting packet->mad.data to (struct ib_rmpp_mad *) create a new structure
struct ib_rmpp_mad_hdr {
struct ib_mad_hdr mad_hdr;
struct ib_rmpp_hdr rmpp_hdr;
} __packed;and cast packet->mad.data to (struct ib_rmpp_mad_hdr *).
Notice that
IB_MGMT_RMPP_HDR == sizeof(struct ib_rmpp_mad_hdr) == 36 bytes
Refactor the rest of the code, accordingly.
Fix the following warnings seen under GCC-13 and -Warray-bounds:drivers/infiniband/core/user_mad.c:564:50: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] drivers/infiniband/core/user_mad.c:566:42: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] drivers/infiniband/core/user_mad.c:618:25: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=] drivers/infiniband/core/user_mad.c:622:44: warning: array subscript ‘struct ib_rmpp_mad[0]’ is partly outside array bounds of ‘unsigned char[140]’ [-Warray-bounds=]
--- drivers/infiniband/core/user_mad.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
drivers/infiniband/core/user_mad.c +14 -9
@@ -131,6 +131,11 @@ struct ib_umad_packet {struct ib_user_mad mad; }; +struct ib_rmpp_mad_hdr { +struct ib_mad_hdr mad_hdr; +struct ib_rmpp_hdr rmpp_hdr; +} __packed; +#define CREATE_TRACE_POINTS #include <trace/events/ib_umad.h>
@@ -494,11 +499,11 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, size_t count, loff_t *pos) { struct ib_umad_file *file = filp->private_data; +struct ib_rmpp_mad_hdr *rmpp_mad_hdr;struct ib_umad_packet *packet;struct ib_mad_agent *agent;struct rdma_ah_attr ah_attr;struct ib_ah *ah; -struct ib_rmpp_mad *rmpp_mad;__be64 *tid;int ret, data_len, hdr_len, copy_offset, rmpp_active;u8 base_version;
@@ -506,7 +511,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,if (count <hdr_size (file) +IB_MGMT_RMPP_HDR )return -EINVAL ; - packet =kzalloc (sizeof *packet +IB_MGMT_RMPP_HDR ,GFP_KERNEL ); + packet =kzalloc (sizeof (*packet) +IB_MGMT_RMPP_HDR ,GFP_KERNEL );if (!packet)return -ENOMEM ;
@@ -560,13 +565,13 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, goto err_up; } - rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; - hdr_len =ib_get_mad_data_offset (rmpp_mad->mad_hdr.mgmt_class); + rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data; + hdr_len =ib_get_mad_data_offset (rmpp_mad_hdr->mad_hdr.mgmt_class); -if (ib_is_mad_class_rmpp (rmpp_mad->mad_hdr.mgmt_class) +if (ib_is_mad_class_rmpp (rmpp_mad_hdr->mad_hdr.mgmt_class) &&ib_mad_kernel_rmpp_agent (agent)) { copy_offset =IB_MGMT_RMPP_HDR ; - rmpp_active =ib_get_rmpp_flags (&rmpp_mad->rmpp_hdr) & + rmpp_active =ib_get_rmpp_flags (&rmpp_mad_hdr->rmpp_hdr) &IB_MGMT_RMPP_FLAG_ACTIVE ; }else { copy_offset =IB_MGMT_MAD_HDR ;
@@ -615,12 +620,12 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; *tid =cpu_to_be64 (((u64 ) agent->hi_tid) <<32 | (be64_to_cpup (tid) &0xffffffff )); - rmpp_mad->mad_hdr.tid = *tid; + rmpp_mad_hdr->mad_hdr.tid = *tid; }if (!ib_mad_kernel_rmpp_agent (agent) - &&ib_is_mad_class_rmpp (rmpp_mad->mad_hdr.mgmt_class) - && (ib_get_rmpp_flags (&rmpp_mad->rmpp_hdr) &IB_MGMT_RMPP_FLAG_ACTIVE )) { + &&ib_is_mad_class_rmpp (rmpp_mad_hdr->mad_hdr.mgmt_class) + && (ib_get_rmpp_flags (&rmpp_mad_hdr->rmpp_hdr) &IB_MGMT_RMPP_FLAG_ACTIVE )) {spin_lock_irq (&file->send_lock);list_add_tail (&packet->list, &file->send_list);spin_unlock_irq (&file->send_lock);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 52/161 clk: tegra20: fix gcc-7 constant overflow warning
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit b4a2adbf3586efa12fe78b9dec047423e01f3010 ]
Older gcc versions get confused by comparing a u32 value to a negative constant in a switch()/case block:
drivers/clk/tegra/clk-tegra20.c: In function 'tegra20_clk_measure_input_freq':drivers/clk/tegra/clk-tegra20.c:581:2: error: case label does not reduce to an integer constant
case OSC_CTRL_OSC_FREQ_12MHZ:
^~~~drivers/clk/tegra/clk-tegra20.c:593:2: error: case label does not reduce to an integer constant
case OSC_CTRL_OSC_FREQ_26MHZ:
Make the constants unsigned instead.
--- drivers/clk/tegra/clk-tegra20.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
drivers/clk/tegra/clk-tegra20.c +14 -14
@@ -18,24 +18,24 @@#define MISC_CLK_ENB 0x48#define OSC_CTRL 0x50 -#define OSC_CTRL_OSC_FREQ_MASK (3<<30) -#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) -#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) -#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) -#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) -#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) - -#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28) -#define OSC_CTRL_PLL_REF_DIV_1 (0<<28) -#define OSC_CTRL_PLL_REF_DIV_2 (1<<28) -#define OSC_CTRL_PLL_REF_DIV_4 (2<<28) +#define OSC_CTRL_OSC_FREQ_MASK (3u<<30) +#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30) +#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30) +#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30) +#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30) +#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK) + +#define OSC_CTRL_PLL_REF_DIV_MASK (3u<<28) +#define OSC_CTRL_PLL_REF_DIV_1 (0u<<28) +#define OSC_CTRL_PLL_REF_DIV_2 (1u<<28) +#define OSC_CTRL_PLL_REF_DIV_4 (2u<<28)#define OSC_FREQ_DET 0x58 -#define OSC_FREQ_DET_TRIG (1<<31) +#define OSC_FREQ_DET_TRIG (1u<<31)#define OSC_FREQ_DET_STATUS 0x5c -#define OSC_FREQ_DET_BUSY (1<<31) -#define OSC_FREQ_DET_CNT_MASK 0xFFFF +#define OSC_FREQ_DET_BUSYu (1<<31) +#define OSC_FREQ_DET_CNT_MASK 0xFFFFu#define TEGRA20_CLK_PERIPH_BANKS 3
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 53/161 iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any
In reply to Greg Kroah-HartmanFrom: Tomas Krcka <[email protected]>
[ Upstream commit 67ea0b7ce41844eae7c10bb04dfe66a23318c224 ]
When an overflow occurs in the PRI queue, the SMMU toggles the overflow flag in the PROD register. To exit the overflow condition, the PRI thread is supposed to acknowledge it by toggling this flag in the CONS register. Unacknowledged overflow causes the queue to stop adding anything new.
Currently, the priq thread always writes the CONS register back to the SMMU after clearing the queue.
The writeback is not necessary if the OVFLG in the PROD register has not been changed, no overflow has occured.
This commit checks the difference of the overflow flag between CONS and PROD register. If it's different, toggles the OVACKFLG flag in the CONS register and write it to the SMMU.
The situation is similar for the event queue.
The acknowledge register is also toggled after clearing the event queue but never propagated to the hardware. This would only be done the next time when executing evtq thread.
Unacknowledged event queue overflow doesn't affect the event queue, because the SMMU still adds elements to that queue when the overflow condition is active.
But it feel nicer to keep SMMU in sync when possible, so use the same way here as well.
--- drivers/iommu/arm-smmu-v3.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
drivers/iommu/arm-smmu-v3.c +14 -5
@@ -760,6 +760,18 @@ static void queue_inc_cons(struct arm_smmu_ll_queue *q) q->cons =Q_OVF (q->cons) |Q_WRP (q, cons) |Q_IDX (q, cons); } +static void queue_sync_cons_ovf (struct arm_smmu_queue *q) +{ +struct arm_smmu_ll_queue *llq = &q->llq; + +if (likely (Q_OVF (llq->prod) ==Q_OVF (llq->cons))) +return ; + + llq->cons =Q_OVF (llq->prod) |Q_WRP (llq, llq->cons) | +Q_IDX (llq, llq->cons); +queue_sync_cons_out (q); +} +static int queue_sync_prod_in (struct arm_smmu_queue *q) {int ret =0 ;
@@ -1720,8 +1732,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev) }while (!queue_empty (llq));/* Sync our overflow flag, as we believe we're up to speed */ - llq->cons =Q_OVF (llq->prod) |Q_WRP (llq, llq->cons) | -Q_IDX (llq, llq->cons); +queue_sync_cons_ovf (q);return IRQ_HANDLED ; }
@@ -1779,9 +1790,7 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev) }while (!queue_empty (llq));/* Sync our overflow flag, as we believe we're up to speed */ - llq->cons =Q_OVF (llq->prod) |Q_WRP (llq, llq->cons) | -Q_IDX (llq, llq->cons); -queue_sync_cons_out (q); +queue_sync_cons_ovf (q);return IRQ_HANDLED ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 54/161 Input: xpad - add constants for GIP interface numbers
In reply to Greg Kroah-HartmanFrom: Vicki Pfau <[email protected]>
[ Upstream commit f9b2e603c6216824e34dc9a67205d98ccc9a41ca ]
Wired GIP devices present multiple interfaces with the same USB identification other than the interface number. This adds constants for differentiating two of them and uses them where appropriate
--- drivers/input/joystick/xpad.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/input/joystick/xpad.c +4 -1
@@ -489,6 +489,9 @@ struct xboxone_init_packet { } +#define GIP_WIRED_INTF_DATA 0 +#define GIP_WIRED_INTF_AUDIO 1 +/* * This packet is required for all Xbox One pads with 2015 * or later firmware installed (or present from the factory).
@@ -1813,7 +1816,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id }if (xpad->xtype ==XTYPE_XBOXONE && - intf->cur_altsetting->desc.bInterfaceNumber !=0 ) { + intf->cur_altsetting->desc.bInterfaceNumber !=GIP_WIRED_INTF_DATA ) {/* * The Xbox One controller lists three interfaces all with the * same interface class, subclass and protocol. Differentiate by
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 55/161 phy: st: miphy28lp: use _poll_timeout functions for waits
In reply to Greg Kroah-HartmanFrom: Alain Volmat <[email protected]>
[ Upstream commit e3be4dd2c8d8aabfd2c3127d0e2e5754d3ae82d6 ]
This commit introduces _poll_timeout functions usage instead of wait loops waiting for a status bit.
--- drivers/phy/st/phy-miphy28lp.c | 42 ++++++++-------------------------- 1 file changed, 10 insertions(+), 32 deletions(-)
drivers/phy/st/phy-miphy28lp.c +10 -32
@@ -9,6 +9,7 @@#include <linux/platform_device.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h>
@@ -484,19 +485,11 @@ static inline void miphy28lp_pcie_config_gen(struct miphy28lp_phy *miphy_phy)static inline int miphy28lp_wait_compensation (struct miphy28lp_phy *miphy_phy) { -unsigned long finish = jiffies +5 *HZ ;u8 val;/* Waiting for Compensation to complete */ -do { - val =readb_relaxed (miphy_phy->base +MIPHY_COMP_FSM_6 ); - -if (time_after_eq (jiffies, finish)) -return -EBUSY ; -cpu_relax (); - }while (!(val &COMP_DONE )); - -return 0 ; +return readb_relaxed_poll_timeout (miphy_phy->base +MIPHY_COMP_FSM_6 , + val, val &COMP_DONE ,1 ,5 *USEC_PER_SEC ); }
@@ -805,7 +798,6 @@ static inline void miphy28lp_configure_usb3(struct miphy28lp_phy *miphy_phy)static inline int miphy_is_ready (struct miphy28lp_phy *miphy_phy) { -unsigned long finish = jiffies +5 *HZ ;u8 mask =HFC_PLL |HFC_RDY ;u8 val;
@@ -816,21 +808,14 @@ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy)if (miphy_phy->type ==PHY_TYPE_SATA ) mask |=PHY_RDY ; -do { - val =readb_relaxed (miphy_phy->base +MIPHY_STATUS_1 ); -if ((val & mask) != mask) -cpu_relax (); -else -return 0 ; - }while (!time_after_eq (jiffies, finish)); - -return -EBUSY ; +return readb_relaxed_poll_timeout (miphy_phy->base +MIPHY_STATUS_1 , + val, (val & mask) == mask,1 , +5 *USEC_PER_SEC ); }static int miphy_osc_is_ready (struct miphy28lp_phy *miphy_phy) {struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; -unsigned long finish = jiffies +5 *HZ ;u32 val;if (!miphy_phy->osc_rdy)
@@ -839,17 +824,10 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy)if (!miphy_phy->syscfg_reg[SYSCFG_STATUS ])return -EINVAL ; -do { -regmap_read (miphy_dev->regmap, - miphy_phy->syscfg_reg[SYSCFG_STATUS ], &val); - -if ((val &MIPHY_OSC_RDY ) !=MIPHY_OSC_RDY ) -cpu_relax (); -else -return 0 ; - }while (!time_after_eq (jiffies, finish)); - -return -EBUSY ; +return regmap_read_poll_timeout (miphy_dev->regmap, + miphy_phy->syscfg_reg[SYSCFG_STATUS ], + val, val &MIPHY_OSC_RDY ,1 , +5 *USEC_PER_SEC ); } static int miphy28lp_get_resource_byname(struct device_node *child,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 56/161 mfd: dln2: Fix memory leak in dln2_probe()
In reply to Greg Kroah-HartmanFrom: Qiang Ning <[email protected]>
[ Upstream commit 96da8f148396329ba769246cb8ceaa35f1ddfc48 ]
When dln2_setup_rx_urbs() in dln2_probe() fails, error out_free forgets to call usb_put_dev() to decrease the refcount of dln2->usb_dev.
Fix this by adding usb_put_dev() in the error handling code of dln2_probe().
--- drivers/mfd/dln2.c | 1 + 1 file changed, 1 insertion(+)
drivers/mfd/dln2.c +1 -0
@@ -797,6 +797,7 @@ static int dln2_probe(struct usb_interface *interface,dln2_stop_rx_urbs (dln2); out_free: +usb_put_dev (dln2->usb_dev);dln2_free (dln2);return ret;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 57/161 btrfs: replace calls to btrfs_find_free_ino with btrfs_find_free_objectid
In reply to Greg Kroah-HartmanFrom: Nikolay Borisov <[email protected]>
[ Upstream commit abadc1fcd72e887a8f875dabe4a07aa8c28ac8af ]
The former is going away as part of the inode map removal so switch callers to btrfs_find_free_objectid. No functional changes since with INODE_MAP disabled (default) find_free_objectid was called anyway.
Stable-dep-of: 0004ff15ea26 ("btrfs: fix space cache inconsistency after error loading it from disk")
--- fs/btrfs/inode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
fs/btrfs/inode.c +6 -6
@@ -6830,7 +6830,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,if (IS_ERR (trans))return PTR_ERR (trans); - err =btrfs_find_free_ino (root, &objectid); + err =btrfs_find_free_objectid (root, &objectid);if (err) goto out_unlock;
@@ -6894,7 +6894,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,if (IS_ERR (trans))return PTR_ERR (trans); - err =btrfs_find_free_ino (root, &objectid); + err =btrfs_find_free_objectid (root, &objectid);if (err) goto out_unlock;
@@ -7039,7 +7039,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)if (IS_ERR (trans))return PTR_ERR (trans); - err =btrfs_find_free_ino (root, &objectid); + err =btrfs_find_free_objectid (root, &objectid);if (err) goto out_fail;
@@ -9930,7 +9930,7 @@ static int btrfs_whiteout_for_rename(struct btrfs_trans_handle *trans,u64 objectid;u64 index; - ret =btrfs_find_free_ino (root, &objectid); + ret =btrfs_find_free_objectid (root, &objectid);if (ret)return ret;
@@ -10416,7 +10416,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,if (IS_ERR (trans))return PTR_ERR (trans); - err =btrfs_find_free_ino (root, &objectid); + err =btrfs_find_free_objectid (root, &objectid);if (err) goto out_unlock;
@@ -10699,7 +10699,7 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)if (IS_ERR (trans))return PTR_ERR (trans); - ret =btrfs_find_free_ino (root, &objectid); + ret =btrfs_find_free_objectid (root, &objectid);if (ret) goto out;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 58/161 btrfs: fix space cache inconsistency after error loading it from disk
In reply to Greg Kroah-HartmanFrom: Filipe Manana <[email protected]>
[ Upstream commit 0004ff15ea26015a0a3a6182dca3b9d1df32e2b7 ]
When loading a free space cache from disk, at __load_free_space_cache(), if we fail to insert a bitmap entry, we still increment the number of total bitmaps in the btrfs_free_space_ctl structure, which is incorrect since we failed to add the bitmap entry. On error we then empty the cache by calling __btrfs_remove_free_space_cache(), which will result in getting the total bitmaps counter set to 1.
A failure to load a free space cache is not critical, so if a failure happens we just rebuild the cache by scanning the extent tree, which happens at block-group.c:caching_thread(). Yet the failure will result in having the total bitmaps of the btrfs_free_space_ctl always bigger by 1 then the number of bitmap entries we have. So fix this by having the total bitmaps counter be incremented only if we successfully added the bitmap entry.
--- fs/btrfs/free-space-cache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/btrfs/free-space-cache.c +4 -3
@@ -784,15 +784,16 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, }spin_lock (&ctl->tree_lock); ret =link_free_space (ctl, e); - ctl->total_bitmaps++; - ctl->op->recalc_thresholds (ctl); -spin_unlock (&ctl->tree_lock);if (ret) { +spin_unlock (&ctl->tree_lock);btrfs_err (fs_info,"Duplicate entries in free space cache, dumping" );kmem_cache_free (btrfs_free_space_cachep, e); goto free_cache; } + ctl->total_bitmaps++; + ctl->op->recalc_thresholds (ctl); +spin_unlock (&ctl->tree_lock);list_add_tail (&e->list, &bitmaps); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 59/161 ASoC: fsl_micfil: register platform component before registering cpu dai
In reply to Greg Kroah-HartmanFrom: Shengjiu Wang <[email protected]>
[ Upstream commit 0adf292069dcca8bab76a603251fcaabf77468ca ]
There is no defer probe when adding platform component to snd_soc_pcm_runtime(rtd), the code is in snd_soc_add_pcm_runtime()
snd_soc_register_card()
-> snd_soc_bind_card()
-> snd_soc_add_pcm_runtime()
-> adding cpu dai
-> adding codec dai
-> adding platform component.So if the platform component is not ready at that time, then the sound card still registered successfully, but platform component is empty, the sound card can't be used.
As there is defer probe checking for cpu dai component, then register platform component before cpu dai to avoid such issue.
--- sound/soc/fsl/fsl_micfil.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
sound/soc/fsl/fsl_micfil.c +10 -5
@@ -740,18 +740,23 @@ static int fsl_micfil_probe(struct platform_device *pdev)pm_runtime_enable (&pdev->dev); +/* +* Register platform component before registering cpu dai for there +* is not defer probe for platform component in snd_soc_add_pcm_runtime(). +*/ + ret =devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 ); +if (ret) { +dev_err (&pdev->dev,"failed to pcm register\n" ); +return ret; + } + ret =devm_snd_soc_register_component (&pdev->dev, &fsl_micfil_component, &fsl_micfil_dai,1 );if (ret) {dev_err (&pdev->dev,"failed to register component %s\n" , fsl_micfil_component.name); -return ret; } - ret =devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 ); -if (ret) -dev_err (&pdev->dev,"failed to pcm register\n" ); -return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 60/161 cpupower: Make TSC read per CPU for Mperf monitor
In reply to Greg Kroah-HartmanFrom: Wyes Karny <[email protected]>
[ Upstream commit c2adb1877b76fc81ae041e1db1a6ed2078c6746b ]
System-wide TSC read could cause a drift in C0 percentage calculation. Because if first TSC is read and then one by one mperf is read for all cpus, this introduces drift between mperf reading of later CPUs and TSC reading. To lower this drift read TSC per CPU and also just after mperf read. This technique improves C0 percentage calculation in Mperf monitor.
Before fix: (System 100% busy)
| Mperf || RAPL || Idle_Stats PKG|CORE| CPU| C0 | Cx | Freq || pack | core || POLL | C1 | C2 0| 0| 0| 87.15| 12.85| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 0| 256| 84.62| 15.38| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 1| 1| 87.15| 12.85| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 1| 257| 84.08| 15.92| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 2| 2| 86.61| 13.39| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 2| 258| 83.26| 16.74| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 3| 3| 86.61| 13.39| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 3| 259| 83.60| 16.40| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 4| 4| 86.33| 13.67| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 4| 260| 83.33| 16.67| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 5| 5| 86.06| 13.94| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 5| 261| 83.05| 16.95| 2695||168659003|3970468|| 0.00| 0.00| 0.00 0| 6| 6| 85.51| 14.49| 2695||168659003|3970468|| 0.00| 0.00| 0.00
After fix: (System 100% busy)
| Mperf || RAPL || Idle_Stats PKG|CORE| CPU| C0 | Cx | Freq || pack | core || POLL | C1 | C2 0| 0| 0| 98.03| 1.97| 2415||163295480|3811189|| 0.00| 0.00| 0.00 0| 0| 256| 98.50| 1.50| 2394||163295480|3811189|| 0.00| 0.00| 0.00 0| 1| 1| 99.99| 0.01| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 1| 257| 99.99| 0.01| 2375||163295480|3811189|| 0.00| 0.00| 0.00 0| 2| 2| 99.99| 0.01| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 2| 258|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 3| 3|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 3| 259| 99.99| 0.01| 2435||163295480|3811189|| 0.00| 0.00| 0.00 0| 4| 4|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 4| 260|100.00| 0.00| 2435||163295480|3811189|| 0.00| 0.00| 0.00 0| 5| 5| 99.99| 0.01| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 5| 261|100.00| 0.00| 2435||163295480|3811189|| 0.00| 0.00| 0.00 0| 6| 6|100.00| 0.00| 2401||163295480|3811189|| 0.00| 0.00| 0.00 0| 6| 262|100.00| 0.00| 2435||163295480|3811189|| 0.00| 0.00| 0.00
--- .../utils/idle_monitor/mperf_monitor.c | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-)
tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +14 -17
@@ -66,8 +66,8 @@ static int max_freq_mode;*/ static unsigned long max_frequency; -static unsigned long long tsc_at_measure_start; -static unsigned long long tsc_at_measure_end; +static unsigned long long *tsc_at_measure_start; +static unsigned long long *tsc_at_measure_end;static unsigned long long *mperf_previous_count;static unsigned long long *aperf_previous_count;static unsigned long long *mperf_current_count;
@@ -130,7 +130,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent, aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu];if (max_freq_mode ==MAX_FREQ_TSC_REF ) { - tsc_diff = tsc_at_measure_end - tsc_at_measure_start; + tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; *percent =100.0 * mperf_diff / tsc_diff;dprint ("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n" , mperf_cstates[id].name, mperf_diff, tsc_diff);
@@ -167,7 +167,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,if (max_freq_mode ==MAX_FREQ_TSC_REF ) {/* Calculate max_freq from TSC count */ - tsc_diff = tsc_at_measure_end - tsc_at_measure_start; + tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; time_diff =timespec_diff_us (time_start, time_end); max_frequency = tsc_diff / time_diff; }
@@ -186,33 +186,27 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count,static int mperf_start (void ) {int cpu; -unsigned long long dbg;clock_gettime (CLOCK_REALTIME , &time_start); -mperf_get_tsc (&tsc_at_measure_start); -for (cpu =0 ; cpu < cpu_count; cpu++) +for (cpu =0 ; cpu < cpu_count; cpu++) { +mperf_get_tsc (&tsc_at_measure_start[cpu]);mperf_init_stats (cpu); + } -mperf_get_tsc (&dbg); -dprint ("TSC diff: %llu\n" , dbg - tsc_at_measure_start);return 0 ; }static int mperf_stop (void ) { -unsigned long long dbg;int cpu; -for (cpu =0 ; cpu < cpu_count; cpu++) +for (cpu =0 ; cpu < cpu_count; cpu++) {mperf_measure_stats (cpu); +mperf_get_tsc (&tsc_at_measure_end[cpu]); + } -mperf_get_tsc (&tsc_at_measure_end);clock_gettime (CLOCK_REALTIME , &time_end); - -mperf_get_tsc (&dbg); -dprint ("TSC diff: %llu\n" , dbg - tsc_at_measure_end); -return 0 ; }
@@ -311,7 +305,8 @@ struct cpuidle_monitor *mperf_register(void) aperf_previous_count =calloc (cpu_count,sizeof (unsigned long long )); mperf_current_count =calloc (cpu_count,sizeof (unsigned long long )); aperf_current_count =calloc (cpu_count,sizeof (unsigned long long )); - + tsc_at_measure_start =calloc (cpu_count,sizeof (unsigned long long )); + tsc_at_measure_end =calloc (cpu_count,sizeof (unsigned long long )); mperf_monitor.name_len =strlen (mperf_monitor.name);return &mperf_monitor; }
@@ -322,6 +317,8 @@ void mperf_unregister(void)free (aperf_previous_count);free (mperf_current_count);free (aperf_current_count); +free (tsc_at_measure_start); +free (tsc_at_measure_end);free (is_valid); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 61/161 af_key: Reject optional tunnel/BEET mode templates in outbound policies
In reply to Greg Kroah-HartmanFrom: Tobias Brunner <[email protected]>
[ Upstream commit cf3128a7aca55b2eefb68281d44749c683bdc96f ]
xfrm_state_find() uses encap_family of the current template with the passed local and remote addresses to find a matching state. If an optional tunnel or BEET mode template is skipped in a mixed-family scenario, there could be a mismatch causing an out-of-bounds read as the addresses were not replaced to match the family of the next template.
While there are theoretical use cases for optional templates in outbound policies, the only practical one is to skip IPComp states in inbound policies if uncompressed packets are received that are handled by an implicitly created IPIP state instead.
--- net/key/af_key.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/key/af_key.c +8 -4
@@ -1944,7 +1944,8 @@ static u32 gen_reqid(struct net *net) }static int -parse_ipsecrequest (struct xfrm_policy *xp,struct sadb_x_ipsecrequest *rq) +parse_ipsecrequest (struct xfrm_policy *xp,struct sadb_x_policy *pol, +struct sadb_x_ipsecrequest *rq) {struct net *net =xp_net (xp);struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr;
@@ -1962,9 +1963,12 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)if ((mode =pfkey_mode_to_xfrm (rq->sadb_x_ipsecrequest_mode)) <0 )return -EINVAL ; t->mode = mode; -if (rq->sadb_x_ipsecrequest_level ==IPSEC_LEVEL_USE ) +if (rq->sadb_x_ipsecrequest_level ==IPSEC_LEVEL_USE ) { +if ((mode ==XFRM_MODE_TUNNEL || mode ==XFRM_MODE_BEET ) && + pol->sadb_x_policy_dir ==IPSEC_DIR_OUTBOUND ) +return -EINVAL ; t->optional =1 ; -else if (rq->sadb_x_ipsecrequest_level ==IPSEC_LEVEL_UNIQUE ) { + }else if (rq->sadb_x_ipsecrequest_level ==IPSEC_LEVEL_UNIQUE ) { t->reqid = rq->sadb_x_ipsecrequest_reqid;if (t->reqid >IPSEC_MANUAL_REQID_MAX ) t->reqid =0 ;
@@ -2006,7 +2010,7 @@ parse_ipsecrequests(struct xfrm_policy *xp, struct sadb_x_policy *pol) rq->sadb_x_ipsecrequest_len < sizeof(*rq))return -EINVAL ; -if ((err =parse_ipsecrequest (xp, rq)) <0 ) +if ((err =parse_ipsecrequest (xp, pol, rq)) <0 )return err; len -= rq->sadb_x_ipsecrequest_len; rq = (void *)((u8 *)rq + rq->sadb_x_ipsecrequest_len);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 62/161 net: fec: Better handle pm_runtime_get() failing in .remove()
In reply to Greg Kroah-HartmanFrom: Uwe Kleine-König <[email protected]>
[ Upstream commit f816b9829b19394d318e01953aa3b2721bca040d ]
In the (unlikely) event that pm_runtime_get() (disguised as pm_runtime_resume_and_get()) fails, the remove callback returned an error early. The problem with this is that the driver core ignores the error value and continues removing the device. This results in a resource leak. Worse the devm allocated resources are freed and so if a callback of the driver is called later the register mapping is already gone which probably results in a crash.
--- drivers/net/ethernet/freescale/fec_main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/net/ethernet/freescale/fec_main.c +10 -3
@@ -3769,7 +3769,9 @@ fec_drv_remove(struct platform_device *pdev) ret =pm_runtime_get_sync (&pdev->dev);if (ret <0 ) -return ret; +dev_err (&pdev->dev, +"Failed to resume device in remove callback (%pe)\n" , +ERR_PTR (ret));cancel_work_sync (&fep->tx_timeout_work);fec_ptp_stop (pdev);
@@ -3782,8 +3784,13 @@ fec_drv_remove(struct platform_device *pdev)of_phy_deregister_fixed_link (np);of_node_put (fep->phy_node); -clk_disable_unprepare (fep->clk_ahb); -clk_disable_unprepare (fep->clk_ipg); +/* After pm_runtime_get_sync() failed, the clks are still off, so skip +* disabling them again. +*/ +if (ret >=0 ) { +clk_disable_unprepare (fep->clk_ahb); +clk_disable_unprepare (fep->clk_ipg); + }pm_runtime_put_noidle (&pdev->dev);pm_runtime_disable (&pdev->dev);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 63/161 ALSA: firewire-digi00x: prevent potential use after free
In reply to Greg Kroah-HartmanFrom: Dan Carpenter <[email protected]>
[ Upstream commit c0e72058d5e21982e61a29de6b098f7c1f0db498 ]
This code was supposed to return an error code if init_stream() failed, but it instead freed dg00x->rx_stream and returned success. This potentially leads to a use after free.
--- sound/firewire/digi00x/digi00x-stream.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
sound/firewire/digi00x/digi00x-stream.c +3 -1
@@ -259,8 +259,10 @@ int snd_dg00x_stream_init_duplex(struct snd_dg00x *dg00x)return err; err =init_stream (dg00x, &dg00x->tx_stream); -if (err <0 ) +if (err <0 ) {destroy_stream (dg00x, &dg00x->rx_stream); +return err; + } err =amdtp_domain_init (&dg00x->domain);if (err <0 ) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 64/161 vsock: avoid to close connected socket after the timeout
In reply to Greg Kroah-HartmanFrom: Zhuang Shengen <[email protected]>
[ Upstream commit 6d4486efe9c69626cab423456169e250a5cd3af5 ]
When client and server establish a connection through vsock, the client send a request to the server to initiate the connection, then start a timer to wait for the server's response. When the server's RESPONSE message arrives, the timer also times out and exits. The server's RESPONSE message is processed first, and the connection is established. However, the client's timer also times out, the original processing logic of the client is to directly set the state of this vsock to CLOSE and return ETIMEDOUT. It will not notify the server when the port is released, causing the server port remain.
when client's vsock_connect timeout,it should check sk state is ESTABLISHED or not. if sk state is ESTABLISHED, it means the connection is established, the client should not set the sk state to CLOSE
Note: I encountered this issue on kernel-4.18, which can be fixed by this patch. Then I checked the latest code in the community and found similar issue.
--- net/vmw_vsock/af_vsock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/vmw_vsock/af_vsock.c +1 -1
@@ -1232,7 +1232,7 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,vsock_transport_cancel_pkt (vsk);vsock_remove_connected (vsk); goto out_wait; - }else if (timeout ==0 ) { + }else if ((sk->sk_state !=TCP_ESTABLISHED ) && (timeout ==0 )) { err = -ETIMEDOUT ; sk->sk_state =TCP_CLOSE ; sock->state =SS_UNCONNECTED ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 65/161 serial: arc_uart: fix of_iomap leak in `arc_serial_probe`
In reply to Greg Kroah-HartmanFrom: Ke Zhang <[email protected]>
[ Upstream commit 8ab5fc55d7f65d58a3c3aeadf11bdf60267cd2bd ]
Smatch reports:
drivers/tty/serial/arc_uart.c:631 arc_serial_probe() warn:
'port->membase' from of_iomap() not released on lines: 631.
In arc_serial_probe(), if uart_add_one_port() fails, port->membase is not released, which would cause a resource leak.
To fix this, I replace of_iomap with devm_platform_ioremap_resource.
--- drivers/tty/serial/arc_uart.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/tty/serial/arc_uart.c +4 -3
@@ -613,10 +613,11 @@ static int arc_serial_probe(struct platform_device *pdev) } uart->baud = val; - port->membase =of_iomap (np,0 ); -if (!port->membase) + port->membase =devm_platform_ioremap_resource (pdev,0 ); +if (IS_ERR (port->membase)) {/* No point of dev_err since UART itself is hosed here */ -return -ENXIO ; +return PTR_ERR (port->membase); + } port->irq =irq_of_parse_and_map (np,0 );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 66/161 ip6_gre: Fix skb_under_panic in __gre6_xmit()
In reply to Greg Kroah-HartmanFrom: Peilin Ye <[email protected]>
[ Upstream commit ab198e1d0dd8dc4bc7575fb50758e2cbd51e14e1 ]
Feng reported an skb_under_panic BUG triggered by running test_ip6gretap() in tools/testing/selftests/bpf/test_tunnel.sh:
[ 82.492551] skbuff: skb_under_panic: text:ffffffffb268bb8e len:403 put:12 head:ffff9997c5480000 data:ffff9997c547fff8 tail:0x18b end:0x2c0 dev:ip6gretap11 <...> [ 82.607380] Call Trace: [ 82.609389] <TASK> [ 82.611136] skb_push.cold.109+0x10/0x10 [ 82.614289] __gre6_xmit+0x41e/0x590 [ 82.617169] ip6gre_tunnel_xmit+0x344/0x3f0 [ 82.620526] dev_hard_start_xmit+0xf1/0x330 [ 82.623882] sch_direct_xmit+0xe4/0x250 [ 82.626961] __dev_queue_xmit+0x720/0xfe0 <...> [ 82.633431] packet_sendmsg+0x96a/0x1cb0 [ 82.636568] sock_sendmsg+0x30/0x40
<...>
The following sequence of events caused the BUG:
1. During ip6gretap device initialization, tunnel->tun_hlen (e.g. 4) is calculated based on old flags (see ip6gre_calc_hlen());
2. packet_snd() reserves header room for skb A, assuming tunnel->tun_hlen is 4;
3. Later (in clsact Qdisc), the eBPF program sets a new tunnel key for skb A using bpf_skb_set_tunnel_key() (see _ip6gretap_set_tunnel());
4. __gre6_xmit() detects the new tunnel key, and recalculates "tun_hlen" (e.g. 12) based on new flags (e.g. TUNNEL_KEY and TUNNEL_SEQ);
5. gre_build_header() calls skb_push() with insufficient reserved header room, triggering the BUG.
As sugguested by Cong, fix it by moving the call to skb_cow_head() after the recalculation of tun_hlen.
Reproducer:
OBJ=$LINUX/tools/testing/selftests/bpf/test_tunnel_kern.o
ip netns add at_ns0
ip link add veth0 type veth peer name veth1
ip link set veth0 netns at_ns0
ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0 ip netns exec at_ns0 ip link set dev veth0 up
ip link set dev veth1 up mtu 1500
ip addr add dev veth1 172.16.1.200/24
ip netns exec at_ns0 ip addr add ::11/96 dev veth0 ip netns exec at_ns0 ip link set dev veth0 up ip addr add dev veth1 ::22/96
ip link set dev veth1 up
ip netns exec at_ns0 \ ip link add dev ip6gretap00 type ip6gretap seq flowlabel 0xbcdef key 2 \ local ::11 remote ::22
ip netns exec at_ns0 ip addr add dev ip6gretap00 10.1.1.100/24 ip netns exec at_ns0 ip addr add dev ip6gretap00 fc80::100/96 ip netns exec at_ns0 ip link set dev ip6gretap00 up
ip link add dev ip6gretap11 type ip6gretap external ip addr add dev ip6gretap11 10.1.1.200/24 ip addr add dev ip6gretap11 fc80::200/24
ip link set dev ip6gretap11 up
tc qdisc add dev ip6gretap11 clsact
tc filter add dev ip6gretap11 egress bpf da obj $OBJ sec ip6gretap_set_tunnel tc filter add dev ip6gretap11 ingress bpf da obj $OBJ sec ip6gretap_get_tunnel
ping6 -c 3 -w 10 -q ::11
Stable-dep-of: d80fc101d2eb ("erspan: get the proto with the md version for collect_md")
--- net/ipv6/ip6_gre.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
net/ipv6/ip6_gre.c +6 -3
@@ -720,9 +720,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,else fl6->daddr = tunnel->parms.raddr; -if (skb_cow_head (skb, dev->needed_headroom ?: tunnel->hlen)) -return -ENOMEM ; -/* Push GRE header. */ protocol = (dev->type ==ARPHRD_ETHER ) ?htons (ETH_P_TEB ) : proto;
@@ -751,6 +748,9 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, (TUNNEL_CSUM |TUNNEL_KEY |TUNNEL_SEQ ); tun_hlen =gre_calc_hlen (flags); +if (skb_cow_head (skb, dev->needed_headroom ?: tun_hlen + tunnel->encap_hlen)) +return -ENOMEM ; + gre_build_header(skb, tun_hlen, flags, protocol, tunnel_id_to_key32(tun_info->key.tun_id),
@@ -761,6 +761,9 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,if (tunnel->parms.o_flags &TUNNEL_SEQ ) tunnel->o_seqno++; +if (skb_cow_head (skb, dev->needed_headroom ?: tunnel->hlen)) +return -ENOMEM ; +gre_build_header (skb, tunnel->tun_hlen, tunnel->parms.o_flags, protocol, tunnel->parms.o_key,htonl (tunnel->o_seqno));
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 67/161 ip6_gre: Make o_seqno start from 0 in native mode
In reply to Greg Kroah-HartmanFrom: Peilin Ye <[email protected]>
[ Upstream commit fde98ae91f79cab4e020f40c35ed23cbdc59661c ]
For IP6GRE and IP6GRETAP devices, currently o_seqno starts from 1 in native mode. According to RFC 2890 2.2., "The first datagram is sent with a sequence number of 0." Fix it.
It is worth mentioning that o_seqno already starts from 0 in collect_md mode, see the "if (tunnel->parms.collect_md)" clause in __gre6_xmit(), where tunnel->o_seqno is passed to gre_build_header() before getting incremented.
Stable-dep-of: d80fc101d2eb ("erspan: get the proto with the md version for collect_md")
--- net/ipv6/ip6_gre.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
net/ipv6/ip6_gre.c +5 -6
@@ -711,6 +711,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, {struct ip6_tnl *tunnel =netdev_priv (dev);__be16 protocol; +__be16 flags;if (dev->type ==ARPHRD_ETHER )IPCB (skb)->flags =0 ;
@@ -726,7 +727,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,if (tunnel->parms.collect_md) {struct ip_tunnel_info *tun_info;const struct ip_tunnel_key *key; -__be16 flags;int tun_hlen; tun_info =skb_tunnel_info (skb);
@@ -758,15 +758,14 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, : 0); }else { -if (tunnel->parms.o_flags &TUNNEL_SEQ ) - tunnel->o_seqno++; -if (skb_cow_head (skb, dev->needed_headroom ?: tunnel->hlen))return -ENOMEM ; -gre_build_header (skb, tunnel->tun_hlen, tunnel->parms.o_flags, + flags = tunnel->parms.o_flags; + +gre_build_header (skb, tunnel->tun_hlen, flags, protocol, tunnel->parms.o_key, -htonl (tunnel->o_seqno)); + (flags &TUNNEL_SEQ ) ?htonl (tunnel->o_seqno++) :0 ); } return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 68/161 ip_gre, ip6_gre: Fix race condition on o_seqno in collect_md mode
In reply to Greg Kroah-HartmanFrom: Peilin Ye <[email protected]>
[ Upstream commit 31c417c948d7f6909cb63f0ac3298f3c38f8ce20 ]
As pointed out by Jakub Kicinski, currently using TUNNEL_SEQ in collect_md mode is racy for [IP6]GRE[TAP] devices. Consider the following sequence of events:
1. An [IP6]GRE[TAP] device is created in collect_md mode using "ip link add ... external". "ip" ignores "[o]seq" if "external" is specified, so TUNNEL_SEQ is off, and the device is marked as NETIF_F_LLTX (i.e. it uses lockless TX);
2. Someone sets TUNNEL_SEQ on outgoing skb's, using e.g. bpf_skb_set_tunnel_key() in an eBPF program attached to this device;
3. gre_fb_xmit() or __gre6_xmit() processes these skb's:
gre_build_header(skb, tun_hlen, flags, protocol, tunnel_id_to_key32(tun_info->key.tun_id), (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++) : 0); ^^^^^^^^^^^^^^^^^
Since we are not using the TX lock (&txq->_xmit_lock), multiple CPUs may try to do this tunnel->o_seqno++ in parallel, which is racy. Fix it by making o_seqno atomic_t.
As mentioned by Eric Dumazet in commit b790e01aee74 ("ip_gre: lockless xmit"), making o_seqno atomic_t increases "chance for packets being out of order at receiver" when NETIF_F_LLTX is on.
Maybe a better fix would be:
1. Do not ignore "oseq" in external mode. Users MUST specify "oseq" if they want the kernel to allow sequencing of outgoing packets;
2. Reject all outgoing TUNNEL_SEQ packets if the device was not created with "oseq".
Unfortunately, that would break userspace.
We could now make [IP6]GRE[TAP] devices always NETIF_F_LLTX, but let us do it in separate patches to keep this fix minimal.
Stable-dep-of: d80fc101d2eb ("erspan: get the proto with the md version for collect_md")
--- include/net/ip6_tunnel.h | 2 +- include/net/ip_tunnels.h | 2 +- net/ipv4/ip_gre.c | 6 +++--- net/ipv6/ip6_gre.c | 7 ++++--- 4 files changed, 9 insertions(+), 8 deletions(-)
include/net/ip6_tunnel.h +1 -1
@@ -57,7 +57,7 @@ struct ip6_tnl {/* These fields used only by GRE */ __u32 i_seqno;/* The last seen seqno */ -__u32 o_seqno;/* The last output seqno */ +atomic_t o_seqno;/* The last output seqno */ int hlen;/* tun_hlen + encap_hlen */ int tun_hlen;/* Precalculated header length */ int encap_hlen;/* Encap header length (FOU,GUE) */
include/net/ip_tunnels.h +1 -1
@@ -113,7 +113,7 @@ struct ip_tunnel {/* These four fields used only by GRE */ u32 i_seqno;/* The last seen seqno */ -u32 o_seqno;/* The last output seqno */ +atomic_t o_seqno;/* The last output seqno */ int tun_hlen;/* Precalculated header length */ /* These four fields used only by ERSPAN */
net/ipv4/ip_gre.c +3 -3
@@ -437,7 +437,7 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,/* Push GRE header. */ gre_build_header (skb, tunnel->tun_hlen, flags, proto, tunnel->parms.o_key, - (flags &TUNNEL_SEQ ) ?htonl (tunnel->o_seqno++) :0 ); + (flags &TUNNEL_SEQ ) ?htonl (atomic_fetch_inc (&tunnel->o_seqno)) :0 );ip_tunnel_xmit (skb, dev, tnl_params, tnl_params->protocol); }
@@ -475,7 +475,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev, (TUNNEL_CSUM |TUNNEL_KEY |TUNNEL_SEQ );gre_build_header (skb, tunnel_hlen, flags, proto,tunnel_id_to_key32 (tun_info->key.tun_id), - (flags &TUNNEL_SEQ ) ?htonl (tunnel->o_seqno++) :0 ); + (flags &TUNNEL_SEQ ) ?htonl (atomic_fetch_inc (&tunnel->o_seqno)) :0 );ip_md_tunnel_xmit (skb, dev,IPPROTO_GRE , tunnel_hlen);
@@ -557,7 +557,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev) }gre_build_header (skb,8 ,TUNNEL_SEQ , - proto,0 ,htonl (tunnel->o_seqno++)); + proto,0 ,htonl (atomic_fetch_inc (&tunnel->o_seqno)));ip_md_tunnel_xmit (skb, dev,IPPROTO_GRE , tunnel_hlen);
net/ipv6/ip6_gre.c +4 -3
@@ -754,7 +754,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,gre_build_header (skb, tun_hlen, flags, protocol,tunnel_id_to_key32 (tun_info->key.tun_id), - (flags &TUNNEL_SEQ ) ?htonl (tunnel->o_seqno++) + (flags &TUNNEL_SEQ ) ?htonl (atomic_fetch_inc (&tunnel->o_seqno)) :0 ); }else {
@@ -765,7 +765,8 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,gre_build_header (skb, tunnel->tun_hlen, flags, protocol, tunnel->parms.o_key, - (flags &TUNNEL_SEQ ) ?htonl (tunnel->o_seqno++) :0 ); + (flags &TUNNEL_SEQ ) ?htonl (atomic_fetch_inc (&tunnel->o_seqno)) + :0 ); } return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
@@ -1048,7 +1049,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,/* Push GRE header. */ proto = (t->parms.erspan_ver ==1 ) ?htons (ETH_P_ERSPAN ) :htons (ETH_P_ERSPAN2 ); -gre_build_header (skb,8 ,TUNNEL_SEQ , proto,0 ,htonl (t->o_seqno++)); +gre_build_header (skb,8 ,TUNNEL_SEQ , proto,0 ,htonl (atomic_fetch_inc (&t->o_seqno)));/* TooBig packet may have updated dst->dev's mtu */ if (!t->parms.collect_md && dst &&dst_mtu (dst) > dst->dev->mtu)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 69/161 erspan: get the proto with the md version for collect_md
In reply to Greg Kroah-HartmanFrom: Xin Long <[email protected]>
[ Upstream commit d80fc101d2eb9b3188c228d61223890aeea480a4 ]
In commit 20704bd1633d ("erspan: build the header with the right proto according to erspan_ver"), it gets the proto with t->parms.erspan_ver, but t->parms.erspan_ver is not used by collect_md branch, and instead it should get the proto with md->version for collect_md.
Thanks to Kevin for pointing this out.
--- net/ipv6/ip6_gre.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
net/ipv6/ip6_gre.c +8 -5
@@ -1003,12 +1003,14 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,ntohl (tun_id),ntohl (md->u.index), truncate, false); + proto =htons (ETH_P_ERSPAN ); }else if (md->version ==2 ) {erspan_build_header_v2 (skb,ntohl (tun_id), md->u.md2.dir,get_hwid (&md->u.md2), truncate, false); + proto =htons (ETH_P_ERSPAN2 ); }else { goto tx_err; }
@@ -1031,24 +1033,25 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,break ; } -if (t->parms.erspan_ver ==1 ) +if (t->parms.erspan_ver ==1 ) {erspan_build_header (skb,ntohl (t->parms.o_key), t->parms.index, truncate, false); -else if (t->parms.erspan_ver ==2 ) + proto =htons (ETH_P_ERSPAN ); + }else if (t->parms.erspan_ver ==2 ) {erspan_build_header_v2 (skb,ntohl (t->parms.o_key), t->parms.dir, t->parms.hwid, truncate, false); -else + proto =htons (ETH_P_ERSPAN2 ); + }else { goto tx_err; + } fl6.daddr = t->parms.raddr; }/* Push GRE header. */ - proto = (t->parms.erspan_ver ==1 ) ?htons (ETH_P_ERSPAN ) - :htons (ETH_P_ERSPAN2 );gre_build_header (skb,8 ,TUNNEL_SEQ , proto,0 ,htonl (atomic_fetch_inc (&t->o_seqno)));/* TooBig packet may have updated dst->dev's mtu */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 70/161 net: hns3: fix sending pfc frames after reset issue
In reply to Greg Kroah-HartmanFrom: Jijie Shao <[email protected]>
[ Upstream commit f14db07064727dd3bc0906c77a6d2759c1bbb395 ]
To prevent the system from abnormally sending PFC frames after an abnormal reset. The hns3 driver notifies the firmware to disable pfc before reset.
--- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 15 +++++++++------ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 4 ++-- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 5 +++++ 3 files changed, 16 insertions(+), 8 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +9 -6
@@ -6688,12 +6688,15 @@ static void hclge_ae_stop(struct hnae3_handle *handle)/* If it is not PF reset or FLR, the firmware will disable the MAC, * so it only need to stop phy here. */ -if (test_bit (HCLGE_STATE_RST_HANDLING , &hdev->state) && - hdev->reset_type !=HNAE3_FUNC_RESET && - hdev->reset_type !=HNAE3_FLR_RESET ) { -hclge_mac_stop_phy (hdev); -hclge_update_link_status (hdev); -return ; +if (test_bit (HCLGE_STATE_RST_HANDLING , &hdev->state)) { +hclge_pfc_pause_en_cfg (hdev,HCLGE_PFC_TX_RX_DISABLE , +HCLGE_PFC_DISABLE ); +if (hdev->reset_type !=HNAE3_FUNC_RESET && + hdev->reset_type !=HNAE3_FLR_RESET ) { +hclge_mac_stop_phy (hdev); +hclge_update_link_status (hdev); +return ; + } }for (i =0 ; i < handle->kinfo.num_tqps; i++)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +2 -2
@@ -170,8 +170,8 @@ int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)return hclge_cmd_send (&hdev->hw, &desc,1 ); } -static int hclge_pfc_pause_en_cfg (struct hclge_dev *hdev,u8 tx_rx_bitmap, -u8 pfc_bitmap) +int hclge_pfc_pause_en_cfg (struct hclge_dev *hdev,u8 tx_rx_bitmap, +u8 pfc_bitmap) {struct hclge_desc desc;struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data;
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +5 -0
@@ -109,6 +109,9 @@ struct hclge_bp_to_qs_map_cmd {u32 rsvd1; }; +#define HCLGE_PFC_DISABLE 0 +#define HCLGE_PFC_TX_RX_DISABLE 0 +struct hclge_pfc_en_cmd {u8 tx_rx_en_bitmap;u8 pri_en_bitmap;
@@ -150,6 +153,8 @@ void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc);void hclge_tm_pfc_info_update (struct hclge_dev *hdev);int hclge_tm_dwrr_cfg (struct hclge_dev *hdev);int hclge_tm_init_hw (struct hclge_dev *hdev,bool init); +int hclge_pfc_pause_en_cfg (struct hclge_dev *hdev,u8 tx_rx_bitmap, +u8 pfc_bitmap);int hclge_mac_pause_en_cfg (struct hclge_dev *hdev,bool tx,bool rx);int hclge_pause_addr_cfg (struct hclge_dev *hdev,const u8 *mac_addr);int hclge_pfc_rx_stats_get (struct hclge_dev *hdev,u64 *stats);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 71/161 net: hns3: fix reset delay time to avoid configuration timeout
In reply to Greg Kroah-HartmanFrom: Jie Wang <[email protected]>
[ Upstream commit 814d0c786068e858d889ada3153bff82f64223ad ]
Currently the hns3 vf function reset delays 5000ms before vf rebuild process. In product applications, this delay is too long for application configurations and causes configuration timeout.
According to the tests, 500ms delay is enough for reset process except PF FLR. So this patch modifies delay to 500ms in these scenarios.
--- drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +4 -1
@@ -1432,7 +1432,10 @@ static int hclgevf_reset_wait(struct hclgevf_dev *hdev)* might happen in case reset assertion was made by PF. Yes, this also * means we might end up waiting bit more even for VF reset. */ -msleep (5000 ); +if (hdev->reset_type ==HNAE3_VF_FULL_RESET ) +msleep (5000 ); +else +msleep (500 );return 0 ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 72/161 media: netup_unidvb: fix use-after-free at del_timer()
In reply to Greg Kroah-HartmanFrom: Duoming Zhou <[email protected]>
[ Upstream commit 0f5bb36bf9b39a2a96e730bf4455095b50713f63 ]
When Universal DVB card is detaching, netup_unidvb_dma_fini() uses del_timer() to stop dma->timeout timer. But when timer handler netup_unidvb_dma_timeout() is running, del_timer() could not stop it. As a result, the use-after-free bug could happen. The process is shown below:
(cleanup routine) | (timer routine)
| mod_timer(&dev->tx_sim_timer, ..)
netup_unidvb_finidev() | (wait a time)
netup_unidvb_dma_fini() | netup_unidvb_dma_timeout()
del_timer(&dma->timeout); |
| ndev->pci_dev->dev //USEFix by changing del_timer() to del_timer_sync().
--- drivers/media/pci/netup_unidvb/netup_unidvb_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/pci/netup_unidvb/netup_unidvb_core.c +1 -1
@@ -697,7 +697,7 @@ static void netup_unidvb_dma_fini(struct netup_unidvb_dev *ndev, int num)netup_unidvb_dma_enable (dma,0 );msleep (50 );cancel_work_sync (&dma->work); -del_timer (&dma->timeout); +del_timer_sync (&dma->timeout); }static int netup_unidvb_dma_setup (struct netup_unidvb_dev *ndev)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 73/161 drm/exynos: fix g2d_open/close helper function definitions
In reply to Greg Kroah-HartmanFrom: Arnd Bergmann <[email protected]>
[ Upstream commit 2ef0785b30bd6549ddbc124979f1b6596e065ae2 ]
The empty stub functions are defined as global functions, which causes a warning because of missing prototypes:
drivers/gpu/drm/exynos/exynos_drm_g2d.h:37:5: error: no previous prototype for 'g2d_open' drivers/gpu/drm/exynos/exynos_drm_g2d.h:42:5: error: no previous prototype for 'g2d_close'
Mark them as 'static inline' to avoid the warning and to make them behave as intended.
--- drivers/gpu/drm/exynos/exynos_drm_g2d.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/exynos/exynos_drm_g2d.h +2 -2
@@ -34,11 +34,11 @@ static inline int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data, return -ENODEV; } -int g2d_open (struct drm_device *drm_dev,struct drm_file *file) +static inline int g2d_open (struct drm_device *drm_dev,struct drm_file *file) {return 0 ; } -void g2d_close (struct drm_device *drm_dev,struct drm_file *file) +static inline void g2d_close (struct drm_device *drm_dev,struct drm_file *file) { }#endif
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 74/161 net: nsh: Use correct mac_offset to unwind gso skb in nsh_gso_segment()
In reply to Greg Kroah-HartmanFrom: Dong Chenchen <[email protected]>
[ Upstream commit c83b49383b595be50647f0c764a48c78b5f3c4f8 ]
As the call trace shows, skb_panic was caused by wrong skb->mac_header in nsh_gso_segment():
invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI
CPU: 3 PID: 2737 Comm: syz Not tainted 6.3.0-next-20230505 #1 RIP: 0010:skb_panic+0xda/0xe0 call Trace: skb_push+0x91/0xa0 nsh_gso_segment+0x4f3/0x570 skb_mac_gso_segment+0x19e/0x270 __skb_gso_segment+0x1e8/0x3c0 validate_xmit_skb+0x452/0x890 validate_xmit_skb_list+0x99/0xd0 sch_direct_xmit+0x294/0x7c0 __dev_queue_xmit+0x16f0/0x1d70 packet_xmit+0x185/0x210 packet_snd+0xc15/0x1170 packet_sendmsg+0x7b/0xa0 sock_sendmsg+0x14f/0x160
The root cause is:nsh_gso_segment() use skb->network_header - nhoff to reset mac_header in skb_gso_error_unwind() if inner-layer protocol gso fails. However, skb->network_header may be reset by inner-layer protocol gso function e.g. mpls_gso_segment. skb->mac_header reset by the inaccurate network_header will be larger than skb headroom.
nsh_gso_segment
nhoff = skb->network_header - skb->mac_header;
__skb_pull(skb,nsh_len)
skb_mac_gso_segment
mpls_gso_segment
skb_reset_network_header(skb);//skb->network_header+=nsh_len
return -EINVAL;
skb_gso_error_unwind
skb_push(skb, nsh_len);
skb->mac_header = skb->network_header - nhoff;
// skb->mac_header > skb->headroom, cause skb_push panicUse correct mac_offset to restore mac_header and get rid of nhoff.
--- net/nsh/nsh.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
net/nsh/nsh.c +3 -5
@@ -77,13 +77,12 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, netdev_features_t features) {struct sk_buff *segs =ERR_PTR (-EINVAL ); +u16 mac_offset = skb->mac_header;unsigned int nsh_len, mac_len;__be16 proto; -int nhoff;skb_reset_network_header (skb); - nhoff = skb->network_header - skb->mac_header; mac_len = skb->mac_len;if (unlikely (!pskb_may_pull (skb,NSH_BASE_HDR_LEN )))
@@ -108,15 +107,14 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, segs =skb_mac_gso_segment (skb, features);if (IS_ERR_OR_NULL (segs)) {skb_gso_error_unwind (skb,htons (ETH_P_NSH ), nsh_len, - skb->network_header - nhoff, - mac_len); + mac_offset, mac_len); goto out; }for (skb = segs; skb; skb = skb->next) { skb->protocol =htons (ETH_P_NSH );__skb_push (skb, nsh_len); -skb_set_mac_header (skb, -nhoff); + skb->mac_header = mac_offset; skb->network_header = skb->mac_header + mac_len; skb->mac_len = mac_len; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 75/161 net: bcmgenet: Remove phy_stop() from bcmgenet_netif_stop()
In reply to Greg Kroah-HartmanFrom: Florian Fainelli <[email protected]>
[ Upstream commit 93e0401e0fc0c54b0ac05b687cd135c2ac38187c ]
The call to phy_stop() races with the later call to phy_disconnect(), resulting in concurrent phy_suspend() calls being run from different CPUs. The final call to phy_disconnect() ensures that the PHY is stopped and suspended, too.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +0 -1
@@ -2988,7 +2988,6 @@ static void bcmgenet_netif_stop(struct net_device *dev)/* Disable MAC transmit. TX DMA disabled must be done before this */ umac_enable_set (priv,CMD_TX_EN , false); -phy_stop (dev->phydev);bcmgenet_disable_rx_napi (priv);bcmgenet_intr_disable (priv);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 76/161 net: bcmgenet: Restore phy_stop() depending upon suspend/close
In reply to Greg Kroah-HartmanFrom: Florian Fainelli <[email protected]>
[ Upstream commit 225c657945c4a6307741cb3cc89467eadcc26e9b ]
Removing the phy_stop() from bcmgenet_netif_stop() ended up causing warnings from the PHY library that phy_start() is called from the RUNNING state since we are no longer stopping the PHY state machine during bcmgenet_suspend().
Restore the call to phy_stop() but make it conditional on being called from the close or suspend path.
--- drivers/net/ethernet/broadcom/genet/bcmgenet.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +5 -3
@@ -2973,7 +2973,7 @@ static int bcmgenet_open(struct net_device *dev)return ret; } -static void bcmgenet_netif_stop (struct net_device *dev) +static void bcmgenet_netif_stop (struct net_device *dev,bool stop_phy) {struct bcmgenet_priv *priv =netdev_priv (dev);
@@ -2988,6 +2988,8 @@ static void bcmgenet_netif_stop(struct net_device *dev)/* Disable MAC transmit. TX DMA disabled must be done before this */ umac_enable_set (priv,CMD_TX_EN , false); +if (stop_phy) +phy_stop (dev->phydev);bcmgenet_disable_rx_napi (priv);bcmgenet_intr_disable (priv);
@@ -3013,7 +3015,7 @@ static int bcmgenet_close(struct net_device *dev)netif_dbg (priv, ifdown, dev,"bcmgenet_close\n" ); -bcmgenet_netif_stop (dev); +bcmgenet_netif_stop (dev, false);/* Really kill the PHY state machine and disconnect from it */ phy_disconnect (dev->phydev);
@@ -3711,7 +3713,7 @@ static int bcmgenet_suspend(struct device *d)netif_device_detach (dev); -bcmgenet_netif_stop (dev); +bcmgenet_netif_stop (dev, true);if (!device_may_wakeup (d))phy_suspend (dev->phydev);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 77/161 wifi: iwlwifi: mvm: dont trust firmware n_channels
In reply to Greg Kroah-HartmanFrom: Johannes Berg <[email protected]>
[ Upstream commit 682b6dc29d98e857e6ca4bbc077c7dc2899b7473 ]
If the firmware sends us a corrupted MCC response with n_channels much larger than the command response can be, we might copy far too much (uninitialized) memory and even crash if the n_channels is large enough to make it run out of the one page allocated for the FW response.
Fix that by checking the lengths. Doing a < comparison would be sufficient, but the firmware should be doing it correctly, so check more strictly.
--- drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +10 -0
@@ -508,6 +508,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data; n_channels =__le32_to_cpu (mcc_resp->n_channels); +if (iwl_rx_packet_payload_len (pkt) != +struct_size (mcc_resp, channels, n_channels)) { + resp_cp =ERR_PTR (-EINVAL ); + goto exit; + } resp_len =sizeof (struct iwl_mcc_update_resp ) + n_channels *sizeof (__le32); resp_cp =kmemdup (mcc_resp, resp_len,GFP_KERNEL );
@@ -519,6 +524,11 @@ iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data; n_channels =__le32_to_cpu (mcc_resp_v3->n_channels); +if (iwl_rx_packet_payload_len (pkt) != +struct_size (mcc_resp_v3, channels, n_channels)) { + resp_cp =ERR_PTR (-EINVAL ); + goto exit; + } resp_len =sizeof (struct iwl_mcc_update_resp ) + n_channels *sizeof (__le32); resp_cp =kzalloc (resp_len,GFP_KERNEL );
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 78/161 cassini: Fix a memory leak in the error handling path of cas_init_one()
In reply to Greg Kroah-HartmanFrom: Christophe JAILLET <[email protected]>
[ Upstream commit 412cd77a2c24b191c65ea53025222418db09817c ]
cas_saturn_firmware_init() allocates some memory using vmalloc(). This memory is freed in the .remove() function but not it the error handling path of the probe.
Add the missing vfree() to avoid a memory leak, should an error occur.
--- drivers/net/ethernet/sun/cassini.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/sun/cassini.c +2 -0
@@ -5138,6 +5138,8 @@ static int cas_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)cas_shutdown (cp);mutex_unlock (&cp->pm_mutex); +vfree (cp->fw_data); +pci_iounmap (pdev, cp->regs);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 79/161 igb: fix bit_shift to be in [1..8] range
In reply to Greg Kroah-HartmanFrom: Aleksandr Loktionov <[email protected]>
[ Upstream commit 60d758659f1fb49e0d5b6ac2691ede8c0958795b ]
In igb_hash_mc_addr() the expression:
"mc_addr[4] >> 8 - bit_shift", right shifting "mc_addr[4]"
shift by more than 7 bits always yields zero, so hash becomes not so different. Add initialization with bit_shift = 1 and add a loop condition to ensure bit_shift will be always in [1..8] range.
--- drivers/net/ethernet/intel/igb/e1000_mac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igb/e1000_mac.c +2 -2
@@ -425,7 +425,7 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)static u32 igb_hash_mc_addr (struct e1000_hw *hw,u8 *mc_addr) {u32 hash_value, hash_mask; -u8 bit_shift =0 ; +u8 bit_shift =1 ;/* Register count multiplied by bits per register */ hash_mask = (hw->mac.mta_reg_count *32 ) -1 ;
@@ -433,7 +433,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)/* For a mc_filter_type of 0, bit_shift is the number of left-shifts * where 0xFF would still fall within the hash mask. */ -while (hash_mask >> bit_shift !=0xFF ) +while (hash_mask >> bit_shift !=0xFF && bit_shift <4 ) bit_shift++;/* The portion of the address that is used for the hash table
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 80/161 vlan: fix a potential uninit-value in vlan_dev_hard_start_xmit()
In reply to Greg Kroah-HartmanFrom: Eric Dumazet <[email protected]>
[ Upstream commit dacab578c7c6cd06c50c89dfa36b0e0f10decd4e ]
syzbot triggered the following splat [1], sending an empty message through pppoe_sendmsg().
When VLAN_FLAG_REORDER_HDR flag is set, vlan_dev_hard_header() does not push extra bytes for the VLAN header, because vlan is offloaded.
Unfortunately vlan_dev_hard_start_xmit() first reads veth->h_vlan_proto before testing (vlan->flags & VLAN_FLAG_REORDER_HDR).
We need to swap the two conditions.
[1]
BUG: KMSAN: uninit-value in vlan_dev_hard_start_xmit+0x171/0x7f0 net/8021q/vlan_dev.c:111 vlan_dev_hard_start_xmit+0x171/0x7f0 net/8021q/vlan_dev.c:111 __netdev_start_xmit include/linux/netdevice.h:4883 [inline] netdev_start_xmit include/linux/netdevice.h:4897 [inline] xmit_one net/core/dev.c:3580 [inline] dev_hard_start_xmit+0x253/0xa20 net/core/dev.c:3596 __dev_queue_xmit+0x3c7f/0x5ac0 net/core/dev.c:4246 dev_queue_xmit include/linux/netdevice.h:3053 [inline] pppoe_sendmsg+0xa93/0xb80 drivers/net/ppp/pppoe.c:900 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] ____sys_sendmsg+0xa24/0xe40 net/socket.c:2501 ___sys_sendmsg+0x2a1/0x3f0 net/socket.c:2555 __sys_sendmmsg+0x411/0xa50 net/socket.c:2641 __do_sys_sendmmsg net/socket.c:2670 [inline] __se_sys_sendmmsg net/socket.c:2667 [inline] __x64_sys_sendmmsg+0xbc/0x120 net/socket.c:2667 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Uninit was created at:
slab_post_alloc_hook+0x12d/0xb60 mm/slab.h:774 slab_alloc_node mm/slub.c:3452 [inline] kmem_cache_alloc_node+0x543/0xab0 mm/slub.c:3497 kmalloc_reserve+0x148/0x470 net/core/skbuff.c:520 __alloc_skb+0x3a7/0x850 net/core/skbuff.c:606 alloc_skb include/linux/skbuff.h:1277 [inline] sock_wmalloc+0xfe/0x1a0 net/core/sock.c:2583 pppoe_sendmsg+0x3af/0xb80 drivers/net/ppp/pppoe.c:867 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg net/socket.c:747 [inline] ____sys_sendmsg+0xa24/0xe40 net/socket.c:2501 ___sys_sendmsg+0x2a1/0x3f0 net/socket.c:2555 __sys_sendmmsg+0x411/0xa50 net/socket.c:2641 __do_sys_sendmmsg net/socket.c:2670 [inline] __se_sys_sendmmsg net/socket.c:2667 [inline] __x64_sys_sendmmsg+0xbc/0x120 net/socket.c:2667 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd CPU: 0 PID: 29770 Comm: syz-executor.0 Not tainted 6.3.0-rc6-syzkaller-gc478e5b17829 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/30/2023
--- net/8021q/vlan_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/8021q/vlan_dev.c +2 -2
@@ -109,8 +109,8 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,* NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... */ -if (veth->h_vlan_proto != vlan->vlan_proto || - vlan->flags &VLAN_FLAG_REORDER_HDR ) { +if (vlan->flags &VLAN_FLAG_REORDER_HDR || + veth->h_vlan_proto != vlan->vlan_proto) {u16 vlan_tci; vlan_tci = vlan->vlan_id; vlan_tci |=vlan_dev_get_egress_qos_mask (dev, skb->priority);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 81/161 USB: usbtmc: Fix direction for 0-length ioctl control messages
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit 94d25e9128988c6a1fc9070f6e98215a95795bd8 upstream.
The syzbot fuzzer found a problem in the usbtmc driver: When a user submits an ioctl for a 0-length control transfer, the driver does not check that the direction is set to OUT:
------------[ cut here ]------------ usb 3-1: BOGUS control dir, pipe 80000b80 doesn't match bRequestType fd WARNING: CPU: 0 PID: 5100 at drivers/usb/core/urb.c:411 usb_submit_urb+0x14a7/0x1880 drivers/usb/core/urb.c:411 Modules linked in: CPU: 0 PID: 5100 Comm: syz-executor428 Not tainted 6.3.0-syzkaller-12049-g58390c8ce1bd #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/14/2023 RIP: 0010:usb_submit_urb+0x14a7/0x1880 drivers/usb/core/urb.c:411 Code: 7c 24 40 e8 1b 13 5c fb 48 8b 7c 24 40 e8 21 1d f0 fe 45 89 e8 44 89 f1 4c 89 e2 48 89 c6 48 c7 c7 e0 b5 fc 8a e8 19 c8 23 fb <0f> 0b e9 9f ee ff ff e8 ed 12 5c fb 0f b6 1d 12 8a 3c 08 31 ff 41 RSP: 0018:ffffc90003d2fb00 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff8880789e9058 RCX: 0000000000000000 RDX: ffff888029593b80 RSI: ffffffff814c1447 RDI: 0000000000000001 RBP: ffff88801ea742f8 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffff88802915e528 R13: 00000000000000fd R14: 0000000080000b80 R15: ffff8880222b3100 FS: 0000555556ca63c0(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f9ef4d18150 CR3: 0000000073e5b000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> usb_start_wait_urb+0x101/0x4b0 drivers/usb/core/message.c:58 usb_internal_control_msg drivers/usb/core/message.c:102 [inline] usb_control_msg+0x320/0x4a0 drivers/usb/core/message.c:153 usbtmc_ioctl_request drivers/usb/class/usbtmc.c:1954 [inline] usbtmc_ioctl+0x1b3d/0x2840 drivers/usb/class/usbtmc.c:2097
To fix this, we must override the direction in the bRequestType field of the control request structure when the length is 0.
--- drivers/usb/class/usbtmc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/class/usbtmc.c +2 -0
@@ -1898,6 +1898,8 @@ static int usbtmc_ioctl_request(struct uif (request.req.wLength >USBTMC_BUFSIZE )return -EMSGSIZE ; +if (request.req.wLength ==0 )/* Length-0 requests are never IN */ + request.req.bRequestType &= ~USB_DIR_IN ; is_in = request.req.bRequestType &USB_DIR_IN ;
Greg Kroah-Hartman
maintainerPATCH 82/161 usb-storage: fix deadlock when a scsi command timeouts more than once
In reply to Greg Kroah-HartmanFrom: Maxime Bizon <[email protected]>
commit a398d5eac6984316e71474e25b975688f282379b upstream.
With faulty usb-storage devices, read/write can timeout, in that case the SCSI layer will abort and re-issue the command. USB storage has no internal timeout, it relies on SCSI layer aborting commands via .eh_abort_handler() for non those responsive devices.
After two consecutive timeouts of the same command, SCSI layer calls .eh_device_reset_handler(), without calling .eh_abort_handler() first.
With usb-storage, this causes a deadlock:
-> .eh_device_reset_handler
-> device_reset
-> mutex_lock(&(us->dev_mutex));mutex already by usb_stor_control_thread(), which is waiting for command completion:
-> usb_stor_control_thread (mutex taken here)
-> usb_stor_invoke_transport
-> usb_stor_Bulk_transport
-> usb_stor_bulk_srb
-> usb_stor_bulk_transfer_sglist
-> usb_sg_waitMake sure we cancel any pending command in .eh_device_reset_handler() to avoid this.
--- drivers/usb/storage/scsiglue.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/usb/storage/scsiglue.c +21 -7
@@ -407,22 +407,25 @@ static DEF_SCSI_QCMD(queuecommand)***********************************************************************/ /* Command timeout and abort */ -static int command_abort (struct scsi_cmnd *srb) +static int command_abort_matching (struct us_data *us,struct scsi_cmnd *srb_match) { -struct us_data *us =host_to_us (srb->device->host); - -usb_stor_dbg (us,"%s called\n" , __func__); -/* * us->srb together with the TIMED_OUT, RESETTING, and ABORTING * bits are protected by the host lock. */ scsi_lock (us_to_host (us)); -/* Is this command still active? */ -if (us->srb != srb) { +/* is there any active pending command to abort ? */ +if (!us->srb) {scsi_unlock (us_to_host (us));usb_stor_dbg (us,"-- nothing to abort\n" ); +return SUCCESS ; + } + +/* Does the command match the passed srb if any ? */ +if (srb_match && us->srb != srb_match) { +scsi_unlock (us_to_host (us)); +usb_stor_dbg (us,"-- pending command mismatch\n" );return FAILED ; }
@@ -445,6 +448,14 @@ static int command_abort(struct scsi_cmnreturn SUCCESS ; } +static int command_abort (struct scsi_cmnd *srb) +{ +struct us_data *us =host_to_us (srb->device->host); + +usb_stor_dbg (us,"%s called\n" , __func__); +return command_abort_matching (us, srb); +} +/* * This invokes the transport reset mechanism to reset the state of the * device
@@ -456,6 +467,9 @@ static int device_reset(struct scsi_cmndusb_stor_dbg (us,"%s called\n" , __func__); +/* abort any pending command before reset */ +command_abort_matching (us,NULL ); +/* lock the device pointers and do the reset */ mutex_lock (&(us->dev_mutex)); result = us->transport_reset (us);
Greg Kroah-Hartman
maintainerPATCH 83/161 USB: UHCI: adjust zhaoxin UHCI controllers OverCurrent bit value
In reply to Greg Kroah-HartmanFrom: Weitao Wang <[email protected]>
commit dddb342b5b9e482bb213aecc08cbdb201ea4f8da upstream.
OverCurrent condition is not standardized in the UHCI spec. Zhaoxin UHCI controllers report OverCurrent bit active off. In order to handle OverCurrent condition correctly, the uhci-hcd driver needs to be told to expect the active-off behavior.
--- drivers/usb/host/uhci-pci.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/usb/host/uhci-pci.c +6 -4
@@ -119,11 +119,13 @@ static int uhci_pci_init(struct usb_hcd uhci->rh_numports =uhci_count_ports (hcd); -/* Intel controllers report the OverCurrent bit active on. -* VIA controllers report it active off, so we'll adjust the -* bit value. (It's not standardized in the UHCI spec.) +/* +* Intel controllers report the OverCurrent bit active on. VIA +* and ZHAOXIN controllers report it active off, so we'll adjust +* the bit value. (It's not standardized in the UHCI spec.) */ -if (to_pci_dev (uhci_dev (uhci))->vendor ==PCI_VENDOR_ID_VIA ) +if (to_pci_dev (uhci_dev (uhci))->vendor ==PCI_VENDOR_ID_VIA || +to_pci_dev (uhci_dev (uhci))->vendor ==PCI_VENDOR_ID_ZHAOXIN ) uhci->oc_low =1 ;/* HP's server management chip requires a longer port reset delay. */
Greg Kroah-Hartman
maintainerPATCH 84/161 usb: dwc3: debugfs: Resume dwc3 before accessing registers
In reply to Greg Kroah-HartmanFrom: Udipto Goswami <[email protected]>
commit 614ce6a2ea50068b45339257891e51e639ac9001 upstream.
When the dwc3 device is runtime suspended, various required clocks are in disabled state and it is not guaranteed that access to any registers would work. Depending on the SoC glue, a register read could be as benign as returning 0 or be fatal enough to hang the system.
In order to prevent such scenarios of fatal errors, make sure to resume dwc3 then allow the function to proceed.
--- drivers/usb/dwc3/debugfs.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
drivers/usb/dwc3/debugfs.c +109 -0
@@ -327,6 +327,11 @@ static int dwc3_lsp_show(struct seq_fileunsigned int current_mode;unsigned long flags;u32 reg; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); reg =dwc3_readl (dwc->regs,DWC3_GSTS );
@@ -345,6 +350,8 @@ static int dwc3_lsp_show(struct seq_file }spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -390,6 +397,11 @@ static int dwc3_mode_show(struct seq_filstruct dwc3 *dwc = s->private;unsigned long flags;u32 reg; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); reg =dwc3_readl (dwc->regs,DWC3_GCTL );
@@ -409,6 +421,8 @@ static int dwc3_mode_show(struct seq_filseq_printf (s,"UNKNOWN %08x\n" ,DWC3_GCTL_PRTCAP (reg)); } +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -455,6 +469,11 @@ static int dwc3_testmode_show(struct seqstruct dwc3 *dwc = s->private;unsigned long flags;u32 reg; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); reg =dwc3_readl (dwc->regs,DWC3_DCTL );
@@ -485,6 +504,8 @@ static int dwc3_testmode_show(struct seqseq_printf (s,"UNKNOWN %d\n" , reg); } +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -501,6 +522,7 @@ static ssize_t dwc3_testmode_write(strucunsigned long flags;u32 testmode =0 ;char buf[32 ]; +int ret;if (copy_from_user (&buf, ubuf,min_t (size_t,sizeof (buf) -1 , count)))return -EFAULT ;
@@ -518,10 +540,16 @@ static ssize_t dwc3_testmode_write(strucelse testmode =0 ; + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret; +spin_lock_irqsave (&dwc->lock, flags);dwc3_gadget_set_test_mode (dwc, testmode);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return count; }
@@ -540,12 +568,18 @@ static int dwc3_link_state_show(struct senum dwc3_link_state state;u32 reg;u8 speed; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); reg =dwc3_readl (dwc->regs,DWC3_GSTS );if (DWC3_GSTS_CURMOD (reg) !=DWC3_GSTS_CURMOD_DEVICE ) {seq_puts (s,"Not available\n" );spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev);return 0 ; }
@@ -558,6 +592,8 @@ static int dwc3_link_state_show(struct s dwc3_gadget_hs_link_string(state));spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -576,6 +612,7 @@ static ssize_t dwc3_link_state_write(strchar buf[32 ];u32 reg;u8 speed; +int ret;if (copy_from_user (&buf, ubuf,min_t (size_t,sizeof (buf) -1 , count)))return -EFAULT ;
@@ -595,10 +632,15 @@ static ssize_t dwc3_link_state_write(strelse return -EINVAL ; + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret; +spin_lock_irqsave (&dwc->lock, flags); reg =dwc3_readl (dwc->regs,DWC3_GSTS );if (DWC3_GSTS_CURMOD (reg) !=DWC3_GSTS_CURMOD_DEVICE ) {spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev);return -EINVAL ; }
@@ -608,12 +650,15 @@ static ssize_t dwc3_link_state_write(strif (speed <DWC3_DSTS_SUPERSPEED && state !=DWC3_LINK_STATE_RECOV ) {spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev);return -EINVAL ; }dwc3_gadget_set_link_state (dwc, state);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return count; }
@@ -636,6 +681,11 @@ static int dwc3_tx_fifo_size_show(structstruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_TXFIFO );
@@ -646,6 +696,8 @@ static int dwc3_tx_fifo_size_show(structseq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -655,6 +707,11 @@ static int dwc3_rx_fifo_size_show(structstruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_RXFIFO );
@@ -665,6 +722,8 @@ static int dwc3_rx_fifo_size_show(structseq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -674,12 +733,19 @@ static int dwc3_tx_request_queue_show(ststruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_TXREQQ );seq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -689,12 +755,19 @@ static int dwc3_rx_request_queue_show(ststruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_RXREQQ );seq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -704,12 +777,19 @@ static int dwc3_rx_info_queue_show(strucstruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_RXINFOQ );seq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -719,12 +799,19 @@ static int dwc3_descriptor_fetch_queue_sstruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_DESCFETCHQ );seq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -734,12 +821,19 @@ static int dwc3_event_queue_show(structstruct dwc3 *dwc = dep->dwc;unsigned long flags;u32 val; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); val =dwc3_core_fifo_space (dep,DWC3_EVENTQ );seq_printf (s,"%u\n" , val);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -785,6 +879,11 @@ static int dwc3_trb_ring_show(struct seqstruct dwc3 *dwc = dep->dwc;unsigned long flags;int i; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags);if (dep->number <=1 ) {
@@ -814,6 +913,8 @@ static int dwc3_trb_ring_show(struct seq out:spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -826,6 +927,11 @@ static int dwc3_ep_info_register_show(stu32 lower_32_bits;u32 upper_32_bits;u32 reg; +int ret; + + ret =pm_runtime_resume_and_get (dwc->dev); +if (ret <0 ) +return ret;spin_lock_irqsave (&dwc->lock, flags); reg =DWC3_GDBGLSPMUX_EPSELECT (dep->number);
@@ -838,6 +944,8 @@ static int dwc3_ep_info_register_show(stseq_printf (s,"0x%016llx\n" , ep_info);spin_unlock_irqrestore (&dwc->lock, flags); +pm_runtime_put_sync (dwc->dev); +return 0 ; }
@@ -899,6 +1007,7 @@ void dwc3_debugfs_init(struct dwc3 *dwc) dwc->regset->regs = dwc3_regs; dwc->regset->nregs =ARRAY_SIZE (dwc3_regs); dwc->regset->base = dwc->regs -DWC3_GLOBALS_REGS_START ; + dwc->regset->dev = dwc->dev; root =debugfs_create_dir (dev_name (dwc->dev),NULL ); dwc->root = root;
Greg Kroah-Hartman
maintainerPATCH 85/161 usb: typec: altmodes/displayport: fix pin_assignment_show
In reply to Greg Kroah-HartmanFrom: Badhri Jagan Sridharan <[email protected]>
commit d8f28269dd4bf9b55c3fb376ae31512730a96fce upstream.
This patch fixes negative indexing of buf array in pin_assignment_show when get_current_pin_assignments returns 0 i.e. no compatible pin assignments are found.
BUG: KASAN: use-after-free in pin_assignment_show+0x26c/0x33c ... Call trace: dump_backtrace+0x110/0x204 dump_stack_lvl+0x84/0xbc print_report+0x358/0x974 kasan_report+0x9c/0xfc __do_kernel_fault+0xd4/0x2d4 do_bad_area+0x48/0x168 do_tag_check_fault+0x24/0x38 do_mem_abort+0x6c/0x14c el1_abort+0x44/0x68 el1h_64_sync_handler+0x64/0xa4 el1h_64_sync+0x78/0x7c pin_assignment_show+0x26c/0x33c dev_attr_show+0x50/0xc0
--- drivers/usb/typec/altmodes/displayport.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/usb/typec/altmodes/displayport.c +4 -0
@@ -501,6 +501,10 @@ static ssize_t pin_assignment_show(strucmutex_unlock (&dp->lock); +/* get_current_pin_assignments can return 0 when no matching pin assignments are found */ +if (len ==0 ) + len++; + buf[len -1 ] ='\n' ;return len; }
Greg Kroah-Hartman
maintainerPATCH 86/161 ALSA: hda: Fix Oops by 9.1 surround channel names
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 3b44ec8c5c44790a82f07e90db45643c762878c6 upstream.
get_line_out_pfx() may trigger an Oops by overflowing the static array with more than 8 channels. This was reported for MacBookPro 12,1 with Cirrus codec.
As a workaround, extend for the 9.1 channels and also fix the potential Oops by unifying the code paths accessing the same array with the proper size check.
--- sound/pci/hda/hda_generic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
sound/pci/hda/hda_generic.c +4 -3
@@ -1147,8 +1147,8 @@ static bool path_has_mixer(struct hda_coreturn path && path->ctls[ctl_type]; } -static const char *const channel_name[4 ] = { -"Front" ,"Surround" ,"CLFE" ,"Side" +static const char *const channel_name[] = { +"Front" ,"Surround" ,"CLFE" ,"Side" ,"Back" , };/* give some appropriate ctl name prefix for the given line out channel */
@@ -1174,7 +1174,7 @@ static const char *get_line_out_pfx(stru/* multi-io channels */ if (ch >= cfg->line_outs) -return channel_name[ch]; + goto fixed_name;switch (cfg->line_out_type) {case AUTO_PIN_SPEAKER_OUT :
@@ -1226,6 +1226,7 @@ static const char *get_line_out_pfx(struif (cfg->line_outs ==1 && !spec->multi_ios)return "Line Out" ; + fixed_name:if (ch >=ARRAY_SIZE (channel_name)) {snd_BUG ();return "PCM" ;
Greg Kroah-Hartman
maintainerPATCH 87/161 ALSA: hda: Add NVIDIA codec IDs a3 through a7 to patch table
In reply to Greg Kroah-HartmanFrom: Nikhil Mahale <[email protected]>
commit dc4f2ccaedddb489a83e7b12ebbdc347272aacc9 upstream.
These IDs are for AD102, AD103, AD104, AD106, and AD107 gpus with audio functions that are largely similar to the existing ones.
Tested audio using gnome-settings, over HDMI, DP-SST and DP-MST connections on AD106 gpu.
--- sound/pci/hda/patch_hdmi.c | 5 +++++ 1 file changed, 5 insertions(+)
sound/pci/hda/patch_hdmi.c +5 -0
@@ -4197,6 +4197,11 @@ HDA_CODEC_ENTRY(0x10de009d, "GPU 9d HDMIHDA_CODEC_ENTRY (0x10de009e ,"GPU 9e HDMI/DP" , patch_nvhdmi),HDA_CODEC_ENTRY (0x10de009f ,"GPU 9f HDMI/DP" , patch_nvhdmi),HDA_CODEC_ENTRY (0x10de00a0 ,"GPU a0 HDMI/DP" , patch_nvhdmi), +HDA_CODEC_ENTRY (0x10de00a3 ,"GPU a3 HDMI/DP" , patch_nvhdmi), +HDA_CODEC_ENTRY (0x10de00a4 ,"GPU a4 HDMI/DP" , patch_nvhdmi), +HDA_CODEC_ENTRY (0x10de00a5 ,"GPU a5 HDMI/DP" , patch_nvhdmi), +HDA_CODEC_ENTRY (0x10de00a6 ,"GPU a6 HDMI/DP" , patch_nvhdmi), +HDA_CODEC_ENTRY (0x10de00a7 ,"GPU a7 HDMI/DP" , patch_nvhdmi),HDA_CODEC_ENTRY (0x10de8001 ,"MCP73 HDMI" , patch_nvhdmi_2ch),HDA_CODEC_ENTRY (0x10de8067 ,"MCP67/68 HDMI" , patch_nvhdmi_2ch), HDA_CODEC_ENTRY(0x11069f80, "VX900 HDMI/DP", patch_via_hdmi),
Greg Kroah-Hartman
maintainerPATCH 88/161 ALSA: hda/realtek: Add a quirk for HP EliteDesk 805
In reply to Greg Kroah-HartmanFrom: Ai Chao <[email protected]>
commit 90670ef774a8b6700c38ce1222e6aa263be54d5f upstream.
Add a quirk for HP EliteDesk 805 to fixup ALC3867 headset MIC no sound.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -10342,6 +10342,7 @@ static const struct snd_pci_quirk alc662SND_PCI_QUIRK (0x103c ,0x1632 ,"HP RP5800" ,ALC662_FIXUP_HP_RP5800 ),SND_PCI_QUIRK (0x103c ,0x870c ,"HP" ,ALC897_FIXUP_HP_HSMIC_VERB ),SND_PCI_QUIRK (0x103c ,0x8719 ,"HP" ,ALC897_FIXUP_HP_HSMIC_VERB ), +SND_PCI_QUIRK (0x103c ,0x872b ,"HP" ,ALC897_FIXUP_HP_HSMIC_VERB ),SND_PCI_QUIRK (0x103c ,0x873e ,"HP" ,ALC671_FIXUP_HP_HEADSET_MIC2 ),SND_PCI_QUIRK (0x103c ,0x877e ,"HP 288 Pro G6" ,ALC671_FIXUP_HP_HEADSET_MIC2 ), SND_PCI_QUIRK(0x103c, 0x885f, "HP 288 Pro G8", ALC671_FIXUP_HP_HEADSET_MIC2),
Greg Kroah-Hartman
maintainerPATCH 89/161 ALSA: hda/realtek: Add quirk for 2nd ASUS GU603
In reply to Greg Kroah-HartmanFrom: Luke D. Jones <[email protected]>
commit a4671b7fba59775845ee60cfbdfc4ba64300211b upstream.
Add quirk for GU603 with 0x1c62 variant of codec.
--- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_realtek.c +1 -0
@@ -8273,6 +8273,7 @@ static const struct snd_pci_quirk alc269SND_PCI_QUIRK (0x1043 ,0x1b13 ,"Asus U41SV" ,ALC269_FIXUP_INV_DMIC ),SND_PCI_QUIRK (0x1043 ,0x1bbd ,"ASUS Z550MA" ,ALC255_FIXUP_ASUS_MIC_NO_PRESENCE ),SND_PCI_QUIRK (0x1043 ,0x1c23 ,"Asus X55U" ,ALC269_FIXUP_LIMIT_INT_MIC_BOOST ), +SND_PCI_QUIRK (0x1043 ,0x1c62 ,"ASUS GU603" ,ALC289_FIXUP_ASUS_GA401 ),SND_PCI_QUIRK (0x1043 ,0x1c92 ,"ASUS ROG Strix G15" ,ALC285_FIXUP_ASUS_G533Z_PINS ),SND_PCI_QUIRK (0x1043 ,0x1ccd ,"ASUS X555UB" ,ALC256_FIXUP_ASUS_MIC ), SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
Greg Kroah-Hartman
maintainerPATCH 90/161 can: j1939: recvmsg(): allow MSG_CMSG_COMPAT flag
In reply to Greg Kroah-HartmanFrom: Oliver Hartkopp <[email protected]>
commit 1db080cbdbab28752bbb1c86d64daf96253a5da1 upstream.
The control message provided by J1939 support MSG_CMSG_COMPAT but blocked recvmsg() syscalls that have set this flag, i.e. on 32bit user space on 64 bit kernels.
--- net/can/j1939/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/can/j1939/socket.c +1 -1
@@ -798,7 +798,7 @@ static int j1939_sk_recvmsg(struct sockestruct j1939_sk_buff_cb *skcb;int ret =0 ; -if (flags & ~(MSG_DONTWAIT |MSG_ERRQUEUE )) +if (flags & ~(MSG_DONTWAIT |MSG_ERRQUEUE |MSG_CMSG_COMPAT ))return -EINVAL ;if (flags &MSG_ERRQUEUE )
Greg Kroah-Hartman
maintainerPATCH 91/161 can: kvaser_pciefd: Set CAN_STATE_STOPPED in kvaser_pciefd_stop()
In reply to Greg Kroah-HartmanFrom: Jimmy Assarsson <[email protected]>
commit aed0e6ca7dbb8fbea9bc69c9ac663d5533c8c5d8 upstream.
Set can.state to CAN_STATE_STOPPED in kvaser_pciefd_stop(). Without this fix, wrong CAN state was repported after the interface was brought down.
--- drivers/net/can/kvaser_pciefd.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/can/kvaser_pciefd.c +1 -0
@@ -719,6 +719,7 @@ static int kvaser_pciefd_stop(struct netiowrite32 (0 , can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG );del_timer (&can->bec_poll_timer); } + can->can.state =CAN_STATE_STOPPED ;close_candev (netdev);return ret;
Greg Kroah-Hartman
maintainerPATCH 92/161 can: kvaser_pciefd: Call request_irq() before enabling interrupts
In reply to Greg Kroah-HartmanFrom: Jimmy Assarsson <[email protected]>
commit 84762d8da89d29ba842317eb842973e628c27391 upstream.
Make sure the interrupt handler is registered before enabling interrupts.
--- drivers/net/can/kvaser_pciefd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/net/can/kvaser_pciefd.c +5 -5
@@ -1823,6 +1823,11 @@ static int kvaser_pciefd_probe(struct pcif (err) goto err_teardown_can_ctrls; + err =request_irq (pcie->pci->irq, kvaser_pciefd_irq_handler, +IRQF_SHARED ,KVASER_PCIEFD_DRV_NAME , pcie); +if (err) + goto err_teardown_can_ctrls; +iowrite32 (KVASER_PCIEFD_SRB_IRQ_DPD0 |KVASER_PCIEFD_SRB_IRQ_DPD1 , pcie->reg_base +KVASER_PCIEFD_SRB_IRQ_REG );
@@ -1843,11 +1848,6 @@ static int kvaser_pciefd_probe(struct pciowrite32 (KVASER_PCIEFD_SRB_CMD_RDB1 , pcie->reg_base +KVASER_PCIEFD_SRB_CMD_REG ); - err =request_irq (pcie->pci->irq, kvaser_pciefd_irq_handler, -IRQF_SHARED ,KVASER_PCIEFD_DRV_NAME , pcie); -if (err) - goto err_teardown_can_ctrls; - err =kvaser_pciefd_reg_candev (pcie);if (err) goto err_free_irq;
Greg Kroah-Hartman
maintainerPATCH 93/161 can: kvaser_pciefd: Empty SRB buffer in probe
In reply to Greg Kroah-HartmanFrom: Jimmy Assarsson <[email protected]>
commit c589557dd1426f5adf90c7a919d4fde5a3e4ef64 upstream.
Empty the "Shared receive buffer" (SRB) in probe, to assure we start in a known state, and don't process any irrelevant packets.
--- drivers/net/can/kvaser_pciefd.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/net/can/kvaser_pciefd.c +15 -0
@@ -70,10 +70,12 @@ MODULE_DESCRIPTION("CAN driver for Kvase#define KVASER_PCIEFD_SYSID_BUILD_REG (KVASER_PCIEFD_SYSID_BASE + 0x14)/* Shared receive buffer registers */ #define KVASER_PCIEFD_SRB_BASE 0x1f200 +#define KVASER_PCIEFD_SRB_FIFO_LAST_REG (KVASER_PCIEFD_SRB_BASE + 0x1f4)#define KVASER_PCIEFD_SRB_CMD_REG (KVASER_PCIEFD_SRB_BASE + 0x200)#define KVASER_PCIEFD_SRB_IEN_REG (KVASER_PCIEFD_SRB_BASE + 0x204)#define KVASER_PCIEFD_SRB_IRQ_REG (KVASER_PCIEFD_SRB_BASE + 0x20c)#define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210) +#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214)#define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218)/* EPCS flash controller registers */ #define KVASER_PCIEFD_SPI_BASE 0x1fc00
@@ -110,6 +112,9 @@ MODULE_DESCRIPTION("CAN driver for Kvase/* DMA support */ #define KVASER_PCIEFD_SRB_STAT_DMA BIT(24) +/* SRB current packet level */ +#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK 0xff +/* DMA Enable */ #define KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE BIT(0)
@@ -1053,6 +1058,7 @@ static int kvaser_pciefd_setup_dma(struc {int i;u32 srb_status; +u32 srb_packet_count;dma_addr_t dma_addr[KVASER_PCIEFD_DMA_COUNT ];/* Disable the DMA */
@@ -1080,6 +1086,15 @@ static int kvaser_pciefd_setup_dma(strucKVASER_PCIEFD_SRB_CMD_RDB1 , pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); +/* Empty Rx FIFO */ + srb_packet_count =ioread32 (pcie->reg_base +KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG ) & +KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK ; +while (srb_packet_count) { +/* Drop current packet in FIFO */ +ioread32 (pcie->reg_base +KVASER_PCIEFD_SRB_FIFO_LAST_REG ); + srb_packet_count--; + } + srb_status =ioread32 (pcie->reg_base +KVASER_PCIEFD_SRB_STAT_REG );if (!(srb_status &KVASER_PCIEFD_SRB_STAT_DI )) {dev_err (&pcie->pci->dev,"DMA not idle before enabling\n" );
Greg Kroah-Hartman
maintainerPATCH 94/161 can: kvaser_pciefd: Clear listen-only bit if not explicitly requested
In reply to Greg Kroah-HartmanFrom: Jimmy Assarsson <[email protected]>
commit bf7ac55e991ca177f1ac16be51152f1ef291a4df upstream.
The listen-only bit was never cleared, causing the controller to always use listen-only mode, if previously set.
--- drivers/net/can/kvaser_pciefd.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/can/kvaser_pciefd.c +2 -0
@@ -561,6 +561,8 @@ static void kvaser_pciefd_setup_controllif (can->can.ctrlmode &CAN_CTRLMODE_LISTENONLY ) mode |=KVASER_PCIEFD_KCAN_MODE_LOM ; +else + mode &= ~KVASER_PCIEFD_KCAN_MODE_LOM ; mode |=KVASER_PCIEFD_KCAN_MODE_EEN ; mode |=KVASER_PCIEFD_KCAN_MODE_EPEN ;
Greg Kroah-Hartman
maintainerPATCH 95/161 can: kvaser_pciefd: Do not send EFLUSH command on TFD interrupt
In reply to Greg Kroah-HartmanFrom: Jimmy Assarsson <[email protected]>
commit 262d7a52ba27525e3c1203230c9f0524e48bbb34 upstream.
Under certain circumstances we send two EFLUSH commands, resulting in two EFLUSH ack packets, while only expecting a single EFLUSH ack. This can cause the driver Tx flush completion to get out of sync.
To avoid this problem, don't enable the "Transmit buffer flush done" (TFD) interrupt and remove the code handling it.
Now we only send EFLUSH command after receiving status packet with "Init detected" (IDET) bit set.
--- drivers/net/can/kvaser_pciefd.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-)
drivers/net/can/kvaser_pciefd.c +4 -17
@@ -533,7 +533,7 @@ static int kvaser_pciefd_set_tx_irq(struKVASER_PCIEFD_KCAN_IRQ_TOF |KVASER_PCIEFD_KCAN_IRQ_ABD |KVASER_PCIEFD_KCAN_IRQ_TAE |KVASER_PCIEFD_KCAN_IRQ_TAL |KVASER_PCIEFD_KCAN_IRQ_FDIC |KVASER_PCIEFD_KCAN_IRQ_BPP | -KVASER_PCIEFD_KCAN_IRQ_TAR |KVASER_PCIEFD_KCAN_IRQ_TFD ; +KVASER_PCIEFD_KCAN_IRQ_TAR ;iowrite32 (msk, can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG );
@@ -581,7 +581,7 @@ static void kvaser_pciefd_start_controllspin_lock_irqsave (&can->lock, irq);iowrite32 (-1 , can->reg_base +KVASER_PCIEFD_KCAN_IRQ_REG ); -iowrite32 (KVASER_PCIEFD_KCAN_IRQ_ABD |KVASER_PCIEFD_KCAN_IRQ_TFD , +iowrite32 (KVASER_PCIEFD_KCAN_IRQ_ABD , can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG ); status =ioread32 (can->reg_base +KVASER_PCIEFD_KCAN_STAT_REG );
@@ -624,7 +624,7 @@ static int kvaser_pciefd_bus_on(struct kiowrite32 (0 , can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG );iowrite32 (-1 , can->reg_base +KVASER_PCIEFD_KCAN_IRQ_REG ); -iowrite32 (KVASER_PCIEFD_KCAN_IRQ_ABD |KVASER_PCIEFD_KCAN_IRQ_TFD , +iowrite32 (KVASER_PCIEFD_KCAN_IRQ_ABD , can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG ); mode =ioread32 (can->reg_base +KVASER_PCIEFD_KCAN_MODE_REG );
@@ -1009,8 +1009,7 @@ static int kvaser_pciefd_setup_can_ctrlsSET_NETDEV_DEV (netdev, &pcie->pci->dev);iowrite32 (-1 , can->reg_base +KVASER_PCIEFD_KCAN_IRQ_REG ); -iowrite32 (KVASER_PCIEFD_KCAN_IRQ_ABD | -KVASER_PCIEFD_KCAN_IRQ_TFD , +iowrite32 (KVASER_PCIEFD_KCAN_IRQ_ABD , can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG ); pcie->can[i] = can;
@@ -1439,9 +1438,6 @@ static int kvaser_pciefd_handle_status_p cmd =KVASER_PCIEFD_KCAN_CMD_AT ; cmd |= ++can->cmd_seq <<KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT ;iowrite32 (cmd, can->reg_base +KVASER_PCIEFD_KCAN_CMD_REG ); - -iowrite32 (KVASER_PCIEFD_KCAN_IRQ_TFD , - can->reg_base +KVASER_PCIEFD_KCAN_IEN_REG ); } else if (p->header[0] & KVASER_PCIEFD_SPACK_IDET && p->header[0] & KVASER_PCIEFD_SPACK_IRM && cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK) &&
@@ -1730,15 +1726,6 @@ static int kvaser_pciefd_transmit_irq(stif (irq &KVASER_PCIEFD_KCAN_IRQ_TOF )netdev_err (can->can.dev,"Tx FIFO overflow\n" ); -if (irq &KVASER_PCIEFD_KCAN_IRQ_TFD ) { -u8 count =ioread32 (can->reg_base + -KVASER_PCIEFD_KCAN_TX_NPACKETS_REG ) &0xff ; - -if (count ==0 ) -iowrite32 (KVASER_PCIEFD_KCAN_CTRL_EFLUSH , - can->reg_base +KVASER_PCIEFD_KCAN_CTRL_REG ); - } -if (irq &KVASER_PCIEFD_KCAN_IRQ_BPP )netdev_err (can->can.dev,"Fail to change bittiming, when not in reset mode\n" );
Greg Kroah-Hartman
maintainerPATCH 96/161 can: kvaser_pciefd: Disable interrupts in probe error path
In reply to Greg Kroah-HartmanFrom: Jimmy Assarsson <[email protected]>
commit 11164bc39459335ab93c6e99d53b7e4292fba38b upstream.
Disable interrupts in error path of probe function.
--- drivers/net/can/kvaser_pciefd.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/can/kvaser_pciefd.c +2 -0
@@ -1859,6 +1859,8 @@ static int kvaser_pciefd_probe(struct pcreturn 0 ; err_free_irq: +/* Disable PCI interrupts */ +iowrite32 (0 , pcie->reg_base +KVASER_PCIEFD_IEN_REG );free_irq (pcie->pci->irq, pcie); err_teardown_can_ctrls:
Greg Kroah-Hartman
maintainerPATCH 97/161 KVM: x86: do not report a vCPU as preempted outside instruction boundaries
In reply to Greg Kroah-HartmanFrom: Paolo Bonzini <[email protected]>
commit 6cd88243c7e03845a450795e134b488fc2afb736 upstream.
If a vCPU is outside guest mode and is scheduled out, it might be in the process of making a memory access. A problem occurs if another vCPU uses the PV TLB flush feature during the period when the vCPU is scheduled out, and a virtual address has already been translated but has not yet been accessed, because this is equivalent to using a stale TLB entry.
To avoid this, only report a vCPU as preempted if sure that the guest is at an instruction boundary. A rescheduling request will be delivered to the host physical CPU as an external interrupt, so for simplicity consider any vmexit *not* instruction boundary except for external interrupts.
It would in principle be okay to report the vCPU as preempted also if it is sleeping in kvm_vcpu_block(): a TLB flush IPI will incur the vmentry/vmexit overhead unnecessarily, and optimistic spinning is also unlikely to succeed. However, leave it for later because right now kvm_vcpu_check_block() is doing memory accesses. Even though the TLB flush issue only applies to virtual memory address, it's very much preferrable to be conservative.
--- arch/x86/include/asm/kvm_host.h | 3 +++ arch/x86/kvm/svm.c | 3 ++- arch/x86/kvm/vmx/vmx.c | 1 + arch/x86/kvm/x86.c | 22 ++++++++++++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-)
arch/x86/include/asm/kvm_host.h +3 -0
@@ -563,6 +563,7 @@ struct kvm_vcpu_arch {u64 ia32_misc_enable_msr;u64 smbase;u64 smi_count; +bool at_instruction_boundary;bool tpr_access_reporting;u64 ia32_xss;u64 microcode_version;
@@ -981,6 +982,8 @@ struct kvm_vcpu_stat {u64 irq_injections;u64 nmi_injections;u64 req_event; +u64 preemption_reported; +u64 preemption_other; };struct x86_instruction_info ;
arch/x86/kvm/svm.c +2 -1
@@ -6246,7 +6246,8 @@ out:static void svm_handle_exit_irqoff (struct kvm_vcpu *vcpu) { - +if (to_svm (vcpu)->vmcb->control.exit_code ==SVM_EXIT_INTR ) + vcpu->arch.at_instruction_boundary = true; }static void svm_sched_in (struct kvm_vcpu *vcpu,int cpu)
arch/x86/kvm/vmx/vmx.c +1 -0
@@ -6358,6 +6358,7 @@ static void handle_external_interrupt_ir );kvm_after_interrupt (vcpu); + vcpu->arch.at_instruction_boundary = true; }STACK_FRAME_NON_STANDARD (handle_external_interrupt_irqoff);
arch/x86/kvm/x86.c +22 -0
@@ -207,6 +207,8 @@ struct kvm_stats_debugfs_item debugfs_en { "nmi_injections", VCPU_STAT(nmi_injections) }, { "req_event", VCPU_STAT(req_event) }, { "l1d_flush", VCPU_STAT(l1d_flush) }, + { "preemption_reported", VCPU_STAT(preemption_reported) }, + { "preemption_other", VCPU_STAT(preemption_other) }, { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) }, { "mmu_pte_write", VM_STAT(mmu_pte_write) }, { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
@@ -3562,6 +3564,19 @@ static void kvm_steal_time_set_preemptedstruct kvm_host_map map;struct kvm_steal_time *st; +/* +* The vCPU can be marked preempted if and only if the VM-Exit was on +* an instruction boundary and will not trigger guest emulation of any +* kind (see vcpu_run). Vendor specific code controls (conservatively) +* when this is true, for example allowing the vCPU to be marked +* preempted if and only if the VM-Exit was due to a host interrupt. +*/ +if (!vcpu->arch.at_instruction_boundary) { + vcpu->stat.preemption_other++; +return ; + } + + vcpu->stat.preemption_reported++;if (!(vcpu->arch.st.msr_val &KVM_MSR_ENABLED ))return ;
@@ -8446,6 +8461,13 @@ static int vcpu_run(struct kvm_vcpu *vcp vcpu->arch.l1tf_flush_l1d = true;for (;;) { +/* +* If another guest vCPU requests a PV TLB flush in the middle +* of instruction emulation, the rest of the emulation could +* use a stale page translation. Assume that any code after +* this point can start executing an instruction. +*/ + vcpu->arch.at_instruction_boundary = false;if (kvm_vcpu_running (vcpu)) { r =vcpu_enter_guest (vcpu); }else {
Greg Kroah-Hartman
maintainerPATCH 98/161 statfs: enforce statfs[64] structure initialization
In reply to Greg Kroah-HartmanFrom: Ilya Leoshkevich <[email protected]>
commit ed40866ec7d328b3dfb70db7e2011640a16202c3 upstream.
s390's struct statfs and struct statfs64 contain padding, which field-by-field copying does not set. Initialize the respective structs with zeros before filling them and copying them to userspace, like it's already done for the compat versions of these structs.
Found by KMSAN.
--- fs/statfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/statfs.c +2 -2
@@ -128,6 +128,7 @@ static int do_statfs_native(struct kstatif (sizeof (buf) ==sizeof (*st))memcpy (&buf, st,sizeof (*st));else { +memset (&buf,0 ,sizeof (buf));if (sizeof buf.f_blocks ==4 ) { if ((st->f_blocks | st->f_bfree | st->f_bavail | st->f_bsize | st->f_frsize) &
@@ -156,7 +157,6 @@ static int do_statfs_native(struct kstat buf.f_namelen = st->f_namelen; buf.f_frsize = st->f_frsize; buf.f_flags = st->f_flags; -memset (buf.f_spare,0 ,sizeof (buf.f_spare)); }if (copy_to_user (p, &buf,sizeof (buf)))return -EFAULT ;
@@ -169,6 +169,7 @@ static int do_statfs64(struct kstatfs *sif (sizeof (buf) ==sizeof (*st))memcpy (&buf, st,sizeof (*st));else { +memset (&buf,0 ,sizeof (buf)); buf.f_type = st->f_type; buf.f_bsize = st->f_bsize; buf.f_blocks = st->f_blocks;
@@ -180,7 +181,6 @@ static int do_statfs64(struct kstatfs *s buf.f_namelen = st->f_namelen; buf.f_frsize = st->f_frsize; buf.f_flags = st->f_flags; -memset (buf.f_spare,0 ,sizeof (buf.f_spare)); }if (copy_to_user (p, &buf,sizeof (buf)))return -EFAULT ;
Greg Kroah-Hartman
maintainerPATCH 99/161 serial: Add support for Advantech PCI-1611U card
In reply to Greg Kroah-HartmanFrom: Vitaliy Tomin <[email protected]>
commit d2b00516de0e1d696724247098f6733a6ea53908 upstream.
Add support for Advantech PCI-1611U card
Advantech provides opensource drivers for this and many others card based on legacy copy of 8250_pci driver called adv950
https://www.advantech.com/emt/support/details/driver?id=1-TDOIMJ
It is hard to maintain to run as out of tree module on newer kernels. Just adding PCI ID to kernel 8250_pci works perfect.
--- drivers/tty/serial/8250/8250_pci.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/tty/serial/8250/8250_pci.c +5 -0
@@ -1837,6 +1837,8 @@ pci_moxa_setup(struct serial_private *pr#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530#define PCI_VENDOR_ID_ADVANTECH 0x13fe#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66 +#define PCI_DEVICE_ID_ADVANTECH_PCI1600 0x1600 +#define PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 0x1611#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620#define PCI_DEVICE_ID_ADVANTECH_PCI3618 0x3618#define PCI_DEVICE_ID_ADVANTECH_PCIf618 0xf618
@@ -4157,6 +4159,9 @@ static SIMPLE_DEV_PM_OPS(pciserial_pm_op pciserial_resume_one);static const struct pci_device_id serial_pci_tbl[] = { + {PCI_VENDOR_ID_ADVANTECH ,PCI_DEVICE_ID_ADVANTECH_PCI1600 , +PCI_DEVICE_ID_ADVANTECH_PCI1600_1611 ,PCI_ANY_ID ,0 ,0 , + pbn_b0_4_921600 },/* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ {PCI_VENDOR_ID_ADVANTECH ,PCI_DEVICE_ID_ADVANTECH_PCI3620 ,PCI_DEVICE_ID_ADVANTECH_PCI3620 ,0x0001 ,0 ,0 ,
Greg Kroah-Hartman
maintainerPATCH 100/161 ceph: force updating the msg pointer in non-split case
In reply to Greg Kroah-HartmanFrom: Xiubo Li <[email protected]>
commit 4cafd0400bcb6187c0d4ab4d4b0229a89ac4f8c2 upstream.
When the MClientSnap reqeust's op is not CEPH_SNAP_OP_SPLIT the request may still contain a list of 'split_realms', and we need to skip it anyway. Or it will be parsed as a corrupt snaptrace.
--- fs/ceph/snap.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
fs/ceph/snap.c +13 -0
@@ -1005,6 +1005,19 @@ skip_inode:continue ;adjust_snap_realm_parent (mdsc, child, realm->ino); } + }else { +/* +* In the non-split case both 'num_split_inos' and +* 'num_split_realms' should be 0, making this a no-op. +* However the MDS happens to populate 'split_realms' list +* in one of the UPDATE op cases by mistake. +* +* Skip both lists just in case to ensure that 'p' is +* positioned at the start of realm info, as expected by +* ceph_update_snap_trace(). +*/ + p +=sizeof (u64) * num_split_inos; + p +=sizeof (u64) * num_split_realms; }/*
Greg Kroah-Hartman
maintainerPATCH 101/161 tpm/tpm_tis: Disable interrupts for more Lenovo devices
In reply to Greg Kroah-HartmanFrom: Jerry Snitselaar <[email protected]>
commit e7d3e5c4b1dd50a70b31524c3228c62bb41bbab2 upstream.
The P360 Tiny suffers from an irq storm issue like the T490s, so add an entry for it to tpm_tis_dmi_table, and force polling. There also previously was a report from the previous attempt to enable interrupts that involved a ThinkPad L490. So an entry is added for it as well.
--- drivers/char/tpm/tpm_tis.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/char/tpm/tpm_tis.c +16 -0
@@ -83,6 +83,22 @@ static const struct dmi_system_id tpm_ti DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"), }, }, + { + .callback = tpm_tis_disable_irq, + .ident = "ThinkStation P360 Tiny", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P360 Tiny"), + }, + }, + { + .callback = tpm_tis_disable_irq, + .ident = "ThinkPad L490", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"), + }, + }, {} };
Greg Kroah-Hartman
maintainerPATCH 102/161 powerpc/64s/radix: Fix soft dirty tracking
In reply to Greg Kroah-HartmanFrom: Michael Ellerman <[email protected]>
commit 66b2ca086210732954a7790d63d35542936fc664 upstream.
It was reported that soft dirty tracking doesn't work when using the Radix MMU.
The tracking is supposed to work by clearing the soft dirty bit for a mapping and then write protecting the PTE. If/when the page is written to, a page fault occurs and the soft dirty bit is added back via pte_mkdirty(). For example in wp_page_reuse():
entry = maybe_mkwrite(pte_mkdirty(entry), vma); if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1)) update_mmu_cache(vma, vmf->address, vmf->pte);
Unfortunately on radix _PAGE_SOFTDIRTY is being dropped by radix__ptep_set_access_flags(), called from ptep_set_access_flags(), meaning the soft dirty bit is not set even though the page has been written to.
Fix it by adding _PAGE_SOFTDIRTY to the set of bits that are able to be changed in radix__ptep_set_access_flags().
--- arch/powerpc/mm/book3s64/radix_pgtable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/mm/book3s64/radix_pgtable.c +2 -2
@@ -1018,8 +1018,8 @@ void radix__ptep_set_access_flags(struct pte_t entry, unsigned long address, int psize) { struct mm_struct *mm = vma->vm_mm; -unsigned long set =pte_val (entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_RW | _PAGE_EXEC); +unsigned long set =pte_val (entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY | + _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);unsigned long change =pte_val (entry) ^pte_val (*ptep);/*
Greg Kroah-Hartman
maintainerPATCH 103/161 nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode()
In reply to Greg Kroah-HartmanFrom: Ryusuke Konishi <[email protected]>
commit 9b5a04ac3ad9898c4745cba46ea26de74ba56a8e upstream.
During unmount process of nilfs2, nothing holds nilfs_root structure after nilfs2 detaches its writer in nilfs_detach_log_writer(). However, since nilfs_evict_inode() uses nilfs_root for some cleanup operations, it may cause use-after-free read if inodes are left in "garbage_list" and released by nilfs_dispose_list() at the end of nilfs_detach_log_writer().
Fix this issue by modifying nilfs_evict_inode() to only clear inode without additional metadata changes that use nilfs_root if the file system is degraded to read-only or the writer is detached.
--- fs/nilfs2/inode.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
fs/nilfs2/inode.c +18 -0
@@ -930,6 +930,7 @@ void nilfs_evict_inode(struct inode *inostruct nilfs_transaction_info ti;struct super_block *sb = inode->i_sb;struct nilfs_inode_info *ii =NILFS_I (inode); +struct the_nilfs *nilfs;int ret;if (inode->i_nlink || !ii->i_root ||unlikely (is_bad_inode (inode))) {
@@ -942,6 +943,23 @@ void nilfs_evict_inode(struct inode *inotruncate_inode_pages_final (&inode->i_data); + nilfs = sb->s_fs_info; +if (unlikely (sb_rdonly (sb) || !nilfs->ns_writer)) { +/* +* If this inode is about to be disposed after the file system +* has been degraded to read-only due to file system corruption +* or after the writer has been detached, do not make any +* changes that cause writes, just clear it. +* Do this check after read-locking ns_segctor_sem by +* nilfs_transaction_begin() in order to avoid a race with +* the writer detach operation. +*/ +clear_inode (inode); +nilfs_clear_inode (inode); +nilfs_transaction_abort (sb); +return ; + } +/* TODO: some of the following operations may fail. */ nilfs_truncate_bmap (ii,0 );nilfs_mark_inode_dirty (inode);
Greg Kroah-Hartman
maintainerPATCH 104/161 netfilter: nftables: add nft_parse_register_load() and use it
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 4f16d25c68ec844299a4df6ecbb0234eaf88a935 ]
This new function combines the netlink register attribute parser and the load validation function.
This update requires to replace:
enum nft_registers sreg:8;
in many of the expression private areas otherwise compiler complains with:
error: cannot take address of bit-field ‘sreg’
when passing the register field as reference.
--- include/net/netfilter/nf_tables.h | 2 +- include/net/netfilter/nf_tables_core.h | 4 +-- include/net/netfilter/nft_meta.h | 2 +- net/ipv4/netfilter/nft_dup_ipv4.c | 18 ++++++------- net/ipv6/netfilter/nft_dup_ipv6.c | 18 ++++++------- net/netfilter/nf_tables_api.c | 18 +++++++++++-- net/netfilter/nft_bitwise.c | 6 ++--- net/netfilter/nft_byteorder.c | 6 ++--- net/netfilter/nft_cmp.c | 8 +++--- net/netfilter/nft_ct.c | 5 ++-- net/netfilter/nft_dup_netdev.c | 6 ++--- net/netfilter/nft_dynset.c | 12 ++++----- net/netfilter/nft_exthdr.c | 6 ++--- net/netfilter/nft_fwd_netdev.c | 18 ++++++------- net/netfilter/nft_hash.c | 10 +++++--- net/netfilter/nft_lookup.c | 6 ++--- net/netfilter/nft_masq.c | 18 ++++++------- net/netfilter/nft_meta.c | 3 +-- net/netfilter/nft_nat.c | 35 +++++++++++--------------- net/netfilter/nft_objref.c | 6 ++--- net/netfilter/nft_payload.c | 4 +-- net/netfilter/nft_queue.c | 12 ++++----- net/netfilter/nft_range.c | 6 ++--- net/netfilter/nft_redir.c | 18 ++++++------- net/netfilter/nft_tproxy.c | 14 +++++------ 25 files changed, 129 insertions(+), 132 deletions(-)
include/net/netfilter/nf_tables.h +1 -1
@@ -208,7 +208,7 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);unsigned int nft_parse_register (const struct nlattr *attr);int nft_dump_register (struct sk_buff *skb,unsigned int attr,unsigned int reg); -int nft_validate_register_load (enum nft_registers reg,unsigned int len); +int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len); int nft_validate_register_store(const struct nft_ctx *ctx, enum nft_registers reg, const struct nft_data *data,
include/net/netfilter/nf_tables_core.h +2 -2
@@ -25,7 +25,7 @@ void nf_tables_core_module_exit(void);struct nft_cmp_fast_expr {u32 data; -enum nft_registers sreg:8 ; +u8 sreg;u8 len; };
@@ -58,7 +58,7 @@ struct nft_payload_set { enum nft_payload_bases base:8;u8 offset;u8 len; - enum nft_registers sreg:8; +u8 sreg;u8 csum_type;u8 csum_offset;u8 csum_flags;
include/net/netfilter/nft_meta.h +1 -1
@@ -8,7 +8,7 @@ struct nft_meta { enum nft_meta_keys key:8;union {enum nft_registers dreg:8 ; -enum nft_registers sreg:8 ; +u8 sreg; }; };
net/ipv4/netfilter/nft_dup_ipv4.c +9 -9
@@ -13,8 +13,8 @@#include <net/netfilter/ipv4/nf_dup_ipv4.h> struct nft_dup_ipv4 { -enum nft_registers sreg_addr:8 ; -enum nft_registers sreg_dev:8 ; +u8 sreg_addr; +u8 sreg_dev; }; static void nft_dup_ipv4_eval(const struct nft_expr *expr,
@@ -40,16 +40,16 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx,if (tb[NFTA_DUP_SREG_ADDR ] ==NULL )return -EINVAL ; - priv->sreg_addr =nft_parse_register (tb[NFTA_DUP_SREG_ADDR ]); - err =nft_validate_register_load (priv->sreg_addr,sizeof (struct in_addr )); + err =nft_parse_register_load (tb[NFTA_DUP_SREG_ADDR ], &priv->sreg_addr, +sizeof (struct in_addr ));if (err <0 )return err; -if (tb[NFTA_DUP_SREG_DEV ] !=NULL ) { - priv->sreg_dev =nft_parse_register (tb[NFTA_DUP_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); - } -return 0 ; +if (tb[NFTA_DUP_SREG_DEV ]) + err =nft_parse_register_load (tb[NFTA_DUP_SREG_DEV ], + &priv->sreg_dev,sizeof (int )); + +return err; }static int nft_dup_ipv4_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/ipv6/netfilter/nft_dup_ipv6.c +9 -9
@@ -13,8 +13,8 @@#include <net/netfilter/ipv6/nf_dup_ipv6.h> struct nft_dup_ipv6 { -enum nft_registers sreg_addr:8 ; -enum nft_registers sreg_dev:8 ; +u8 sreg_addr; +u8 sreg_dev; }; static void nft_dup_ipv6_eval(const struct nft_expr *expr,
@@ -38,16 +38,16 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx,if (tb[NFTA_DUP_SREG_ADDR ] ==NULL )return -EINVAL ; - priv->sreg_addr =nft_parse_register (tb[NFTA_DUP_SREG_ADDR ]); - err =nft_validate_register_load (priv->sreg_addr,sizeof (struct in6_addr )); + err =nft_parse_register_load (tb[NFTA_DUP_SREG_ADDR ], &priv->sreg_addr, +sizeof (struct in6_addr ));if (err <0 )return err; -if (tb[NFTA_DUP_SREG_DEV ] !=NULL ) { - priv->sreg_dev =nft_parse_register (tb[NFTA_DUP_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); - } -return 0 ; +if (tb[NFTA_DUP_SREG_DEV ]) + err =nft_parse_register_load (tb[NFTA_DUP_SREG_DEV ], + &priv->sreg_dev,sizeof (int )); + +return err; }static int nft_dup_ipv6_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nf_tables_api.c +16 -2
@@ -7432,7 +7432,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register);* Validate that the input register is one of the general purpose * registers and that the length of the load is within the bounds. */ -int nft_validate_register_load (enum nft_registers reg,unsigned int len) +static int nft_validate_register_load (enum nft_registers reg,unsigned int len) {if (reg <NFT_REG_1 *NFT_REG_SIZE /NFT_REG32_SIZE )return -EINVAL ;
@@ -7443,7 +7443,21 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len)return 0 ; } -EXPORT_SYMBOL_GPL (nft_validate_register_load); + +int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len) +{ +u32 reg; +int err; + + reg =nft_parse_register (attr); + err =nft_validate_register_load (reg, len); +if (err <0 ) +return err; + + *sreg = reg; +return 0 ; +} +EXPORT_SYMBOL_GPL (nft_parse_register_load);/** * nft_validate_register_store - validate an expressions' register store
net/netfilter/nft_bitwise.c +3 -3
@@ -16,7 +16,7 @@#include <net/netfilter/nf_tables_offload.h> struct nft_bitwise { -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;u8 len;struct nft_data mask;
@@ -65,8 +65,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx, priv->len = len; - priv->sreg =nft_parse_register (tb[NFTA_BITWISE_SREG ]); - err =nft_validate_register_load (priv->sreg, priv->len); + err =nft_parse_register_load (tb[NFTA_BITWISE_SREG ], &priv->sreg, + priv->len);if (err <0 )return err;
net/netfilter/nft_byteorder.c +3 -3
@@ -16,7 +16,7 @@#include <net/netfilter/nf_tables.h> struct nft_byteorder { -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;enum nft_byteorder_ops op:8 ;u8 len;
@@ -131,14 +131,14 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,return -EINVAL ; } - priv->sreg =nft_parse_register (tb[NFTA_BYTEORDER_SREG ]); err =nft_parse_u32_check (tb[NFTA_BYTEORDER_LEN ],U8_MAX , &len);if (err <0 )return err; priv->len = len; - err =nft_validate_register_load (priv->sreg, priv->len); + err =nft_parse_register_load (tb[NFTA_BYTEORDER_SREG ], &priv->sreg, + priv->len);if (err <0 )return err;
net/netfilter/nft_cmp.c +3 -5
@@ -17,7 +17,7 @@struct nft_cmp_expr {struct nft_data data; -enum nft_registers sreg:8 ; +u8 sreg;u8 len;enum nft_cmp_ops op:8 ; };
@@ -86,8 +86,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,return err; } - priv->sreg =nft_parse_register (tb[NFTA_CMP_SREG ]); - err =nft_validate_register_load (priv->sreg, desc.len); + err =nft_parse_register_load (tb[NFTA_CMP_SREG ], &priv->sreg, desc.len);if (err <0 )return err;
@@ -169,8 +168,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,if (err <0 )return err; - priv->sreg =nft_parse_register (tb[NFTA_CMP_SREG ]); - err =nft_validate_register_load (priv->sreg, desc.len); + err =nft_parse_register_load (tb[NFTA_CMP_SREG ], &priv->sreg, desc.len);if (err <0 )return err;
net/netfilter/nft_ct.c +2 -3
@@ -28,7 +28,7 @@ struct nft_ct { enum ip_conntrack_dir dir:8;union {enum nft_registers dreg:8 ; -enum nft_registers sreg:8 ; +u8 sreg; }; };
@@ -600,8 +600,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, } } - priv->sreg =nft_parse_register (tb[NFTA_CT_SREG ]); - err =nft_validate_register_load (priv->sreg, len); + err =nft_parse_register_load (tb[NFTA_CT_SREG ], &priv->sreg, len);if (err <0 ) goto err1;
net/netfilter/nft_dup_netdev.c +3 -3
@@ -14,7 +14,7 @@#include <net/netfilter/nf_dup_netdev.h> struct nft_dup_netdev { -enum nft_registers sreg_dev:8 ; +u8 sreg_dev; }; static void nft_dup_netdev_eval(const struct nft_expr *expr,
@@ -40,8 +40,8 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx,if (tb[NFTA_DUP_SREG_DEV ] ==NULL )return -EINVAL ; - priv->sreg_dev =nft_parse_register (tb[NFTA_DUP_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); +return nft_parse_register_load (tb[NFTA_DUP_SREG_DEV ], &priv->sreg_dev, +sizeof (int )); }static int nft_dup_netdev_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_dynset.c +6 -6
@@ -16,8 +16,8 @@ struct nft_dynset {struct nft_set *set;struct nft_set_ext_tmpl tmpl; enum nft_dynset_ops op:8; - enum nft_registers sreg_key:8; - enum nft_registers sreg_data:8; +u8 sreg_key; +u8 sreg_data;bool invert;u64 timeout;struct nft_expr *expr;
@@ -177,8 +177,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,return err; } - priv->sreg_key =nft_parse_register (tb[NFTA_DYNSET_SREG_KEY ]); - err =nft_validate_register_load (priv->sreg_key, set->klen); + err =nft_parse_register_load (tb[NFTA_DYNSET_SREG_KEY ], &priv->sreg_key, + set->klen);if (err <0 )return err;
@@ -188,8 +188,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,if (set->dtype ==NFT_DATA_VERDICT )return -EOPNOTSUPP ; - priv->sreg_data =nft_parse_register (tb[NFTA_DYNSET_SREG_DATA ]); - err =nft_validate_register_load (priv->sreg_data, set->dlen); + err =nft_parse_register_load (tb[NFTA_DYNSET_SREG_DATA ], + &priv->sreg_data, set->dlen);if (err <0 )return err; }else if (set->flags &NFT_SET_MAP )
net/netfilter/nft_exthdr.c +3 -3
@@ -20,7 +20,7 @@ struct nft_exthdr {u8 len;u8 op; enum nft_registers dreg:8; - enum nft_registers sreg:8; +u8 sreg;u8 flags; };
@@ -403,11 +403,11 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, priv->type =nla_get_u8 (tb[NFTA_EXTHDR_TYPE ]); priv->offset = offset; priv->len = len; - priv->sreg =nft_parse_register (tb[NFTA_EXTHDR_SREG ]); priv->flags = flags; priv->op = op; -return nft_validate_register_load (priv->sreg, priv->len); +return nft_parse_register_load (tb[NFTA_EXTHDR_SREG ], &priv->sreg, + priv->len); } static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx,
net/netfilter/nft_fwd_netdev.c +9 -9
@@ -18,7 +18,7 @@#include <net/ip.h> struct nft_fwd_netdev { -enum nft_registers sreg_dev:8 ; +u8 sreg_dev; }; static void nft_fwd_netdev_eval(const struct nft_expr *expr,
@@ -50,8 +50,8 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx,if (tb[NFTA_FWD_SREG_DEV ] ==NULL )return -EINVAL ; - priv->sreg_dev =nft_parse_register (tb[NFTA_FWD_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); +return nft_parse_register_load (tb[NFTA_FWD_SREG_DEV ], &priv->sreg_dev, +sizeof (int )); }static int nft_fwd_netdev_dump (struct sk_buff *skb,const struct nft_expr *expr)
@@ -83,8 +83,8 @@ static bool nft_fwd_netdev_offload_action(const struct nft_expr *expr) }struct nft_fwd_neigh { -enum nft_registers sreg_dev:8 ; -enum nft_registers sreg_addr:8 ; +u8 sreg_dev; +u8 sreg_addr;u8 nfproto; };
@@ -162,8 +162,6 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx, !tb[NFTA_FWD_NFPROTO])return -EINVAL ; - priv->sreg_dev =nft_parse_register (tb[NFTA_FWD_SREG_DEV ]); - priv->sreg_addr =nft_parse_register (tb[NFTA_FWD_SREG_ADDR ]); priv->nfproto =ntohl (nla_get_be32 (tb[NFTA_FWD_NFPROTO ]));switch (priv->nfproto) {
@@ -177,11 +175,13 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - err =nft_validate_register_load (priv->sreg_dev,sizeof (int )); + err =nft_parse_register_load (tb[NFTA_FWD_SREG_DEV ], &priv->sreg_dev, +sizeof (int ));if (err <0 )return err; -return nft_validate_register_load (priv->sreg_addr, addr_len); +return nft_parse_register_load (tb[NFTA_FWD_SREG_ADDR ], &priv->sreg_addr, + addr_len); }static int nft_fwd_neigh_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_hash.c +6 -4
@@ -14,7 +14,7 @@#include <linux/jhash.h> struct nft_jhash { -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;u8 len;bool autogen_seed:1 ;
@@ -83,7 +83,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,if (tb[NFTA_HASH_OFFSET ]) priv->offset =ntohl (nla_get_be32 (tb[NFTA_HASH_OFFSET ])); - priv->sreg =nft_parse_register (tb[NFTA_HASH_SREG ]); priv->dreg =nft_parse_register (tb[NFTA_HASH_DREG ]); err =nft_parse_u32_check (tb[NFTA_HASH_LEN ],U8_MAX , &len);
@@ -94,6 +93,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx, priv->len = len; + err =nft_parse_register_load (tb[NFTA_HASH_SREG ], &priv->sreg, len); +if (err <0 ) +return err; + priv->modulus =ntohl (nla_get_be32 (tb[NFTA_HASH_MODULUS ]));if (priv->modulus <1 )return -ERANGE ;
@@ -108,8 +111,7 @@ static int nft_jhash_init(const struct nft_ctx *ctx,get_random_bytes (&priv->seed,sizeof (priv->seed)); } -return nft_validate_register_load (priv->sreg, len) && -nft_validate_register_store (ctx, priv->dreg,NULL , +return nft_validate_register_store (ctx, priv->dreg,NULL ,NFT_DATA_VALUE ,sizeof (u32)); }
net/netfilter/nft_lookup.c +3 -3
@@ -17,7 +17,7 @@struct nft_lookup {struct nft_set *set; -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;bool invert;struct nft_set_binding binding;
@@ -73,8 +73,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,if (IS_ERR (set))return PTR_ERR (set); - priv->sreg =nft_parse_register (tb[NFTA_LOOKUP_SREG ]); - err =nft_validate_register_load (priv->sreg, set->klen); + err =nft_parse_register_load (tb[NFTA_LOOKUP_SREG ], &priv->sreg, + set->klen);if (err <0 )return err;
net/netfilter/nft_masq.c +7 -11
@@ -15,8 +15,8 @@struct nft_masq {u32 flags; -enum nft_registers sreg_proto_min:8 ; -enum nft_registers sreg_proto_max:8 ; +u8 sreg_proto_min; +u8 sreg_proto_max; };static const struct nla_policy nft_masq_policy[NFTA_MASQ_MAX +1 ] = {
@@ -54,19 +54,15 @@ static int nft_masq_init(const struct nft_ctx *ctx, }if (tb[NFTA_MASQ_REG_PROTO_MIN ]) { - priv->sreg_proto_min = -nft_parse_register (tb[NFTA_MASQ_REG_PROTO_MIN ]); - - err =nft_validate_register_load (priv->sreg_proto_min, plen); + err =nft_parse_register_load (tb[NFTA_MASQ_REG_PROTO_MIN ], + &priv->sreg_proto_min, plen);if (err <0 )return err;if (tb[NFTA_MASQ_REG_PROTO_MAX ]) { - priv->sreg_proto_max = -nft_parse_register (tb[NFTA_MASQ_REG_PROTO_MAX ]); - - err =nft_validate_register_load (priv->sreg_proto_max, - plen); + err =nft_parse_register_load (tb[NFTA_MASQ_REG_PROTO_MAX ], + &priv->sreg_proto_max, + plen);if (err <0 )return err; }else {
net/netfilter/nft_meta.c +1 -2
@@ -475,8 +475,7 @@ int nft_meta_set_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->sreg =nft_parse_register (tb[NFTA_META_SREG ]); - err =nft_validate_register_load (priv->sreg, len); + err =nft_parse_register_load (tb[NFTA_META_SREG ], &priv->sreg, len);if (err <0 )return err;
net/netfilter/nft_nat.c +14 -21
@@ -21,10 +21,10 @@#include <net/ip.h> struct nft_nat { -enum nft_registers sreg_addr_min:8 ; -enum nft_registers sreg_addr_max:8 ; -enum nft_registers sreg_proto_min:8 ; -enum nft_registers sreg_proto_max:8 ; +u8 sreg_addr_min; +u8 sreg_addr_max; +u8 sreg_proto_min; +u8 sreg_proto_max;enum nf_nat_manip_type type:8 ;u8 family;u16 flags;
@@ -154,18 +154,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, priv->family = family;if (tb[NFTA_NAT_REG_ADDR_MIN ]) { - priv->sreg_addr_min = -nft_parse_register (tb[NFTA_NAT_REG_ADDR_MIN ]); - err =nft_validate_register_load (priv->sreg_addr_min, alen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_ADDR_MIN ], + &priv->sreg_addr_min, alen);if (err <0 )return err;if (tb[NFTA_NAT_REG_ADDR_MAX ]) { - priv->sreg_addr_max = -nft_parse_register (tb[NFTA_NAT_REG_ADDR_MAX ]); - - err =nft_validate_register_load (priv->sreg_addr_max, - alen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_ADDR_MAX ], + &priv->sreg_addr_max, + alen);if (err <0 )return err; }else {
@@ -175,19 +172,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);if (tb[NFTA_NAT_REG_PROTO_MIN ]) { - priv->sreg_proto_min = -nft_parse_register (tb[NFTA_NAT_REG_PROTO_MIN ]); - - err =nft_validate_register_load (priv->sreg_proto_min, plen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_PROTO_MIN ], + &priv->sreg_proto_min, plen);if (err <0 )return err;if (tb[NFTA_NAT_REG_PROTO_MAX ]) { - priv->sreg_proto_max = -nft_parse_register (tb[NFTA_NAT_REG_PROTO_MAX ]); - - err =nft_validate_register_load (priv->sreg_proto_max, - plen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_PROTO_MAX ], + &priv->sreg_proto_max, + plen);if (err <0 )return err; }else {
net/netfilter/nft_objref.c +3 -3
@@ -95,7 +95,7 @@ static const struct nft_expr_ops nft_objref_ops = {struct nft_objref_map {struct nft_set *set; -enum nft_registers sreg:8 ; +u8 sreg;struct nft_set_binding binding; };
@@ -137,8 +137,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,if (!(set->flags &NFT_SET_OBJECT ))return -EINVAL ; - priv->sreg =nft_parse_register (tb[NFTA_OBJREF_SET_SREG ]); - err =nft_validate_register_load (priv->sreg, set->klen); + err =nft_parse_register_load (tb[NFTA_OBJREF_SET_SREG ], &priv->sreg, + set->klen);if (err <0 )return err;
net/netfilter/nft_payload.c +2 -2
@@ -564,7 +564,6 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, priv->base =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_BASE ])); priv->offset =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_OFFSET ])); priv->len =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_LEN ])); - priv->sreg =nft_parse_register (tb[NFTA_PAYLOAD_SREG ]);if (tb[NFTA_PAYLOAD_CSUM_TYPE ]) csum_type =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_CSUM_TYPE ]));
@@ -595,7 +594,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, } priv->csum_type = csum_type; -return nft_validate_register_load (priv->sreg, priv->len); +return nft_parse_register_load (tb[NFTA_PAYLOAD_SREG ], &priv->sreg, + priv->len); }static int nft_payload_set_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_queue.c +6 -6
@@ -19,10 +19,10 @@static u32 jhash_initval__read_mostly ;struct nft_queue { -enum nft_registers sreg_qnum:8 ; -u16 queuenum; -u16 queues_total; -u16 flags; +u8 sreg_qnum; +u16 queuenum; +u16 queues_total; +u16 flags; }; static void nft_queue_eval(const struct nft_expr *expr,
@@ -111,8 +111,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx,struct nft_queue *priv =nft_expr_priv (expr);int err; - priv->sreg_qnum =nft_parse_register (tb[NFTA_QUEUE_SREG_QNUM ]); - err =nft_validate_register_load (priv->sreg_qnum,sizeof (u32)); + err =nft_parse_register_load (tb[NFTA_QUEUE_SREG_QNUM ], + &priv->sreg_qnum,sizeof (u32));if (err <0 )return err;
net/netfilter/nft_range.c +3 -3
@@ -15,7 +15,7 @@struct nft_range_expr {struct nft_data data_from;struct nft_data data_to; -enum nft_registers sreg:8 ; +u8 sreg;u8 len;enum nft_range_ops op:8 ; };
@@ -86,8 +86,8 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr goto err2; } - priv->sreg =nft_parse_register (tb[NFTA_RANGE_SREG ]); - err =nft_validate_register_load (priv->sreg, desc_from.len); + err =nft_parse_register_load (tb[NFTA_RANGE_SREG ], &priv->sreg, + desc_from.len);if (err <0 ) goto err2;
net/netfilter/nft_redir.c +7 -11
@@ -14,8 +14,8 @@#include <net/netfilter/nf_tables.h> struct nft_redir { -enum nft_registers sreg_proto_min:8 ; -enum nft_registers sreg_proto_max:8 ; +u8 sreg_proto_min; +u8 sreg_proto_max;u16 flags; };
@@ -50,19 +50,15 @@ static int nft_redir_init(const struct nft_ctx *ctx, plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);if (tb[NFTA_REDIR_REG_PROTO_MIN ]) { - priv->sreg_proto_min = -nft_parse_register (tb[NFTA_REDIR_REG_PROTO_MIN ]); - - err =nft_validate_register_load (priv->sreg_proto_min, plen); + err =nft_parse_register_load (tb[NFTA_REDIR_REG_PROTO_MIN ], + &priv->sreg_proto_min, plen);if (err <0 )return err;if (tb[NFTA_REDIR_REG_PROTO_MAX ]) { - priv->sreg_proto_max = -nft_parse_register (tb[NFTA_REDIR_REG_PROTO_MAX ]); - - err =nft_validate_register_load (priv->sreg_proto_max, - plen); + err =nft_parse_register_load (tb[NFTA_REDIR_REG_PROTO_MAX ], + &priv->sreg_proto_max, + plen);if (err <0 )return err; }else {
net/netfilter/nft_tproxy.c +7 -7
@@ -13,9 +13,9 @@#endif struct nft_tproxy { -enum nft_registers sreg_addr:8 ; -enum nft_registers sreg_port:8 ; -u8 family; +u8 sreg_addr; +u8 sreg_port; +u8 family; }; static void nft_tproxy_eval_v4(const struct nft_expr *expr,
@@ -254,15 +254,15 @@ static int nft_tproxy_init(const struct nft_ctx *ctx, }if (tb[NFTA_TPROXY_REG_ADDR ]) { - priv->sreg_addr =nft_parse_register (tb[NFTA_TPROXY_REG_ADDR ]); - err =nft_validate_register_load (priv->sreg_addr, alen); + err =nft_parse_register_load (tb[NFTA_TPROXY_REG_ADDR ], + &priv->sreg_addr, alen);if (err <0 )return err; }if (tb[NFTA_TPROXY_REG_PORT ]) { - priv->sreg_port =nft_parse_register (tb[NFTA_TPROXY_REG_PORT ]); - err =nft_validate_register_load (priv->sreg_port,sizeof (u16)); + err =nft_parse_register_load (tb[NFTA_TPROXY_REG_PORT ], + &priv->sreg_port,sizeof (u16));if (err <0 )return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 105/161 netfilter: nftables: add nft_parse_register_store() and use it
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 345023b0db315648ccc3c1a36aee88304a8b4d91 ]
This new function combines the netlink register attribute parser and the store validation function.
This update requires to replace:
enum nft_registers dreg:8;
in many of the expression private areas otherwise compiler complains with:
error: cannot take address of bit-field ‘dreg’
when passing the register field as reference.
--- include/net/netfilter/nf_tables.h | 8 +++--- include/net/netfilter/nf_tables_core.h | 4 +-- include/net/netfilter/nft_fib.h | 2 +- include/net/netfilter/nft_meta.h | 2 +- net/bridge/netfilter/nft_meta_bridge.c | 5 ++-- net/netfilter/nf_tables_api.c | 34 ++++++++++++++++++++++---- net/netfilter/nft_bitwise.c | 8 +++--- net/netfilter/nft_byteorder.c | 8 +++--- net/netfilter/nft_ct.c | 7 +++--- net/netfilter/nft_exthdr.c | 8 +++--- net/netfilter/nft_fib.c | 5 ++-- net/netfilter/nft_hash.c | 17 ++++++------- net/netfilter/nft_immediate.c | 6 ++--- net/netfilter/nft_lookup.c | 8 +++--- net/netfilter/nft_meta.c | 5 ++-- net/netfilter/nft_numgen.c | 15 +++++------- net/netfilter/nft_osf.c | 8 +++--- net/netfilter/nft_payload.c | 6 ++--- net/netfilter/nft_rt.c | 7 +++--- net/netfilter/nft_socket.c | 7 +++--- net/netfilter/nft_tunnel.c | 8 +++--- net/netfilter/nft_xfrm.c | 7 +++--- 22 files changed, 97 insertions(+), 88 deletions(-)
include/net/netfilter/nf_tables.h +4 -4
@@ -209,10 +209,10 @@ unsigned int nft_parse_register(const struct nlattr *attr);int nft_dump_register (struct sk_buff *skb,unsigned int attr,unsigned int reg);int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len); -int nft_validate_register_store (const struct nft_ctx *ctx, -enum nft_registers reg, -const struct nft_data *data, -enum nft_data_types type,unsigned int len); +int nft_parse_register_store (const struct nft_ctx *ctx, +const struct nlattr *attr,u8 *dreg, +const struct nft_data *data, +enum nft_data_types type,unsigned int len);/** * struct nft_userdata - user defined data associated with an object
include/net/netfilter/nf_tables_core.h +2 -2
@@ -31,7 +31,7 @@ struct nft_cmp_fast_expr {struct nft_immediate_expr {struct nft_data data; -enum nft_registers dreg:8 ; +u8 dreg;u8 dlen; };
@@ -51,7 +51,7 @@ struct nft_payload { enum nft_payload_bases base:8;u8 offset;u8 len; - enum nft_registers dreg:8; +u8 dreg; };struct nft_payload_set {
include/net/netfilter/nft_fib.h +1 -1
@@ -5,7 +5,7 @@#include <net/netfilter/nf_tables.h> struct nft_fib { -enum nft_registers dreg:8 ; +u8 dreg;u8 result;u32 flags; };
include/net/netfilter/nft_meta.h +1 -1
@@ -7,7 +7,7 @@struct nft_meta {enum nft_meta_keys key:8 ;union { -enum nft_registers dreg:8 ; +u8 dreg;u8 sreg; }; };
net/bridge/netfilter/nft_meta_bridge.c +2 -3
@@ -87,9 +87,8 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,return nft_meta_get_init (ctx, expr, tb); } - priv->dreg =nft_parse_register (tb[NFTA_META_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_META_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); }static struct nft_expr_type nft_meta_bridge_type;
net/netfilter/nf_tables_api.c +29 -5
@@ -3839,6 +3839,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,return nft_delset (&ctx, set); } +static int nft_validate_register_store (const struct nft_ctx *ctx, +enum nft_registers reg, +const struct nft_data *data, +enum nft_data_types type, +unsigned int len); + static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, struct nft_set *set, const struct nft_set_iter *iter,
@@ -7473,10 +7479,11 @@ EXPORT_SYMBOL_GPL(nft_parse_register_load);* A value of NULL for the data means that its runtime gathered * data. */ -int nft_validate_register_store (const struct nft_ctx *ctx, -enum nft_registers reg, -const struct nft_data *data, -enum nft_data_types type,unsigned int len) +static int nft_validate_register_store (const struct nft_ctx *ctx, +enum nft_registers reg, +const struct nft_data *data, +enum nft_data_types type, +unsigned int len) {int err;
@@ -7508,7 +7515,24 @@ int nft_validate_register_store(const struct nft_ctx *ctx,return 0 ; } } -EXPORT_SYMBOL_GPL (nft_validate_register_store); + +int nft_parse_register_store (const struct nft_ctx *ctx, +const struct nlattr *attr,u8 *dreg, +const struct nft_data *data, +enum nft_data_types type,unsigned int len) +{ +int err; +u32 reg; + + reg =nft_parse_register (attr); + err =nft_validate_register_store (ctx, reg, data, type, len); +if (err <0 ) +return err; + + *dreg = reg; +return 0 ; +} +EXPORT_SYMBOL_GPL (nft_parse_register_store);static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX +1 ] = { [NFTA_VERDICT_CODE ] = { .type =NLA_U32 },
net/netfilter/nft_bitwise.c +4 -4
@@ -17,7 +17,7 @@struct nft_bitwise {u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;u8 len;struct nft_data mask;struct nft_data xor;
@@ -70,9 +70,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,if (err <0 )return err; - priv->dreg =nft_parse_register (tb[NFTA_BITWISE_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); + err =nft_parse_register_store (ctx, tb[NFTA_BITWISE_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len);if (err <0 )return err;
net/netfilter/nft_byteorder.c +4 -4
@@ -17,7 +17,7 @@struct nft_byteorder {u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;enum nft_byteorder_ops op:8 ;u8 len;u8 size;
@@ -142,9 +142,9 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,if (err <0 )return err; - priv->dreg =nft_parse_register (tb[NFTA_BYTEORDER_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); +return nft_parse_register_store (ctx, tb[NFTA_BYTEORDER_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len); }static int nft_byteorder_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_ct.c +3 -4
@@ -27,7 +27,7 @@ struct nft_ct { enum nft_ct_keys key:8; enum ip_conntrack_dir dir:8;union { -enum nft_registers dreg:8 ; +u8 dreg;u8 sreg; }; };
@@ -498,9 +498,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, } } - priv->dreg =nft_parse_register (tb[NFTA_CT_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); + err =nft_parse_register_store (ctx, tb[NFTA_CT_DREG ], &priv->dreg,NULL , +NFT_DATA_VALUE , len);if (err <0 )return err;
net/netfilter/nft_exthdr.c +4 -4
@@ -19,7 +19,7 @@ struct nft_exthdr {u8 offset;u8 len;u8 op; - enum nft_registers dreg:8; +u8 dreg;u8 sreg;u8 flags; };
@@ -353,12 +353,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, priv->type =nla_get_u8 (tb[NFTA_EXTHDR_TYPE ]); priv->offset = offset; priv->len = len; - priv->dreg =nft_parse_register (tb[NFTA_EXTHDR_DREG ]); priv->flags = flags; priv->op = op; -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); +return nft_parse_register_store (ctx, tb[NFTA_EXTHDR_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len); } static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
net/netfilter/nft_fib.c +2 -3
@@ -86,7 +86,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,return -EINVAL ; priv->result =ntohl (nla_get_be32 (tb[NFTA_FIB_RESULT ])); - priv->dreg =nft_parse_register (tb[NFTA_FIB_DREG ]);switch (priv->result) {case NFT_FIB_RESULT_OIF :
@@ -106,8 +105,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,return -EINVAL ; } - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); + err =nft_parse_register_store (ctx, tb[NFTA_FIB_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len);if (err <0 )return err;
net/netfilter/nft_hash.c +7 -10
@@ -15,7 +15,7 @@struct nft_jhash {u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;u8 len;bool autogen_seed:1 ;u32 modulus;
@@ -38,7 +38,7 @@ static void nft_jhash_eval(const struct nft_expr *expr, }struct nft_symhash { -enum nft_registers dreg:8 ; +u8 dreg;u32 modulus;u32 offset; };
@@ -83,8 +83,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,if (tb[NFTA_HASH_OFFSET ]) priv->offset =ntohl (nla_get_be32 (tb[NFTA_HASH_OFFSET ])); - priv->dreg =nft_parse_register (tb[NFTA_HASH_DREG ]); - err =nft_parse_u32_check (tb[NFTA_HASH_LEN ],U8_MAX , &len);if (err <0 )return err;
@@ -111,8 +109,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx,get_random_bytes (&priv->seed,sizeof (priv->seed)); } -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_HASH_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE ,sizeof (u32)); } static int nft_symhash_init(const struct nft_ctx *ctx,
@@ -128,8 +126,6 @@ static int nft_symhash_init(const struct nft_ctx *ctx,if (tb[NFTA_HASH_OFFSET ]) priv->offset =ntohl (nla_get_be32 (tb[NFTA_HASH_OFFSET ])); - priv->dreg =nft_parse_register (tb[NFTA_HASH_DREG ]); - priv->modulus =ntohl (nla_get_be32 (tb[NFTA_HASH_MODULUS ]));if (priv->modulus <1 )return -ERANGE ;
@@ -137,8 +133,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx,if (priv->offset + priv->modulus -1 < priv->offset)return -EOVERFLOW ; -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_HASH_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , +sizeof (u32)); } static int nft_jhash_dump(struct sk_buff *skb,
net/netfilter/nft_immediate.c +3 -3
@@ -48,9 +48,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx, priv->dlen = desc.len; - priv->dreg =nft_parse_register (tb[NFTA_IMMEDIATE_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg, &priv->data, - desc.type, desc.len); + err =nft_parse_register_store (ctx, tb[NFTA_IMMEDIATE_DREG ], + &priv->dreg, &priv->data, desc.type, + desc.len);if (err <0 ) goto err1;
net/netfilter/nft_lookup.c +4 -4
@@ -18,7 +18,7 @@struct nft_lookup {struct nft_set *set;u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;bool invert;struct nft_set_binding binding; };
@@ -97,9 +97,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx,if (!(set->flags &NFT_SET_MAP ))return -EINVAL ; - priv->dreg =nft_parse_register (tb[NFTA_LOOKUP_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , - set->dtype, set->dlen); + err =nft_parse_register_store (ctx, tb[NFTA_LOOKUP_DREG ], + &priv->dreg,NULL , set->dtype, + set->dlen);if (err <0 )return err; }else if (set->flags &NFT_SET_MAP )
net/netfilter/nft_meta.c +2 -3
@@ -380,9 +380,8 @@ int nft_meta_get_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_META_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_META_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); }EXPORT_SYMBOL_GPL (nft_meta_get_init);
net/netfilter/nft_numgen.c +6 -9
@@ -16,7 +16,7 @@ static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);struct nft_ng_inc { -enum nft_registers dreg:8 ; +u8 dreg;u32 modulus;atomic_t counter;u32 offset;
@@ -66,11 +66,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,if (priv->offset + priv->modulus -1 < priv->offset)return -EOVERFLOW ; - priv->dreg =nft_parse_register (tb[NFTA_NG_DREG ]);atomic_set (&priv->counter, priv->modulus -1 ); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_NG_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE ,sizeof (u32)); } static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
@@ -100,7 +99,7 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr) }struct nft_ng_random { -enum nft_registers dreg:8 ; +u8 dreg;u32 modulus;u32 offset; };
@@ -140,10 +139,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,prandom_init_once (&nft_numgen_prandom_state); - priv->dreg =nft_parse_register (tb[NFTA_NG_DREG ]); - -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_NG_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE ,sizeof (u32)); }static int nft_ng_random_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_osf.c +4 -4
@@ -6,7 +6,7 @@#include <linux/netfilter/nfnetlink_osf.h> struct nft_osf { -enum nft_registers dreg:8 ; +u8 dreg;u8 ttl;u32 flags; };
@@ -83,9 +83,9 @@ static int nft_osf_init(const struct nft_ctx *ctx, priv->flags = flags; } - priv->dreg =nft_parse_register (tb[NFTA_OSF_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,NFT_OSF_MAXGENRELEN ); + err =nft_parse_register_store (ctx, tb[NFTA_OSF_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , +NFT_OSF_MAXGENRELEN );if (err <0 )return err;
net/netfilter/nft_payload.c +3 -3
@@ -135,10 +135,10 @@ static int nft_payload_init(const struct nft_ctx *ctx, priv->base =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_BASE ])); priv->offset =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_OFFSET ])); priv->len =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_LEN ])); - priv->dreg =nft_parse_register (tb[NFTA_PAYLOAD_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); +return nft_parse_register_store (ctx, tb[NFTA_PAYLOAD_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len); }static int nft_payload_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_rt.c +3 -4
@@ -15,7 +15,7 @@struct nft_rt {enum nft_rt_keys key:8 ; -enum nft_registers dreg:8 ; +u8 dreg; };static u16 get_tcpmss (const struct nft_pktinfo *pkt,const struct dst_entry *skbdst)
@@ -141,9 +141,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_RT_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_RT_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_rt_get_dump(struct sk_buff *skb,
net/netfilter/nft_socket.c +3 -4
@@ -10,7 +10,7 @@struct nft_socket {enum nft_socket_keys key:8 ;union { -enum nft_registers dreg:8 ; +u8 dreg; }; };
@@ -119,9 +119,8 @@ static int nft_socket_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_SOCKET_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_SOCKET_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_socket_dump(struct sk_buff *skb,
net/netfilter/nft_tunnel.c +3 -5
@@ -14,7 +14,7 @@struct nft_tunnel {enum nft_tunnel_keys key:8 ; -enum nft_registers dreg:8 ; +u8 dreg;enum nft_tunnel_mode mode:8 ; };
@@ -92,8 +92,6 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_TUNNEL_DREG ]); -if (tb[NFTA_TUNNEL_MODE ]) { priv->mode =ntohl (nla_get_be32 (tb[NFTA_TUNNEL_MODE ]));if (priv->mode >NFT_TUNNEL_MODE_MAX )
@@ -102,8 +100,8 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx, priv->mode =NFT_TUNNEL_MODE_NONE ; } -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_TUNNEL_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_tunnel_get_dump(struct sk_buff *skb,
net/netfilter/nft_xfrm.c +3 -4
@@ -24,7 +24,7 @@ static const struct nla_policy nft_xfrm_policy[NFTA_XFRM_MAX + 1] = {struct nft_xfrm {enum nft_xfrm_keys key:8 ; -enum nft_registers dreg:8 ; +u8 dreg;u8 dir;u8 spnum; };
@@ -86,9 +86,8 @@ static int nft_xfrm_get_init(const struct nft_ctx *ctx, priv->spnum = spnum; - priv->dreg =nft_parse_register (tb[NFTA_XFRM_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_XFRM_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); }/* Return true if key asks for daddr/saddr and current
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 106/161 netfilter: nftables: statify nft_parse_register()
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 08a01c11a5bb3de9b0a9c9b2685867e50eda9910 ]
This function is not used anymore by any extension, statify it.
--- include/net/netfilter/nf_tables.h | 1 - net/netfilter/nf_tables_api.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-)
include/net/netfilter/nf_tables.h +0 -1
@@ -205,7 +205,6 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) }int nft_parse_u32_check (const struct nlattr *attr,int max,u32 *dest); -unsigned int nft_parse_register (const struct nlattr *attr);int nft_dump_register (struct sk_buff *skb,unsigned int attr,unsigned int reg);int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len);
net/netfilter/nf_tables_api.c +1 -2
@@ -7393,7 +7393,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check);* Registers used to be 128 bit wide, these register numbers will be * mapped to the corresponding 32 bit register numbers. */ -unsigned int nft_parse_register (const struct nlattr *attr) +static unsigned int nft_parse_register (const struct nlattr *attr) {unsigned int reg;
@@ -7405,7 +7405,6 @@ unsigned int nft_parse_register(const struct nlattr *attr)return reg +NFT_REG_SIZE /NFT_REG32_SIZE -NFT_REG32_00 ; } } -EXPORT_SYMBOL_GPL (nft_parse_register);/** * nft_dump_register - dump a register value to a netlink attribute
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 107/161 netfilter: nf_tables: validate registers coming from userspace.
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 6e1acfa387b9ff82cfc7db8cc3b6959221a95851 ]
Bail out in case userspace uses unsupported registers.
--- net/netfilter/nf_tables_api.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
net/netfilter/nf_tables_api.c +17 -14
@@ -7384,26 +7384,23 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) }EXPORT_SYMBOL_GPL (nft_parse_u32_check); -/** -* nft_parse_register - parse a register value from a netlink attribute -* -* @attr: netlink attribute -* -* Parse and translate a register value from a netlink attribute. -* Registers used to be 128 bit wide, these register numbers will be -* mapped to the corresponding 32 bit register numbers. -*/ -static unsigned int nft_parse_register (const struct nlattr *attr) +static int nft_parse_register (const struct nlattr *attr,u32 *preg) {unsigned int reg; reg =ntohl (nla_get_be32 (attr));switch (reg) { case NFT_REG_VERDICT...NFT_REG_4: -return reg *NFT_REG_SIZE /NFT_REG32_SIZE ; + *preg = reg *NFT_REG_SIZE /NFT_REG32_SIZE ; +break ; + case NFT_REG32_00...NFT_REG32_15: + *preg = reg +NFT_REG_SIZE /NFT_REG32_SIZE -NFT_REG32_00 ; +break ;default : -return reg +NFT_REG_SIZE /NFT_REG32_SIZE -NFT_REG32_00 ; +return -ERANGE ; } + +return 0 ; }/**
@@ -7454,7 +7451,10 @@ int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)u32 reg;int err; - reg =nft_parse_register (attr); + err =nft_parse_register (attr, ®); +if (err <0 ) +return err; + err =nft_validate_register_load (reg, len);if (err <0 )return err;
@@ -7523,7 +7523,10 @@ int nft_parse_register_store(const struct nft_ctx *ctx,int err;u32 reg; - reg =nft_parse_register (attr); + err =nft_parse_register (attr, ®); +if (err <0 ) +return err; + err =nft_validate_register_store (ctx, reg, data, type, len);if (err <0 )return err;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 108/161 netfilter: nf_tables: add nft_setelem_parse_key()
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 20a1452c35425b2cef76f21f8395ef069dfddfa9 ]
Add helper function to parse the set element key netlink attribute.
v4: No changes
v3: New patch
[sbrivio: refactor error paths and labels; use NFT_DATA_VALUE_MAXLEN
instead of sizeof(*key) in helper, value can be longer than that; rebase]
--- net/netfilter/nf_tables_api.c | 91 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 46 deletions(-)
net/netfilter/nf_tables_api.c +45 -46
@@ -4292,11 +4292,28 @@ static int nft_setelem_parse_flags(const struct nft_set *set,return 0 ; } +static int nft_setelem_parse_key (struct nft_ctx *ctx,struct nft_set *set, +struct nft_data *key,struct nlattr *attr) +{ +struct nft_data_desc desc; +int err; + + err =nft_data_init (ctx, key,NFT_DATA_VALUE_MAXLEN , &desc, attr); +if (err <0 ) +return err; + +if (desc.type !=NFT_DATA_VALUE || desc.len != set->klen) { +nft_data_release (key, desc.type); +return -EINVAL ; + } + +return 0 ; +} +static int nft_get_set_elem (struct nft_ctx *ctx,struct nft_set *set,const struct nlattr *attr) {struct nlattr *nla[NFTA_SET_ELEM_MAX +1 ]; -struct nft_data_desc desc;struct nft_set_elem elem;struct sk_buff *skb;uint32_t flags =0 ;
@@ -4315,17 +4332,11 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,if (err <0 )return err; - err =nft_data_init (ctx, &elem.key.val,sizeof (elem.key), &desc, - nla[NFTA_SET_ELEM_KEY ]); + err =nft_setelem_parse_key (ctx, set, &elem.key.val, + nla[NFTA_SET_ELEM_KEY ]);if (err <0 )return err; - err = -EINVAL ; -if (desc.type !=NFT_DATA_VALUE || desc.len != set->klen) { -nft_data_release (&elem.key.val, desc.type); -return err; - } - priv = set->ops->get (ctx->net, set, &elem, flags);if (IS_ERR (priv))return PTR_ERR (priv);
@@ -4518,13 +4529,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, {struct nlattr *nla[NFTA_SET_ELEM_MAX +1 ];u8 genmask =nft_genmask_next (ctx->net); -struct nft_data_desc d1, d2;struct nft_set_ext_tmpl tmpl;struct nft_set_ext *ext, *ext2;struct nft_set_elem elem;struct nft_set_binding *binding;struct nft_object *obj =NULL ;struct nft_userdata *udata; +struct nft_data_desc desc;struct nft_data data;enum nft_registers dreg;struct nft_trans *trans;
@@ -4590,15 +4601,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,return err; } - err =nft_data_init (ctx, &elem.key.val,sizeof (elem.key), &d1, - nla[NFTA_SET_ELEM_KEY ]); + err =nft_setelem_parse_key (ctx, set, &elem.key.val, + nla[NFTA_SET_ELEM_KEY ]);if (err <0 ) goto err1; - err = -EINVAL ; -if (d1.type !=NFT_DATA_VALUE || d1.len != set->klen) - goto err2; -nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , d1.len); +nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , set->klen);if (timeout >0 ) {nft_set_ext_add (&tmpl,NFT_SET_EXT_EXPIRATION );if (timeout != set->timeout)
@@ -4621,13 +4629,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, }if (nla[NFTA_SET_ELEM_DATA ] !=NULL ) { - err =nft_data_init (ctx, &data,sizeof (data), &d2, + err =nft_data_init (ctx, &data,sizeof (data), &desc, nla[NFTA_SET_ELEM_DATA ]);if (err <0 ) goto err2; err = -EINVAL ; -if (set->dtype !=NFT_DATA_VERDICT && d2.len != set->dlen) +if (set->dtype !=NFT_DATA_VERDICT && desc.len != set->dlen) goto err3; dreg =nft_type_to_reg (set->dtype);
@@ -4644,18 +4652,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, err =nft_validate_register_store (&bind_ctx, dreg, &data, - d2.type, d2.len); + desc.type, desc.len);if (err <0 ) goto err3; -if (d2.type ==NFT_DATA_VERDICT && +if (desc.type ==NFT_DATA_VERDICT && (data.verdict.code ==NFT_GOTO || data.verdict.code ==NFT_JUMP ))nft_validate_state_update (ctx->net,NFT_VALIDATE_NEED ); } -nft_set_ext_add_length (&tmpl,NFT_SET_EXT_DATA , d2.len); +nft_set_ext_add_length (&tmpl,NFT_SET_EXT_DATA , desc.len); }/* The full maximum length of userdata can exceed the maximum
@@ -4738,9 +4746,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,kfree (elem.priv); err3:if (nla[NFTA_SET_ELEM_DATA ] !=NULL ) -nft_data_release (&data, d2.type); +nft_data_release (&data, desc.type); err2: -nft_data_release (&elem.key.val, d1.type); +nft_data_release (&elem.key.val,NFT_DATA_VALUE ); err1:return err; }
@@ -4836,7 +4844,6 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, {struct nlattr *nla[NFTA_SET_ELEM_MAX +1 ];struct nft_set_ext_tmpl tmpl; -struct nft_data_desc desc;struct nft_set_elem elem;struct nft_set_ext *ext;struct nft_trans *trans;
@@ -4847,11 +4854,10 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, err =nla_parse_nested_deprecated (nla,NFTA_SET_ELEM_MAX , attr, nft_set_elem_policy,NULL );if (err <0 ) - goto err1; +return err; - err = -EINVAL ;if (nla[NFTA_SET_ELEM_KEY ] ==NULL ) - goto err1; +return -EINVAL ;nft_set_ext_prepare (&tmpl);
@@ -4861,37 +4867,31 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,if (flags !=0 )nft_set_ext_add (&tmpl,NFT_SET_EXT_FLAGS ); - err =nft_data_init (ctx, &elem.key.val,sizeof (elem.key), &desc, - nla[NFTA_SET_ELEM_KEY ]); + err =nft_setelem_parse_key (ctx, set, &elem.key.val, + nla[NFTA_SET_ELEM_KEY ]);if (err <0 ) - goto err1; - - err = -EINVAL ; -if (desc.type !=NFT_DATA_VALUE || desc.len != set->klen) - goto err2; +return err; -nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , desc.len); +nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , set->klen); err = -ENOMEM ; elem.priv =nft_set_elem_init (set, &tmpl, elem.key.val.data,NULL ,0 ,0 ,GFP_KERNEL );if (elem.priv ==NULL ) - goto err2; + goto fail_elem; ext =nft_set_elem_ext (set, elem.priv);if (flags) *nft_set_ext_flags (ext) = flags; trans =nft_trans_elem_alloc (ctx,NFT_MSG_DELSETELEM , set); -if (trans ==NULL ) { - err = -ENOMEM ; - goto err3; - } +if (trans ==NULL ) + goto fail_trans; priv = set->ops->deactivate (ctx->net, set, &elem);if (priv ==NULL ) { err = -ENOENT ; - goto err4; + goto fail_ops; }kfree (elem.priv); elem.priv = priv;
@@ -4902,13 +4902,12 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,list_add_tail (&trans->list, &ctx->net->nft.commit_list);return 0 ; -err4: +fail_ops:kfree (trans); -err3: +fail_trans:kfree (elem.priv); -err2: -nft_data_release (&elem.key.val, desc.type); -err1: +fail_elem: +nft_data_release (&elem.key.val,NFT_DATA_VALUE );return err; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 109/161 netfilter: nf_tables: allow up to 64 bytes in the set element data area
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 ]
So far, the set elements could store up to 128-bits in the data area.
--- include/net/netfilter/nf_tables.h | 4 +++ net/netfilter/nf_tables_api.c | 41 +++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 13 deletions(-)
include/net/netfilter/nf_tables.h +4 -0
@@ -239,6 +239,10 @@ struct nft_set_elem {u32 buf[NFT_DATA_VALUE_MAXLEN /sizeof (u32)];struct nft_data val; } key; +union { +u32 buf[NFT_DATA_VALUE_MAXLEN /sizeof (u32)]; +struct nft_data val; + } data;void *priv; };
net/netfilter/nf_tables_api.c +28 -13
85 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 110/161 netfilter: nf_tables: stricter validation of element data
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 7e6bc1f6cabcd30aba0b11219d8e01b952eacbb6 ]
Make sure element data type and length do not mismatch the one specified by the set declaration.
--- net/netfilter/nf_tables_api.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +8 -1
@@ -4315,13 +4315,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,struct nft_data *data, struct nlattr *attr) { + u32 dtype;int err; err =nft_data_init (ctx, data,NFT_DATA_VALUE_MAXLEN , desc, attr);if (err <0 )return err; -if (desc->type !=NFT_DATA_VERDICT && desc->len != set->dlen) { +if (set->dtype ==NFT_DATA_VERDICT ) + dtype =NFT_DATA_VERDICT ; +else + dtype =NFT_DATA_VALUE ; + +if (dtype != desc->type || + set->dlen != desc->len) {nft_data_release (data, desc->type);return -EINVAL ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 111/161 netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT flag
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 5a2f3dc31811e93be15522d9eb13ed61460b76c8 ]
If the NFTA_SET_ELEM_OBJREF netlink attribute is present and NFT_SET_OBJECT flag is set on, report EINVAL.
Move existing sanity check earlier to validate that NFT_SET_OBJECT requires NFTA_SET_ELEM_OBJREF.
--- net/netfilter/nf_tables_api.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +9 -4
@@ -4595,6 +4595,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,return -EINVAL ; } +if (set->flags &NFT_SET_OBJECT ) { +if (!nla[NFTA_SET_ELEM_OBJREF ] && + !(flags &NFT_SET_ELEM_INTERVAL_END )) +return -EINVAL ; + }else { +if (nla[NFTA_SET_ELEM_OBJREF ]) +return -EINVAL ; + } + if ((flags & NFT_SET_ELEM_INTERVAL_END) && (nla[NFTA_SET_ELEM_DATA] || nla[NFTA_SET_ELEM_OBJREF] ||
@@ -4639,10 +4648,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, }if (nla[NFTA_SET_ELEM_OBJREF ] !=NULL ) { -if (!(set->flags &NFT_SET_OBJECT )) { - err = -EINVAL ; - goto err2; - } obj =nft_obj_lookup (ctx->net, ctx->table, nla[NFTA_SET_ELEM_OBJREF ], set->objtype, genmask);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 112/161 netfilter: nf_tables: hold mutex on netns pre_exit path
In reply to Greg Kroah-HartmanFrom: Pablo Neira Ayuso <[email protected]>
[ 3923b1e4406680d57da7e873da77b1683035d83f ]
clean_net() runs in workqueue while walking over the lists, grab mutex.
--- net/netfilter/nf_tables_api.c | 2 ++ 1 file changed, 2 insertions(+)
net/netfilter/nf_tables_api.c +2 -0
@@ -7866,7 +7866,9 @@ static int __net_init nf_tables_init_net(struct net *net) static void __net_exit nf_tables_pre_exit_net(struct net *net) { +mutex_lock (&net->nft.commit_mutex);__nft_release_hooks (net); +mutex_unlock (&net->nft.commit_mutex); } static void __net_exit nf_tables_exit_net(struct net *net)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 113/161 HID: wacom: Force pen out of prox if no events have been received in a while
In reply to Greg Kroah-HartmanFrom: Jason Gerecke <[email protected]>
commit 94b179052f95c294d83e9c9c34f7833cf3cd4305 upstream.
Prox-out events may not be reliably sent by some AES firmware. This can cause problems for users, particularly due to arbitration logic disabling touch input while the pen is in prox.
This commit adds a timer which is reset every time a new prox event is received. When the timer expires we check to see if the pen is still in prox and force it out if necessary. This is patterend off of the same solution used by 'hid-letsketch' driver which has a similar problem.
--- drivers/hid/wacom.h | 3 +++ drivers/hid/wacom_sys.c | 2 ++ drivers/hid/wacom_wac.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+)
drivers/hid/wacom.h +3 -0
@@ -91,6 +91,7 @@#include <linux/leds.h> #include <linux/usb/input.h> #include <linux/power_supply.h> +#include <linux/timer.h> #include <asm/unaligned.h> /*
@@ -167,6 +168,7 @@ struct wacom {struct delayed_work init_work;struct wacom_remote *remote;struct work_struct mode_change_work; +struct timer_list idleprox_timer;bool generic_has_leds;struct wacom_leds {struct wacom_group_leds *groups;
@@ -239,4 +241,5 @@ struct wacom_led *wacom_led_find(structstruct wacom_led *wacom_led_next (struct wacom *wacom,struct wacom_led *cur);int wacom_equivalent_usage (int usage);int wacom_initialize_leds (struct wacom *wacom); +void wacom_idleprox_timeout (struct timer_list *list);#endif
drivers/hid/wacom_sys.c +2 -0
@@ -2781,6 +2781,7 @@ static int wacom_probe(struct hid_deviceINIT_WORK (&wacom->battery_work, wacom_battery_work);INIT_WORK (&wacom->remote_work, wacom_remote_work);INIT_WORK (&wacom->mode_change_work, wacom_mode_change_work); +timer_setup (&wacom->idleprox_timer, &wacom_idleprox_timeout,TIMER_DEFERRABLE );/* ask for the report descriptor to be loaded by HID */ error =hid_parse (hdev);
@@ -2825,6 +2826,7 @@ static void wacom_remove(struct hid_devicancel_work_sync (&wacom->battery_work);cancel_work_sync (&wacom->remote_work);cancel_work_sync (&wacom->mode_change_work); +del_timer_sync (&wacom->idleprox_timer);if (hdev->bus ==BUS_BLUETOOTH )device_remove_file (&hdev->dev, &dev_attr_speed);
drivers/hid/wacom_wac.c +39 -0
@@ -11,6 +11,7 @@#include "wacom_wac.h" #include "wacom.h" #include <linux/input/mt.h> +#include <linux/jiffies.h> /* resolution for penabled devices */ #define WACOM_PL_RES 20
@@ -41,6 +42,43 @@ static int wacom_numbered_button_to_key(static void wacom_update_led (struct wacom *wacom,int button_count,int mask,int group); + +static void wacom_force_proxout (struct wacom_wac *wacom_wac) +{ +struct input_dev *input = wacom_wac->pen_input; + + wacom_wac->shared->stylus_in_proximity =0 ; + +input_report_key (input,BTN_TOUCH ,0 ); +input_report_key (input,BTN_STYLUS ,0 ); +input_report_key (input,BTN_STYLUS2 ,0 ); +input_report_key (input,BTN_STYLUS3 ,0 ); +input_report_key (input, wacom_wac->tool[0 ],0 ); +if (wacom_wac->serial[0 ]) { +input_report_abs (input,ABS_MISC ,0 ); + } +input_report_abs (input,ABS_PRESSURE ,0 ); + + wacom_wac->tool[0 ] =0 ; + wacom_wac->id[0 ] =0 ; + wacom_wac->serial[0 ] =0 ; + +input_sync (input); +} + +void wacom_idleprox_timeout (struct timer_list *list) +{ +struct wacom *wacom =from_timer (wacom, list, idleprox_timer); +struct wacom_wac *wacom_wac = &wacom->wacom_wac; + +if (!wacom_wac->hid_data.sense_state) { +return ; + } + +hid_warn (wacom->hdev,"%s: tool appears to be hung in-prox. forcing it out.\n" , __func__); +wacom_force_proxout (wacom_wac); +} +/* * Percent of battery capacity for Graphire. * 8th value means AC online and show 100% capacity.
@@ -2328,6 +2366,7 @@ static void wacom_wac_pen_event(struct h value = field->logical_maximum - value;break ;case HID_DG_INRANGE : +mod_timer (&wacom->idleprox_timer, jiffies +msecs_to_jiffies (100 )); wacom_wac->hid_data.inrange_state = value;if (!(features->quirks &WACOM_QUIRK_SENSE )) wacom_wac->hid_data.sense_state = value;
Greg Kroah-Hartman
maintainerPATCH 114/161 HID: wacom: Add new Intuos Pro Small (PTH-460) device IDs
In reply to Greg Kroah-HartmanFrom: Ping Cheng <[email protected]>
commit 0627f3df95e1609693f89e7ceb4156ac5db6e358 upstream.
Add the new PIDs to wacom_wac.c to support the new model in the Intuos Pro series.
--- drivers/hid/wacom_wac.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/hid/wacom_wac.c +5 -0
@@ -4840,6 +4840,10 @@ static const struct wacom_features wacomstatic const struct wacom_features wacom_features_0x3c8 = {"Wacom Intuos BT M" ,21600 ,13500 ,4095 ,63 ,INTUOSHT3_BT ,WACOM_INTUOS_RES ,WACOM_INTUOS_RES ,4 }; +static const struct wacom_features wacom_features_0x3dd = + {"Wacom Intuos Pro S" ,31920 ,19950 ,8191 ,63 , +INTUOSP2S_BT ,WACOM_INTUOS3_RES ,WACOM_INTUOS3_RES ,7 , + .touch_max =10 };static const struct wacom_features wacom_features_HID_ANY_ID = {"Wacom HID" , .type =HID_GENERIC , .oVid =HID_ANY_ID , .oPid =HID_ANY_ID };
@@ -5019,6 +5023,7 @@ const struct hid_device_id wacom_ids[] = { BT_DEVICE_WACOM(0x393) }, { BT_DEVICE_WACOM(0x3c6) }, { BT_DEVICE_WACOM(0x3c8) }, + { BT_DEVICE_WACOM(0x3dd) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) },
Greg Kroah-Hartman
maintainerPATCH 115/161 HID: wacom: add three styli to wacom_intuos_get_tool_type
In reply to Greg Kroah-HartmanFrom: Ping Cheng <[email protected]>
commit bfdc750c4cb2f3461b9b00a2755e2145ac195c9a upstream.
We forgot to add the 3D pen ID a year ago. There are two new pro pen IDs to be added.
--- drivers/hid/wacom_wac.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/hid/wacom_wac.c +3 -0
@@ -713,11 +713,14 @@ static int wacom_intuos_get_tool_type(incase 0x802 :/* Intuos4/5 13HD/24HD General Pen */ case 0x8e2 :/* IntuosHT2 pen */ case 0x022 : +case 0x200 :/* Pro Pen 3 */ +case 0x04200 :/* Pro Pen 3 */ case 0x10842 :/* MobileStudio Pro Pro Pen slim */ case 0x14802 :/* Intuos4/5 13HD/24HD Classic Pen */ case 0x16802 :/* Cintiq 13HD Pro Pen */ case 0x18802 :/* DTH2242 Pen */ case 0x10802 :/* Intuos4/5 13HD/24HD General Pen */ +case 0x80842 :/* Intuos Pro and Cintiq Pro 3D Pen */ tool_type =BTN_TOOL_PEN ;break ;
Greg Kroah-Hartman
maintainerPATCH 116/161 lib/string_helpers: Introduce string_upper() and string_lower() helpers
In reply to Greg Kroah-HartmanFrom: Vadim Pasternak <[email protected]>
[ Upstream commit 58eeba0bdb52afe5c18ce2a760ca9fe2901943e9 ]
Provide the helpers for string conversions to upper and lower cases.
Stable-dep-of: 3c0f4f09c063 ("usb: gadget: u_ether: Fix host MAC address case")
--- include/linux/string_helpers.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
include/linux/string_helpers.h +15 -0
@@ -2,6 +2,7 @@#ifndef _LINUX_STRING_HELPERS_H_#define _LINUX_STRING_HELPERS_H_ +#include <linux/ctype.h> #include <linux/types.h> struct file ;
@@ -75,6 +76,20 @@ static inline int string_escape_str_any_np(const char *src, char *dst,return string_escape_str (src, dst, sz,ESCAPE_ANY_NP , only); } +static inline void string_upper (char *dst,const char *src) +{ +do { + *dst++ =toupper (*src); + }while (*src++); +} + +static inline void string_lower (char *dst,const char *src) +{ +do { + *dst++ =tolower (*src); + }while (*src++); +} +char *kstrdup_quotable (const char *src,gfp_t gfp);char *kstrdup_quotable_cmdline (struct task_struct *task,gfp_t gfp);char *kstrdup_quotable_file (struct file *file,gfp_t gfp);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 117/161 usb: gadget: u_ether: Convert prints to device prints
In reply to Greg Kroah-HartmanFrom: Jon Hunter <[email protected]>
[ Upstream commit 938fc645317632d79c048608689683b5437496ea ]
The USB ethernet gadget driver implements its own print macros which call printk. Device drivers should use the device prints that print the device name. Fortunately, the same macro names are defined in the header file 'linux/usb/composite.h' and these use the device prints. Therefore, remove the local definitions in the USB ethernet gadget driver and use those in 'linux/usb/composite.h'. The only difference is that now the device name is printed instead of the ethernet interface name.
Tested using ethernet gadget on Jetson AGX Orin.
Stable-dep-of: 3c0f4f09c063 ("usb: gadget: u_ether: Fix host MAC address case")
--- drivers/usb/gadget/function/u_ether.c | 36 +-------------------------- 1 file changed, 1 insertion(+), 35 deletions(-)
drivers/usb/gadget/function/u_ether.c +1 -35
@@ -17,6 +17,7 @@#include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/if_vlan.h> +#include <linux/usb/composite.h> #include "u_ether.h"
@@ -102,41 +103,6 @@ static inline int qlen(struct usb_gadget *gadget, unsigned qmult)/*-------------------------------------------------------------------------*/ -/* REVISIT there must be a better way than having two sets -* of debug calls ... -*/ - -#undef DBG -#undef VDBG -#undef ERROR -#undef INFO - -#define xprintk(d, level, fmt, args...) \ - printk(level "%s: " fmt , (d)->net->name , ## args) - -#ifdef DEBUG -#undef DEBUG -#define DBG(dev, fmt, args...) \ - xprintk(dev , KERN_DEBUG , fmt , ## args) -#else -#define DBG(dev, fmt, args...) \ - do { } while (0) -#endif /* DEBUG */ - -#ifdef VERBOSE_DEBUG -#define VDBG DBG -#else -#define VDBG(dev, fmt, args...) \ - do { } while (0) -#endif /* DEBUG */ - -#define ERROR(dev, fmt, args...) \ - xprintk(dev , KERN_ERR , fmt , ## args) -#define INFO(dev, fmt, args...) \ - xprintk(dev , KERN_INFO , fmt , ## args) - -/*-------------------------------------------------------------------------*/ -/* NETWORK DRIVER HOOKUP (to the layer above this driver) */ static void eth_get_drvinfo (struct net_device *net,struct ethtool_drvinfo *p)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 118/161 usb: gadget: u_ether: Fix host MAC address case
In reply to Greg Kroah-HartmanFrom: Konrad Gräfe <[email protected]>
[ Upstream commit 3c0f4f09c063e143822393d99cb2b19a85451c07 ]
The CDC-ECM specification [1] requires to send the host MAC address as an uppercase hexadecimal string in chapter "5.4 Ethernet Networking Functional Descriptor":
The Unicode character is chosen from the set of values 30h through 39h and 41h through 46h (0-9 and A-F).
However, snprintf(.., "%pm", ..) generates a lowercase MAC address string. While most host drivers are tolerant to this, UsbNcm.sys on Windows 10 is not. Instead it uses a different MAC address with all bytes set to zero including and after the first byte containing a lowercase letter. On Windows 11 Microsoft fixed it, but apparently they did not backport the fix.
This change fixes the issue by upper-casing the MAC to comply with the specification.
[1]: https://www.usb.org/document-library/class-definitions-communication-devices-12, file ECM120.pdf
--- drivers/usb/gadget/function/u_ether.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/gadget/function/u_ether.c +3 -0
@@ -17,6 +17,7 @@#include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/if_vlan.h> +#include <linux/string_helpers.h> #include <linux/usb/composite.h> #include "u_ether.h"
@@ -940,6 +941,8 @@ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len) dev =netdev_priv (net);snprintf (host_addr, len,"%pm" , dev->host_mac); +string_upper (host_addr, host_addr); +return strlen (host_addr); }EXPORT_SYMBOL_GPL (gether_get_host_addr_cdc);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 119/161 vc_screen: rewrite vcs_size to accept vc, not inode
In reply to Greg Kroah-HartmanFrom: Jiri Slaby <[email protected]>
[ Upstream commit 71d4abfab322e827a75304431fe0fad3c805cb80 ]
It is weird to fetch the information from the inode over and over. Read and write already have the needed information, so rewrite vcs_size to accept a vc, attr and unicode and adapt vcs_lseek to that.
Also make sure all sites check the return value of vcs_size for errors.
And document it using kernel-doc.
Stable-dep-of: 8fb9ea65c9d1 ("vc_screen: reload load of struct vc_data pointer in vcs_write() to avoid UAF")
--- drivers/tty/vt/vc_screen.c | 46 ++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 17 deletions(-)
drivers/tty/vt/vc_screen.c +29 -17
@@ -200,39 +200,47 @@ vcs_vc(struct inode *inode, int *viewed)return vc_cons[currcons].d; } -/* -* Returns size for VC carried by inode. +/** +* vcs_size -- return size for a VC in @vc +* @vc: which VC +* @attr: does it use attributes? +* @unicode: is it unicode? +* * Must be called with console_lock. */ -static int -vcs_size (struct inode *inode) +static int vcs_size (const struct vc_data *vc,bool attr,bool unicode) {int size; -struct vc_data *vc;WARN_CONSOLE_UNLOCKED (); - vc =vcs_vc (inode,NULL ); -if (!vc) -return -ENXIO ; - size = vc->vc_rows * vc->vc_cols; -if (use_attributes (inode)) { -if (use_unicode (inode)) +if (attr) { +if (unicode)return -EOPNOTSUPP ; - size =2 *size +HEADER_SIZE ; - }else if (use_unicode (inode)) + + size =2 * size +HEADER_SIZE ; + }else if (unicode) size *=4 ; +return size; }static loff_t vcs_lseek (struct file *file,loff_t offset,int orig) { +struct inode *inode =file_inode (file); +struct vc_data *vc;int size;console_lock (); - size =vcs_size (file_inode (file)); + vc =vcs_vc (inode,NULL ); +if (!vc) { +console_unlock (); +return -ENXIO ; + } + + size =vcs_size (vc,use_attributes (inode),use_unicode (inode));console_unlock ();if (size <0 )return size;
@@ -294,7 +302,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)* as copy_to_user at the end of this loop * could sleep. */ - size =vcs_size (inode); + size =vcs_size (vc, attr, uni_mode);if (size <0 ) { ret = size;break ;
@@ -476,7 +484,11 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)if (!vc) goto unlock_out; - size =vcs_size (inode); + size =vcs_size (vc, attr, false); +if (size <0 ) { + ret = size; + goto unlock_out; + } ret = -EINVAL ;if (pos <0 || pos > size) goto unlock_out;
@@ -515,7 +527,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)* the user buffer, so recheck. * Return data written up to now on failure. */ - size =vcs_size (inode); + size =vcs_size (vc, attr, false);if (size <0 ) {if (written)break ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 120/161 vc_screen: reload load of struct vc_data pointer in vcs_write() to avoid UAF
In reply to Greg Kroah-HartmanFrom: George Kennedy <[email protected]>
[ Upstream commit 8fb9ea65c9d1338b0d2bb0a9122dc942cdd32357 ]
After a call to console_unlock() in vcs_write() the vc_data struct can be freed by vc_port_destruct(). Because of that, the struct vc_data pointer must be reloaded in the while loop in vcs_write() after console_lock() to avoid a UAF when vcs_size() is called.
Syzkaller reported a UAF in vcs_size().
BUG: KASAN: slab-use-after-free in vcs_size (drivers/tty/vt/vc_screen.c:215) Read of size 4 at addr ffff8880beab89a8 by task repro_vcs_size/4119 Call Trace: <TASK>
__asan_report_load4_noabort (mm/kasan/report_generic.c:380) vcs_size (drivers/tty/vt/vc_screen.c:215) vcs_write (drivers/tty/vt/vc_screen.c:664) vfs_write (fs/read_write.c:582 fs/read_write.c:564)
...
<TASK>
Allocated by task 1213:
kmalloc_trace (mm/slab_common.c:1064)
vc_allocate (./include/linux/slab.h:559 ./include/linux/slab.h:680
drivers/tty/vt/vt.c:1078 drivers/tty/vt/vt.c:1058)
con_install (drivers/tty/vt/vt.c:3334)
tty_init_dev (drivers/tty/tty_io.c:1303 drivers/tty/tty_io.c:1415
drivers/tty/tty_io.c:1392)
tty_open (drivers/tty/tty_io.c:2082 drivers/tty/tty_io.c:2128)chrdev_open (fs/char_dev.c:415)do_dentry_open (fs/open.c:921)vfs_open (fs/open.c:1052)
...
Freed by task 4116:
kfree (mm/slab_common.c:1016)vc_port_destruct (drivers/tty/vt/vt.c:1044) tty_port_destructor (drivers/tty/tty_port.c:296) tty_port_put (drivers/tty/tty_port.c:312) vt_disallocate_all (drivers/tty/vt/vt_ioctl.c:662 (discriminator 2)) vt_ioctl (drivers/tty/vt/vt_ioctl.c:903)tty_ioctl (drivers/tty/tty_io.c:2778)
...
The buggy address belongs to the object at ffff8880beab8800 which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 424 bytes inside of
freed 1024-byte region [ffff8880beab8800, ffff8880beab8c00)
The buggy address belongs to the physical page:
page:00000000afc77580 refcount:1 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0xbeab8head:00000000afc77580 order:3 entire_mapcount:0 nr_pages_mapped:0
pincount:0
flags: 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)page_type: 0xffffffff()
raw: 000fffffc0010200 ffff888100042dc0 ffffea000426de00 dead000000000002
raw: 0000000000000000 0000000000100010 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8880beab8880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880beab8900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8880beab8980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880beab8a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880beab8a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================Disabling lock debugging due to kernel taint
--- drivers/tty/vt/vc_screen.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/tty/vt/vc_screen.c +9 -2
@@ -523,10 +523,17 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) } } -/* The vcs_size might have changed while we slept to grab -* the user buffer, so recheck. +/* The vc might have been freed or vcs_size might have changed +* while we slept to grab the user buffer, so recheck. * Return data written up to now on failure. */ + vc =vcs_vc (inode, &viewed); +if (!vc) { +if (written) +break ; + ret = -ENXIO ; + goto unlock_out; + } size =vcs_size (vc, attr, false);if (size <0 ) {if (written)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 121/161 s390/qdio: get rid of register asm
In reply to Greg Kroah-HartmanFrom: Heiko Carstens <[email protected]>
[ Upstream commit d3e2ff5436d6ee38b572ba5c01dc7994769bec54 ]
Stable-dep-of: 2862a2fdfae8 ("s390/qdio: fix do_sqbs() inline assembly constraint")
--- drivers/s390/cio/qdio.h | 25 ++++++++------- drivers/s390/cio/qdio_main.c | 62 +++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 41 deletions(-)
drivers/s390/cio/qdio.h +13 -12
@@ -88,15 +88,15 @@ enum qdio_irq_states {static inline int do_sqbs (u64 token,unsigned char state,int queue,int *start,int *count) { - register unsigned long _ccq asm ("0") = *count; - register unsigned long _token asm ("1") = token;unsigned long _queuestart = ((unsigned long )queue <<32 ) | *start; +unsigned long _ccq = *count; asmvolatile ( -" .insn rsy,0xeb000000008A,%1,0,0(%2)" - :"+d" (_ccq),"+d" (_queuestart) - :"d" ((unsigned long )state),"d" (_token) - :"memory" ,"cc" ); +" lgr 1,%[token]\n" +" .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])" + : [ccq]"+&d" (_ccq), [qs]"+&d" (_queuestart) + : [state]"d" ((unsigned long )state), [token]"d" (token) + :"memory" ,"cc" ,"1" ); *count = _ccq &0xff ; *start = _queuestart &0xff ;
@@ -106,16 +106,17 @@ static inline int do_sqbs(u64 token, unsigned char state, int queue,static inline int do_eqbs (u64 token,unsigned char *state,int queue,int *start,int *count,int ack) { - register unsigned long _ccq asm ("0") = *count; - register unsigned long _token asm ("1") = token;unsigned long _queuestart = ((unsigned long )queue <<32 ) | *start;unsigned long _state = (unsigned long )ack <<63 ; +unsigned long _ccq = *count; asmvolatile ( -" .insn rrf,0xB99c0000,%1,%2,0,0" - :"+d" (_ccq),"+d" (_queuestart),"+d" (_state) - :"d" (_token) - :"memory" ,"cc" ); +" lgr 1,%[token]\n" +" .insn rrf,0xb99c0000,%[qs],%[state],%[ccq],0" + : [ccq]"+&d" (_ccq), [qs]"+&d" (_queuestart), + [state]"+&d" (_state) + : [token]"d" (token) + :"memory" ,"cc" ,"1" ); *count = _ccq &0xff ; *start = _queuestart &0xff ; *state = _state &0xff ;
drivers/s390/cio/qdio_main.c +33 -29
94 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 122/161 s390/qdio: fix do_sqbs() inline assembly constraint
In reply to Greg Kroah-HartmanFrom: Heiko Carstens <[email protected]>
[ Upstream commit 2862a2fdfae875888e3c1c3634e3422e01d98147 ]
Use "a" constraint instead of "d" constraint to pass the state parameter to the do_sqbs() inline assembly. This prevents that general purpose register zero is used for the state parameter.
If the compiler would select general purpose register zero this would be problematic for the used instruction in rsy format: the register used for the state parameter is a base register. If the base register is general purpose register zero the contents of the register are unexpectedly ignored when the instruction is executed.
This only applies to z/VM guests using QIOASSIST with dedicated (pass through) QDIO-based devices such as FCP [zfcp driver] as well as real OSA or HiperSockets [qeth driver].
A possible symptom for this case using zfcp is the following repeating kernel message pattern:
zfcp <devbusid>: A QDIO problem occurred
zfcp <devbusid>: A QDIO problem occurred
zfcp <devbusid>: qdio: ZFCP on SC <sc> using AI:1 QEBSM:1 PRI:1 TDD:1 SIGA: W zfcp <devbusid>: A QDIO problem occurred
zfcp <devbusid>: A QDIO problem occurred
Each of the qdio problem message can be accompanied by the following entries for the affected subchannel <sc> in /sys/kernel/debug/s390dbf/qdio_error/hex_ascii for zfcp or qeth:
<sc> ccq: 69....
<sc> SQBS ERROR.
--- drivers/s390/cio/qdio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/s390/cio/qdio.h +1 -1
@@ -95,7 +95,7 @@ static inline int do_sqbs(u64 token, unsigned char state, int queue," lgr 1,%[token]\n" " .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])" : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart) - : [state] "d" ((unsigned long)state), [token] "d" (token) + : [state] "a" ((unsigned long)state), [token] "d" (token) : "memory", "cc", "1"); *count = _ccq &0xff ; *start = _queuestart &0xff ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 123/161 watchdog: sp5100_tco: Immediately trigger upon starting.
In reply to Greg Kroah-HartmanFrom: Gregory Oakes <[email protected]>
commit 4eda19cc8a29cde3580ed73bf11dc73b4e757697 upstream.
The watchdog countdown is supposed to begin when the device file is opened. Instead, it would begin countdown upon the first write to or close of the device file. Now, the ping operation is called within the start operation which ensures the countdown begins. From experimenation, it does not appear possible to do this with a single write including both the start bit and the trigger bit. So, it is done as two distinct writes.
--- drivers/watchdog/sp5100_tco.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/watchdog/sp5100_tco.c +4 -0
@@ -98,6 +98,10 @@ static int tco_timer_start(struct watchd val |=SP5100_WDT_START_STOP_BIT ;writel (val,SP5100_WDT_CONTROL (tco->tcobase)); +/* This must be a distinct write. */ + val |=SP5100_WDT_TRIGGER_BIT ; +writel (val,SP5100_WDT_CONTROL (tco->tcobase)); +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 124/161 spi: fsl-spi: Re-organise transfer bits_per_word adaptation
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
(backported from upstream 8a5299a1278eadf1e08a598a5345c376206f171e)
For different reasons, fsl-spi driver performs bits_per_word modifications for different reasons:
- On CPU mode, to minimise amount of interrupts
- On CPM/QE mode to work around controller byte order
For CPU mode that's done in fsl_spi_prepare_message() while for CPM mode that's done in fsl_spi_setup_transfer().
Reunify all of it in fsl_spi_prepare_message(), and catch impossible cases early through master's bits_per_word_mask instead of returning EINVAL later.
--- drivers/spi/spi-fsl-spi.c | 50 +++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 27 deletions(-)
drivers/spi/spi-fsl-spi.c +23 -27
@@ -204,26 +204,6 @@ static int mspi_apply_cpu_mode_quirks(streturn bits_per_word; } -static int mspi_apply_qe_mode_quirks (struct spi_mpc8xxx_cs *cs, -struct spi_device *spi, -int bits_per_word) -{ -/* CPM/QE uses Little Endian for words > 8 -* so transform 16 and 32 bits words into 8 bits -* Unfortnatly that doesn't work for LSB so -* reject these for now */ -/* Note: 32 bits word, LSB works iff -* tfcr/rfcr is set to CPMFCR_GBL */ -if (spi->mode &SPI_LSB_FIRST && - bits_per_word >8 ) -return -EINVAL ; -if (bits_per_word <=8 ) -return bits_per_word; -if (bits_per_word ==16 || bits_per_word ==32 ) -return 8 ;/* pretend its 8 bits */ -return -EINVAL ; -} -static int fsl_spi_setup_transfer (struct spi_device *spi,struct spi_transfer *t) {
@@ -251,9 +231,6 @@ static int fsl_spi_setup_transfer(struct bits_per_word =mspi_apply_cpu_mode_quirks (cs, spi, mpc8xxx_spi, bits_per_word); - else - bits_per_word =mspi_apply_qe_mode_quirks (cs, spi, - bits_per_word);if (bits_per_word <0 )return bits_per_word;
@@ -371,14 +348,27 @@ static int fsl_spi_do_one_msg(struct spi* In CPU mode, optimize large byte transfers to use larger * bits_per_word values to reduce number of interrupts taken. */ -if (!(mpc8xxx_spi->flags &SPI_CPM_MODE )) { -list_for_each_entry (t, &m->transfers, transfer_list) { +list_for_each_entry (t, &m->transfers, transfer_list) { +if (!(mpc8xxx_spi->flags &SPI_CPM_MODE )) {if (t->len <256 || t->bits_per_word !=8 )continue ;if ((t->len &3 ) ==0 ) t->bits_per_word =32 ;else if ((t->len &1 ) ==0 ) t->bits_per_word =16 ; + }else { +/* +* CPM/QE uses Little Endian for words > 8 +* so transform 16 and 32 bits words into 8 bits +* Unfortnatly that doesn't work for LSB so +* reject these for now +* Note: 32 bits word, LSB works iff +* tfcr/rfcr is set to CPMFCR_GBL +*/ +if (m->spi->mode &SPI_LSB_FIRST && t->bits_per_word >8 ) +return -EINVAL ; +if (t->bits_per_word ==16 || t->bits_per_word ==32 ) + t->bits_per_word =8 ;/* pretend its 8 bits */ } }
@@ -637,8 +627,14 @@ static struct spi_master * fsl_spi_probeif (mpc8xxx_spi->type ==TYPE_GRLIB )fsl_spi_grlib_probe (dev); - master->bits_per_word_mask = - (SPI_BPW_RANGE_MASK (4 ,16 ) |SPI_BPW_MASK (32 )) & +if (mpc8xxx_spi->flags &SPI_CPM_MODE ) + master->bits_per_word_mask = + (SPI_BPW_RANGE_MASK (4 ,8 ) |SPI_BPW_MASK (16 ) |SPI_BPW_MASK (32 )); +else + master->bits_per_word_mask = + (SPI_BPW_RANGE_MASK (4 ,16 ) |SPI_BPW_MASK (32 )); + + master->bits_per_word_mask &=SPI_BPW_RANGE_MASK (1 , mpc8xxx_spi->max_bits_per_word);if (mpc8xxx_spi->flags &SPI_QE_CPU_MODE )
Greg Kroah-Hartman
maintainerPATCH 125/161 spi: fsl-cpm: Use 16 bit mode for large transfers with even size
In reply to Greg Kroah-HartmanFrom: Christophe Leroy <[email protected]>
(cherry picked from upstream fc96ec826bced75cc6b9c07a4ac44bbf651337ab)
On CPM, the RISC core is a lot more efficiant when doing transfers in 16-bits chunks than in 8-bits chunks, but unfortunately the words need to be byte swapped as seen in a previous commit.
So, for large tranfers with an even size, allocate a temporary tx buffer and byte-swap data before and after transfer.
This change allows setting higher speed for transfer. For instance on an MPC 8xx (CPM1 comms RISC processor), the documentation tells that transfer in byte mode at 1 kbit/s uses 0.200% of CPM load at 25 MHz while a word transfer at the same speed uses 0.032% of CPM load. This means the speed can be 6 times higher in word mode for the same CPM load.
For the time being, only do it on CPM1 as there must be a trade-off between the CPM load reduction and the CPU load required to byte swap the data.
--- drivers/spi/spi-fsl-cpm.c | 23 +++++++++++++++++++++++ drivers/spi/spi-fsl-spi.c | 3 +++ 2 files changed, 26 insertions(+)
drivers/spi/spi-fsl-cpm.c +23 -0
@@ -21,6 +21,7 @@#include <linux/spi/spi.h> #include <linux/types.h> #include <linux/platform_device.h> +#include <linux/byteorder/generic.h> #include "spi-fsl-cpm.h" #include "spi-fsl-lib.h"
@@ -120,6 +121,21 @@ int fsl_spi_cpm_bufs(struct mpc8xxx_spi mspi->rx_dma = mspi->dma_dummy_rx; mspi->map_rx_dma =0 ; } +if (t->bits_per_word ==16 && t->tx_buf) { +const u16 *src = t->tx_buf; +u16 *dst; +int i; + + dst =kmalloc (t->len,GFP_KERNEL ); +if (!dst) +return -ENOMEM ; + +for (i =0 ; i < t->len >>1 ; i++) + dst[i] =cpu_to_le16p (src + i); + + mspi->tx = dst; + mspi->map_tx_dma =1 ; + }if (mspi->map_tx_dma) {void *nonconst_tx = (void *)mspi->tx;/* shut up gcc */
@@ -173,6 +189,13 @@ void fsl_spi_cpm_bufs_complete(struct mpif (mspi->map_rx_dma)dma_unmap_single (dev, mspi->rx_dma, t->len,DMA_FROM_DEVICE ); mspi->xfer_in_progress =NULL ; + +if (t->bits_per_word ==16 && t->rx_buf) { +int i; + +for (i =0 ; i < t->len; i +=2 ) +le16_to_cpus (t->rx_buf + i); + } }EXPORT_SYMBOL_GPL (fsl_spi_cpm_bufs_complete);
drivers/spi/spi-fsl-spi.c +3 -0
@@ -369,6 +369,9 @@ static int fsl_spi_do_one_msg(struct spireturn -EINVAL ;if (t->bits_per_word ==16 || t->bits_per_word ==32 ) t->bits_per_word =8 ;/* pretend its 8 bits */ +if (t->bits_per_word ==8 && t->len >=256 && + (mpc8xxx_spi->flags &SPI_CPM1 )) + t->bits_per_word =16 ; } }
Greg Kroah-Hartman
maintainerPATCH 126/161 mt76: mt7615: Fix build with older compilers
In reply to Greg Kroah-HartmanFrom: Pablo Greco <[email protected]>
commit f53300fdaa84dc02f96ab9446b5bac4d20016c43 upstream.
Some compilers (tested with 4.8.5 from CentOS 7) fail properly process FIELD_GET inside an inline function, which ends up in a BUILD_BUG_ON. Convert inline function to a macro.
Fixes commit bf92e7685100 ("mt76: mt7615: add support for per-chain signal strength reporting")
Reported in https://lkml.org/lkml/2019/9/21/146
--- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +1 -4
@@ -13,10 +13,7 @@#include "../dma.h" #include "mac.h" -static inline s8 to_rssi (u32 field,u32 rxv) -{ -return (FIELD_GET (field, rxv) -220 ) /2 ; -} +#define to_rssi (field, rxv) ((FIELD_GET(field, rxv) - 220) / 2)static struct mt76_wcid *mt7615_rx_get_wcid (struct mt7615_dev *dev,u8 idx,bool unicast)
Greg Kroah-Hartman
maintainerPATCH 127/161 ALSA: hda/ca0132: add quirk for EVGA X299 DARK
In reply to Greg Kroah-HartmanFrom: Adam Stylinski <[email protected]>
commit 7843380d07bbeffd3ce6504e73cf61f840ae76ca upstream.
This quirk is necessary for surround and other DSP effects to work with the onboard ca0132 based audio chipset for the EVGA X299 dark mainboard.
--- sound/pci/hda/patch_ca0132.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/hda/patch_ca0132.c +1 -0
@@ -1182,6 +1182,7 @@ static const struct snd_pci_quirk ca0132SND_PCI_QUIRK (0x1458 ,0xA026 ,"Gigabyte G1.Sniper Z97" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x1458 ,0xA036 ,"Gigabyte GA-Z170X-Gaming 7" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x3842 ,0x1038 ,"EVGA X99 Classified" ,QUIRK_R3DI ), +SND_PCI_QUIRK (0x3842 ,0x104b ,"EVGA X299 Dark" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x3842 ,0x1055 ,"EVGA Z390 DARK" ,QUIRK_R3DI ),SND_PCI_QUIRK (0x1102 ,0x0013 ,"Recon3D" ,QUIRK_R3D ), SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
Greg Kroah-Hartman
maintainerPATCH 128/161 ALSA: hda/realtek: Enable headset onLenovo M70/M90
In reply to Greg Kroah-HartmanFrom: Bin Li <[email protected]>
commit 4ca110cab46561cd74a2acd9b447435acb4bec5f upstream.
Lenovo M70/M90 Gen4 are equipped with ALC897, and they need ALC897_FIXUP_HEADSET_MIC_PIN quirk to make its headset mic work. The previous quirk for M70/M90 is for Gen3.
--- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/hda/patch_realtek.c +2 -0
@@ -10370,6 +10370,8 @@ static const struct snd_pci_quirk alc662SND_PCI_QUIRK (0x17aa ,0x32cb ,"Lenovo ThinkCentre M70" ,ALC897_FIXUP_HEADSET_MIC_PIN ),SND_PCI_QUIRK (0x17aa ,0x32cf ,"Lenovo ThinkCentre M950" ,ALC897_FIXUP_HEADSET_MIC_PIN ),SND_PCI_QUIRK (0x17aa ,0x32f7 ,"Lenovo ThinkCentre M90" ,ALC897_FIXUP_HEADSET_MIC_PIN ), +SND_PCI_QUIRK (0x17aa ,0x3321 ,"Lenovo ThinkCentre M70 Gen4" ,ALC897_FIXUP_HEADSET_MIC_PIN ), +SND_PCI_QUIRK (0x17aa ,0x331b ,"Lenovo ThinkCentre M90 Gen4" ,ALC897_FIXUP_HEADSET_MIC_PIN ),SND_PCI_QUIRK (0x17aa ,0x3742 ,"Lenovo TianYi510Pro-14IOB" ,ALC897_FIXUP_HEADSET_MIC_PIN2 ),SND_PCI_QUIRK (0x17aa ,0x38af ,"Lenovo Ideapad Y550P" ,ALC662_FIXUP_IDEAPAD ), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
Greg Kroah-Hartman
maintainerPATCH 129/161 m68k: Move signal frame following exception on 68020/030
In reply to Greg Kroah-HartmanFrom: Finn Thain <[email protected]>
commit b845b574f86dcb6a70dfa698aa87a237b0878d2a upstream.
On 68030/020, an instruction such as, moveml %a2-%a3/%a5,%sp@- may cause a stack page fault during instruction execution (i.e. not at an instruction boundary) and produce a format 0xB exception frame.
In this situation, the value of USP will be unreliable. If a signal is to be delivered following the exception, this USP value is used to calculate the location for a signal frame. This can result in a corrupted user stack.
The corruption was detected in dash (actually in glibc) where it showed up as an intermittent "stack smashing detected" message and crash following signal delivery for SIGCHLD.
It was hard to reproduce that failure because delivery of the signal raced with the page fault and because the kernel places an unpredictable gap of up to 7 bytes between the USP and the signal frame.
A format 0xB exception frame can be produced by a bus error or an address error. The 68030 Users Manual says that address errors occur immediately upon detection during instruction prefetch. The instruction pipeline allows prefetch to overlap with other instructions, which means an address error can arise during the execution of a different instruction. So it seems likely that this patch may help in the address error case also.
--- arch/m68k/kernel/signal.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
arch/m68k/kernel/signal.c +10 -4
@@ -883,11 +883,17 @@ static inline int rt_setup_ucontext(stru }static inline void __user * -get_sigframe (struct ksignal *ksig,size_t frame_size) +get_sigframe (struct ksignal *ksig,struct pt_regs *tregs,size_t frame_size) {unsigned long usp =sigsp (rdusp (), ksig); +unsigned long gap =0 ; -return (void __user *)((usp - frame_size) &-8UL ); +if (CPU_IS_020_OR_030 && tregs->format ==0xb ) { +/* USP is unreliable so use worst-case value */ + gap =256 ; + } + +return (void __user *)((usp - gap - frame_size) &-8UL ); } static int setup_frame(struct ksignal *ksig, sigset_t *set,
@@ -905,7 +911,7 @@ static int setup_frame(struct ksignal *kreturn -EFAULT ; } - frame =get_sigframe (ksig,sizeof (*frame) + fsize); + frame =get_sigframe (ksig, tregs,sizeof (*frame) + fsize);if (fsize) err |=copy_to_user (frame +1 , regs +1 , fsize);
@@ -976,7 +982,7 @@ static int setup_rt_frame(struct ksignalreturn -EFAULT ; } - frame =get_sigframe (ksig,sizeof (*frame)); + frame =get_sigframe (ksig, tregs,sizeof (*frame));if (fsize) err |=copy_to_user (&frame->uc.uc_extra, regs +1 , fsize);
Greg Kroah-Hartman
maintainerPATCH 130/161 parisc: Handle kgdb breakpoints only in kernel context
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 6888ff04e37d01295620a73f3f7efbc79f6ef152 upstream.
The kernel kgdb break instructions should only be handled when running in kernel context.
--- arch/parisc/kernel/traps.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/kernel/traps.c +2 -2
@@ -305,8 +305,8 @@ static void handle_break(struct pt_regs#endif #ifdef CONFIG_KGDB -if (unlikely (iir ==PARISC_KGDB_COMPILED_BREAK_INSN || - iir ==PARISC_KGDB_BREAK_INSN )) { +if (unlikely ((iir ==PARISC_KGDB_COMPILED_BREAK_INSN || + iir ==PARISC_KGDB_BREAK_INSN )) && !user_mode (regs)) {kgdb_handle_exception (9 ,SIGTRAP ,0 , regs);return ; }
Greg Kroah-Hartman
maintainerPATCH 131/161 parisc: Allow to reboot machine after system halt
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 2028315cf59bb899a5ac7e87dc48ecb8fac7ac24 upstream.
In case a machine can't power-off itself on system shutdown, allow the user to reboot it by pressing the RETURN key.
--- arch/parisc/kernel/process.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
arch/parisc/kernel/process.c +8 -3
@@ -124,13 +124,18 @@ void machine_power_off(void)/* It seems we have no way to power the system off via * software. The user has to press the button himself. */ -printk (KERN_EMERG "System shut down completed.\n" -"Please power this system off now." ); +printk ("Power off or press RETURN to reboot.\n" );/* prevent soft lockup/stalled CPU messages for endless loop. */ rcu_sysrq_start ();lockup_detector_soft_poweroff (); -for (;;); +while (1 ) { +/* reboot if user presses RETURN key */ +if (pdc_iodc_getc () ==13 ) { +printk ("Rebooting...\n" ); +machine_restart (NULL ); + } + } }void (*pm_power_off)(void );
Greg Kroah-Hartman
maintainerPATCH 132/161 gpio: mockup: Fix mode of debugfs files
In reply to Greg Kroah-HartmanFrom: Zev Weiss <[email protected]>
commit 0a1bb16e0fe6650c3841e611de374bfd5578ad70 upstream.
This driver's debugfs files have had a read operation since commit 2a9e27408e12 ("gpio: mockup: rework debugfs interface"), but were still being created with write-only mode bits. Update them to indicate that the files can also be read.
--- drivers/gpio/gpio-mockup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpio/gpio-mockup.c +1 -1
@@ -339,7 +339,7 @@ static void gpio_mockup_debugfs_setup(st priv->offset = i; priv->desc = &gc->gpiodev->descs[i]; -debugfs_create_file (name,0200 , chip->dbg_dir, priv, +debugfs_create_file (name,0600 , chip->dbg_dir, priv, &gpio_mockup_debugfs_ops); }
Greg Kroah-Hartman
maintainerPATCH 133/161 btrfs: use nofs when cleaning up aborted transactions
In reply to Greg Kroah-HartmanFrom: Josef Bacik <[email protected]>
commit 597441b3436a43011f31ce71dc0a6c0bf5ce958a upstream.
Our CI system caught a lockdep splat:
======================================================
WARNING: possible circular locking dependency detected
6.3.0-rc7+ #1167 Not tainted
------------------------------------------------------
kswapd0/46 is trying to acquire lock:
ffff8c6543abd650 (sb_internal#2){++++}-{0:0}, at: btrfs_commit_inode_delayed_inode+0x5f/0x120
but task is already holding lock:
ffffffffabe61b40 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat+0x4aa/0x7a0
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (fs_reclaim){+.+.}-{0:0}:
fs_reclaim_acquire+0xa5/0xe0 kmem_cache_alloc+0x31/0x2c0 alloc_extent_state+0x1d/0xd0 __clear_extent_bit+0x2e0/0x4f0 try_release_extent_mapping+0x216/0x280 btrfs_release_folio+0x2e/0x90 invalidate_inode_pages2_range+0x397/0x470 btrfs_cleanup_dirty_bgs+0x9e/0x210 btrfs_cleanup_one_transaction+0x22/0x760 btrfs_commit_transaction+0x3b7/0x13a0 create_subvol+0x59b/0x970 btrfs_mksubvol+0x435/0x4f0 __btrfs_ioctl_snap_create+0x11e/0x1b0 btrfs_ioctl_snap_create_v2+0xbf/0x140 btrfs_ioctl+0xa45/0x28f0 __x64_sys_ioctl+0x88/0xc0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc
-> #0 (sb_internal#2){++++}-{0:0}:
__lock_acquire+0x1435/0x21a0 lock_acquire+0xc2/0x2b0 start_transaction+0x401/0x730 btrfs_commit_inode_delayed_inode+0x5f/0x120 btrfs_evict_inode+0x292/0x3d0 evict+0xcc/0x1d0 inode_lru_isolate+0x14d/0x1e0 __list_lru_walk_one+0xbe/0x1c0 list_lru_walk_one+0x58/0x80 prune_icache_sb+0x39/0x60 super_cache_scan+0x161/0x1f0 do_shrink_slab+0x163/0x340 shrink_slab+0x1d3/0x290 shrink_node+0x300/0x720 balance_pgdat+0x35c/0x7a0 kswapd+0x205/0x410 kthread+0xf0/0x120 ret_from_fork+0x29/0x50
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(fs_reclaim);
lock(sb_internal#2);
lock(fs_reclaim);
lock(sb_internal#2);*** DEADLOCK ***
3 locks held by kswapd0/46:
#0: ffffffffabe61b40 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat+0x4aa/0x7a0 #1: ffffffffabe50270 (shrinker_rwsem){++++}-{3:3}, at: shrink_slab+0x113/0x290 #2: ffff8c6543abd0e0 (&type->s_umount_key#44){++++}-{3:3}, at: super_cache_scan+0x38/0x1f0
stack backtrace: CPU: 0 PID: 46 Comm: kswapd0 Not tainted 6.3.0-rc7+ #1167 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x58/0x90 check_noncircular+0xd6/0x100 ? save_trace+0x3f/0x310 ? add_lock_to_list+0x97/0x120 __lock_acquire+0x1435/0x21a0 lock_acquire+0xc2/0x2b0 ? btrfs_commit_inode_delayed_inode+0x5f/0x120 start_transaction+0x401/0x730 ? btrfs_commit_inode_delayed_inode+0x5f/0x120 btrfs_commit_inode_delayed_inode+0x5f/0x120 btrfs_evict_inode+0x292/0x3d0 ? lock_release+0x134/0x270 ? __pfx_wake_bit_function+0x10/0x10 evict+0xcc/0x1d0 inode_lru_isolate+0x14d/0x1e0 __list_lru_walk_one+0xbe/0x1c0 ? __pfx_inode_lru_isolate+0x10/0x10 ? __pfx_inode_lru_isolate+0x10/0x10 list_lru_walk_one+0x58/0x80 prune_icache_sb+0x39/0x60 super_cache_scan+0x161/0x1f0 do_shrink_slab+0x163/0x340 shrink_slab+0x1d3/0x290 shrink_node+0x300/0x720 balance_pgdat+0x35c/0x7a0 kswapd+0x205/0x410 ? __pfx_autoremove_wake_function+0x10/0x10 ? __pfx_kswapd+0x10/0x10 kthread+0xf0/0x120 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x29/0x50 </TASK>
This happens because when we abort the transaction in the transaction commit path we call invalidate_inode_pages2_range on our block group cache inodes (if we have space cache v1) and any delalloc inodes we may have. The plain invalidate_inode_pages2_range() call passes through GFP_KERNEL, which makes sense in most cases, but not here. Wrap these two invalidate callees with memalloc_nofs_save/memalloc_nofs_restore to make sure we don't end up with the fs reclaim dependency under the transaction dependency.
--- fs/btrfs/disk-io.c | 9 +++++++++ 1 file changed, 9 insertions(+)
fs/btrfs/disk-io.c +9 -0
@@ -4408,7 +4408,11 @@ static void btrfs_destroy_delalloc_inode*/ inode =igrab (&btrfs_inode->vfs_inode);if (inode) { +unsigned int nofs_flag; + + nofs_flag =memalloc_nofs_save ();invalidate_inode_pages2 (inode->i_mapping); +memalloc_nofs_restore (nofs_flag);iput (inode); }spin_lock (&root->delalloc_lock);
@@ -4526,7 +4530,12 @@ static void btrfs_cleanup_bg_io(struct b inode = cache->io_ctl.inode;if (inode) { +unsigned int nofs_flag; + + nofs_flag =memalloc_nofs_save ();invalidate_inode_pages2 (inode->i_mapping); +memalloc_nofs_restore (nofs_flag); +BTRFS_I (inode)->generation =0 ; cache->io_ctl.inode =NULL ;iput (inode);
Greg Kroah-Hartman
maintainerPATCH 134/161 x86/mm: Avoid incomplete Global INVLPG flushes
In reply to Greg Kroah-HartmanFrom: Dave Hansen <[email protected]>
commit ce0b15d11ad837fbacc5356941712218e38a0a83 upstream.
The INVLPG instruction is used to invalidate TLB entries for a specified virtual address. When PCIDs are enabled, INVLPG is supposed to invalidate TLB entries for the specified address for both the current PCID *and* Global entries. (Note: Only kernel mappings set Global=1.)
Unfortunately, some INVLPG implementations can leave Global translations unflushed when PCIDs are enabled.
As a workaround, never enable PCIDs on affected processors.
I expect there to eventually be microcode mitigations to replace this software workaround. However, the exact version numbers where that will happen are not known today. Once the version numbers are set in stone, the processor list can be tweaked to only disable PCIDs on affected processors with affected microcode.
Note: if anyone wants a quick fix that doesn't require patching, just stick 'nopcid' on your kernel command-line.
--- arch/x86/include/asm/intel-family.h | 5 +++++ arch/x86/mm/init.c | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+)
arch/x86/include/asm/intel-family.h +5 -0
@@ -96,6 +96,11 @@#define INTEL_FAM6_LAKEFIELD 0x8A#define INTEL_FAM6_ALDERLAKE 0x97#define INTEL_FAM6_ALDERLAKE_L 0x9A +#define INTEL_FAM6_ALDERLAKE_N 0xBE + +#define INTEL_FAM6_RAPTORLAKE 0xB7 +#define INTEL_FAM6_RAPTORLAKE_P 0xBA +#define INTEL_FAM6_RAPTORLAKE_S 0xBF/* "Small Core" Processors (Atom) */
arch/x86/mm/init.c +25 -0
@@ -9,6 +9,7 @@#include <linux/sched/task.h> #include <asm/set_memory.h> +#include <asm/cpu_device_id.h> #include <asm/e820/api.h> #include <asm/init.h> #include <asm/page.h>
@@ -208,6 +209,24 @@ static void __init probe_page_size_mask( } } +#define INTEL_MATCH (_model) { .vendor = X86_VENDOR_INTEL, \ + .family = 6, \ + .model = _model, \ + } +/* +* INVLPG may not properly flush Global entries +* on these CPUs when PCIDs are enabled. +*/ +static const struct x86_cpu_id invlpg_miss_ids[] = { +INTEL_MATCH (INTEL_FAM6_ALDERLAKE ), +INTEL_MATCH (INTEL_FAM6_ALDERLAKE_L ), +INTEL_MATCH (INTEL_FAM6_ALDERLAKE_N ), +INTEL_MATCH (INTEL_FAM6_RAPTORLAKE ), +INTEL_MATCH (INTEL_FAM6_RAPTORLAKE_P ), +INTEL_MATCH (INTEL_FAM6_RAPTORLAKE_S ), + {} +}; +static void setup_pcid (void ) {if (!IS_ENABLED (CONFIG_X86_64 ))
@@ -216,6 +235,12 @@ static void setup_pcid(void)if (!boot_cpu_has (X86_FEATURE_PCID ))return ; +if (x86_match_cpu (invlpg_miss_ids)) { +pr_info ("Incomplete global flushes, disabling PCID" ); +setup_clear_cpu_cap (X86_FEATURE_PCID ); +return ; + } +if (boot_cpu_has (X86_FEATURE_PGE )) {/* * This can't be cr4_set_bits_and_update_boot() -- the
Greg Kroah-Hartman
maintainerPATCH 135/161 selftests/memfd: Fix unknown type name build failure
In reply to Greg Kroah-HartmanFrom: Hardik Garg <[email protected]>
Partially backport v6.3 commit 11f75a01448f ("selftests/memfd: add tests for MFD_NOEXEC_SEAL MFD_EXEC") to fix an unknown type name build error. In some systems, the __u64 typedef is not present due to differences in system headers, causing compilation errors like this one:
fuse_test.c:64:8: error: unknown type name '__u64'
64 | static __u64 mfd_assert_get_seals(int fd)
This header includes the __u64 typedef which increases the likelihood of successful compilation on a wider variety of systems.
--- tools/testing/selftests/memfd/fuse_test.c | 1 + 1 file changed, 1 insertion(+)
tools/testing/selftests/memfd/fuse_test.c +1 -0
@@ -22,6 +22,7 @@#include <linux/falloc.h> #include <linux/fcntl.h> #include <linux/memfd.h> +#include <linux/types.h> #include <sched.h> #include <stdio.h> #include <stdlib.h>
Greg Kroah-Hartman
maintainerPATCH 136/161 parisc: Fix flush_dcache_page() for usage from irq context
In reply to Greg Kroah-HartmanFrom: Helge Deller <[email protected]>
commit 61e150fb310729c98227a5edf6e4a3619edc3702 upstream.
Since at least kernel 6.1, flush_dcache_page() is called with IRQs disabled, e.g. from aio_complete().
But the current implementation for flush_dcache_page() on parisc unintentionally re-enables IRQs, which may lead to deadlocks.
Fix it by using xa_lock_irqsave() and xa_unlock_irqrestore() for the flush_dcache_mmap_*lock() macros instead.
--- arch/parisc/include/asm/cacheflush.h | 5 +++++ arch/parisc/kernel/cache.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-)
arch/parisc/include/asm/cacheflush.h +5 -0
@@ -57,6 +57,11 @@ extern void flush_dcache_page(struct pag#define flush_dcache_mmap_lock (mapping) xa_lock_irq(&mapping->i_pages)#define flush_dcache_mmap_unlock (mapping) xa_unlock_irq(&mapping->i_pages) +#define flush_dcache_mmap_lock_irqsave (mapping, flags) \ + xa_lock_irqsave(&mapping->i_pages, flags) +#define flush_dcache_mmap_unlock_irqrestore (mapping, flags) \ + xa_unlock_irqrestore(&mapping->i_pages, flags) +#define flush_icache_page (vma,page) do { \ flush_kernel_dcache_page(page); \
arch/parisc/kernel/cache.c +3 -2
@@ -328,6 +328,7 @@ void flush_dcache_page(struct page *pagestruct vm_area_struct *mpnt;unsigned long offset;unsigned long addr, old_addr =0 ; +unsigned long flags;pgoff_t pgoff;if (mapping && !mapping_mapped (mapping)) {
@@ -347,7 +348,7 @@ void flush_dcache_page(struct page *page* declared as MAP_PRIVATE or MAP_SHARED), so we only need * to flush one address here for them all to become coherent */ -flush_dcache_mmap_lock (mapping); +flush_dcache_mmap_lock_irqsave (mapping, flags); vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { offset = (pgoff - mpnt->vm_pgoff) <<PAGE_SHIFT ; addr = mpnt->vm_start + offset;
@@ -370,7 +371,7 @@ void flush_dcache_page(struct page *page old_addr = addr; } } -flush_dcache_mmap_unlock (mapping); +flush_dcache_mmap_unlock_irqrestore (mapping, flags); }EXPORT_SYMBOL (flush_dcache_page);
Greg Kroah-Hartman
maintainerPATCH 137/161 x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms
In reply to Greg Kroah-HartmanFrom: Zhang Rui <[email protected]>
commit edc0a2b5957652f4685ef3516f519f84807087db upstream.
Traditionally, all CPUs in a system have identical numbers of SMT siblings. That changes with hybrid processors where some logical CPUs have a sibling and others have none.
Today, the CPU boot code sets the global variable smp_num_siblings when every CPU thread is brought up. The last thread to boot will overwrite it with the number of siblings of *that* thread. That last thread to boot will "win". If the thread is a Pcore, smp_num_siblings == 2. If it is an Ecore, smp_num_siblings == 1.
smp_num_siblings describes if the *system* supports SMT. It should specify the maximum number of SMT threads among all cores.
Ensure that smp_num_siblings represents the system-wide maximum number of siblings by always increasing its value. Never allow it to decrease.
On MeteorLake-P platform, this fixes a problem that the Ecore CPUs are not updated in any cpu sibling map because the system is treated as an UP system when probing Ecore CPUs.
Below shows part of the CPU topology information before and after the fix, for both Pcore and Ecore CPU (cpu0 is Pcore, cpu 12 is Ecore).
...
-/sys/devices/system/cpu/cpu0/topology/package_cpus:000fff -/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-11 +/sys/devices/system/cpu/cpu0/topology/package_cpus:3fffff +/sys/devices/system/cpu/cpu0/topology/package_cpus_list:0-21
...
-/sys/devices/system/cpu/cpu12/topology/package_cpus:001000 -/sys/devices/system/cpu/cpu12/topology/package_cpus_list:12 +/sys/devices/system/cpu/cpu12/topology/package_cpus:3fffff +/sys/devices/system/cpu/cpu12/topology/package_cpus_list:0-21
Notice that the "before" 'package_cpus_list' has only one CPU. This means that userspace tools like lscpu will see a little laptop like an 11-socket system:
-Core(s) per socket: 1 -Socket(s): 11 +Core(s) per socket: 16 +Socket(s): 1
This is also expected to make the scheduler do rather wonky things too.
[ dhansen: remove CPUID detail from changelog, add end user effects ]
--- arch/x86/kernel/cpu/topology.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/topology.c +3 -2
@@ -79,7 +79,7 @@ int detect_extended_topology_early(struc* initial apic id, which also represents 32-bit extended x2apic id. */ c->initial_apicid = edx; - smp_num_siblings =LEVEL_MAX_SIBLINGS (ebx); + smp_num_siblings =max_t (int, smp_num_siblings,LEVEL_MAX_SIBLINGS (ebx));#endif return 0 ; }
@@ -107,7 +107,8 @@ int detect_extended_topology(struct cpui*/ cpuid_count (leaf,SMT_LEVEL , &eax, &ebx, &ecx, &edx); c->initial_apicid = edx; - core_level_siblings = smp_num_siblings =LEVEL_MAX_SIBLINGS (ebx); + core_level_siblings =LEVEL_MAX_SIBLINGS (ebx); + smp_num_siblings =max_t (int, smp_num_siblings,LEVEL_MAX_SIBLINGS (ebx)); core_plus_mask_width = ht_mask_width =BITS_SHIFT_NEXT_LEVEL (eax); die_level_siblings =LEVEL_MAX_SIBLINGS (ebx); die_plus_mask_width =BITS_SHIFT_NEXT_LEVEL (eax);
Greg Kroah-Hartman
maintainerPATCH 138/161 debugobjects: Dont wake up kswapd from fill_pool()
In reply to Greg Kroah-HartmanFrom: Tetsuo Handa <[email protected]>
commit eb799279fb1f9c63c520fe8c1c41cb9154252db6 upstream.
syzbot is reporting a lockdep warning in fill_pool() because the allocation from debugobjects is using GFP_ATOMIC, which is (__GFP_HIGH | __GFP_KSWAPD_RECLAIM) and therefore tries to wake up kswapd, which acquires kswapd_wait::lock.
Since fill_pool() might be called with arbitrary locks held, fill_pool() should not assume that acquiring kswapd_wait::lock is safe.
Use __GFP_HIGH instead and remove __GFP_NORETRY as it is pointless for !__GFP_DIRECT_RECLAIM allocation.
--- lib/debugobjects.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/debugobjects.c +1 -1
@@ -128,7 +128,7 @@ static const char *obj_states[ODEBUG_STAstatic void fill_pool (void ) { -gfp_t gfp =GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN; +gfp_t gfp = __GFP_HIGH | __GFP_NOWARN;struct debug_obj *obj;unsigned long flags;
Greg Kroah-Hartman
maintainerPATCH 139/161 fbdev: udlfb: Fix endpoint check
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit ed9de4ed39875706607fb08118a58344ae6c5f42 upstream.
The syzbot fuzzer detected a problem in the udlfb driver, caused by an endpoint not having the expected type:
usb 1-1: Read EDID byte 0 failed: -71
usb 1-1: Unable to get valid EDID from device/display
------------[ cut here ]------------ usb 1-1: BOGUS urb xfer, pipe 3 != type 1 WARNING: CPU: 0 PID: 9 at drivers/usb/core/urb.c:504 usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 Modules linked in: CPU: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.4.0-rc1-syzkaller-00016-ga4422ff22142 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/28/2023 Workqueue: usb_hub_wq hub_event RIP: 0010:usb_submit_urb+0xed6/0x1880 drivers/usb/core/urb.c:504 ... Call Trace: <TASK> dlfb_submit_urb+0x92/0x180 drivers/video/fbdev/udlfb.c:1980 dlfb_set_video_mode+0x21f0/0x2950 drivers/video/fbdev/udlfb.c:315 dlfb_ops_set_par+0x2a7/0x8d0 drivers/video/fbdev/udlfb.c:1111 dlfb_usb_probe+0x149a/0x2710 drivers/video/fbdev/udlfb.c:1743
The current approach for this issue failed to catch the problem because it only checks for the existence of a bulk-OUT endpoint; it doesn't check whether this endpoint is the one that the driver will actually use.
We can fix the problem by instead checking that the endpoint used by the driver does exist and is bulk-OUT.
--- drivers/video/fbdev/udlfb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/video/fbdev/udlfb.c +8 -5
@@ -27,6 +27,8 @@#include <video/udlfb.h> #include "edid.h" +#define OUT_EP_NUM 1/* The endpoint number we will use */ +static const struct fb_fix_screeninfo dlfb_fix = { .id ="udlfb" , .type =FB_TYPE_PACKED_PIXELS ,
@@ -1652,7 +1654,7 @@ static int dlfb_usb_probe(struct usb_intstruct fb_info *info;int retval;struct usb_device *usbdev =interface_to_usbdev (intf); -struct usb_endpoint_descriptor *out; +static u8 out_ep[] = {OUT_EP_NUM +USB_DIR_OUT ,0 };/* usb initialization */ dlfb =kzalloc (sizeof (*dlfb),GFP_KERNEL );
@@ -1666,9 +1668,9 @@ static int dlfb_usb_probe(struct usb_int dlfb->udev =usb_get_dev (usbdev);usb_set_intfdata (intf, dlfb); - retval =usb_find_common_endpoints (intf->cur_altsetting,NULL , &out,NULL ,NULL ); -if (retval) { -dev_err (&intf->dev,"Device should have at lease 1 bulk endpoint!\n" ); +if (!usb_check_bulk_endpoints (intf, out_ep)) { +dev_err (&intf->dev,"Invalid DisplayLink device!\n" ); + retval = -EINVAL ; goto error; }
@@ -1927,7 +1929,8 @@ retry: }/* urb->transfer_buffer_length set to actual before submit */ -usb_fill_bulk_urb (urb, dlfb->udev,usb_sndbulkpipe (dlfb->udev,1 ), +usb_fill_bulk_urb (urb, dlfb->udev, +usb_sndbulkpipe (dlfb->udev,OUT_EP_NUM ), buf, size, dlfb_urb_completion, unode); urb->transfer_flags |=URB_NO_TRANSFER_DMA_MAP ;
Greg Kroah-Hartman
maintainerPATCH 140/161 net: fix stack overflow when LRO is disabled for virtual interfaces
In reply to Greg Kroah-HartmanFrom: Taehee Yoo <[email protected]>
commit ae9b15fbe63447bc1d3bba3769f409d17ca6fdf6 upstream.
When the virtual interface's feature is updated, it synchronizes the updated feature for its own lower interface.
This propagation logic should be worked as the iteration, not recursively. But it works recursively due to the netdev notification unexpectedly. This problem occurs when it disables LRO only for the team and bonding interface type.
team0
|
+------+------+-----+-----+
| | | | |
team1 team2 team3 ... team200If team0's LRO feature is updated, it generates the NETDEV_FEAT_CHANGE event to its own lower interfaces(team1 ~ team200).
It is worked by netdev_sync_lower_features().
So, the NETDEV_FEAT_CHANGE notification logic of each lower interface work iteratively.
But generated NETDEV_FEAT_CHANGE event is also sent to the upper interface too.
upper interface(team0) generates the NETDEV_FEAT_CHANGE event for its own lower interfaces again.
lower and upper interfaces receive this event and generate this event again and again.
So, the stack overflow occurs.
But it is not the infinite loop issue.
Because the netdev_sync_lower_features() updates features before generating the NETDEV_FEAT_CHANGE event.
Already synchronized lower interfaces skip notification logic. So, it is just the problem that iteration logic is changed to the recursive unexpectedly due to the notification mechanism.
Reproducer:
ip link add team0 type team
ethtool -K team0 lro on
for i in {1..200}
do
ip link add team$i master team0 type team
ethtool -K team$i lro on
done
ethtool -K team0 lro off
In order to fix it, the notifier_ctx member of bonding/team is introduced.
--- drivers/net/bonding/bond_main.c | 8 +++++++- drivers/net/team/team.c | 7 ++++++- include/linux/if_team.h | 1 + include/net/bonding.h | 1 + 4 files changed, 15 insertions(+), 2 deletions(-)
drivers/net/bonding/bond_main.c +7 -1
@@ -3239,7 +3239,11 @@ static int bond_slave_netdev_event(unsigunblock_netpoll_tx ();break ;case NETDEV_FEAT_CHANGE : -bond_compute_features (bond); +if (!bond->notifier_ctx) { + bond->notifier_ctx = true; +bond_compute_features (bond); + bond->notifier_ctx = false; + }break ;case NETDEV_RESEND_IGMP :/* Propagate to master device */
@@ -4878,6 +4882,8 @@ static int bond_init(struct net_device *if (!bond->wq)return -ENOMEM ; + bond->notifier_ctx = false; +spin_lock_init (&bond->stats_lock);lockdep_register_key (&bond->stats_lock_key);lockdep_set_class (&bond->stats_lock, &bond->stats_lock_key);
drivers/net/team/team.c +6 -1
@@ -1624,6 +1624,7 @@ static int team_init(struct net_device * team->dev = dev;team_set_no_mode (team); + team->notifier_ctx = false; team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats);if (!team->pcpu_stats)
@@ -3015,7 +3016,11 @@ static int team_device_event(struct notiteam_del_slave (port->team->dev, dev);break ;case NETDEV_FEAT_CHANGE : -team_compute_features (port->team); +if (!port->team->notifier_ctx) { + port->team->notifier_ctx = true; +team_compute_features (port->team); + port->team->notifier_ctx = false; + }break ;case NETDEV_PRECHANGEMTU :/* Forbid to change mtu of underlaying device */
include/linux/if_team.h +1 -0
@@ -211,6 +211,7 @@ struct team {bool queue_override_enabled;struct list_head *qom_lists;/* array of queue override mapping lists */ bool port_mtu_change_allowed; +bool notifier_ctx;struct {unsigned int count;unsigned int interval;/* in ms */
include/net/bonding.h +1 -0
@@ -207,6 +207,7 @@ struct bonding {struct slave __rcu *primary_slave;struct bond_up_slave __rcu *usable_slaves;/* Array of usable slaves */ bool force_primary; +bool notifier_ctx;s32 slave_cnt;/* never change this value outside the attach/detach wrappers */ int (*recv_probe)(const struct sk_buff *,struct bonding *,struct slave *);
Greg Kroah-Hartman
maintainerPATCH 141/161 udplite: Fix NULL pointer dereference in __sk_mem_raise_allocated().
In reply to Greg Kroah-HartmanFrom: Kuniyuki Iwashima <[email protected]>
commit ad42a35bdfc6d3c0fc4cb4027d7b2757ce665665 upstream.
syzbot reported [0] a null-ptr-deref in sk_get_rmem0() while using IPPROTO_UDPLITE (0x88):
14:25:52 executing program 1:
r0 = socket$inet6(0xa, 0x80002, 0x88)
We had a similar report [1] for probably sk_memory_allocated_add() in __sk_mem_raise_allocated(), and commit c915fe13cbaa ("udplite: fix NULL pointer dereference") fixed it by setting .memory_allocated for udplite_prot and udplitev6_prot.
To fix the variant, we need to set either .sysctl_wmem_offset or .sysctl_rmem.
Now UDP and UDPLITE share the same value for .memory_allocated, so we use the same .sysctl_wmem_offset for UDP and UDPLITE.
[0]:
general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 0 PID: 6829 Comm: syz-executor.1 Not tainted 6.4.0-rc2-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/28/2023 RIP: 0010:sk_get_rmem0 include/net/sock.h:2907 [inline] RIP: 0010:__sk_mem_raise_allocated+0x806/0x17a0 net/core/sock.c:3006 Code: c1 ea 03 80 3c 02 00 0f 85 23 0f 00 00 48 8b 44 24 08 48 8b 98 38 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 da 48 c1 ea 03 <0f> b6 14 02 48 89 d8 83 e0 07 83 c0 03 38 d0 0f 8d 6f 0a 00 00 8b RSP: 0018:ffffc90005d7f450 EFLAGS: 00010246 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffc90004d92000 RDX: 0000000000000000 RSI: ffffffff88066482 RDI: ffffffff8e2ccbb8 RBP: ffff8880173f7000 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000030000 R13: 0000000000000001 R14: 0000000000000340 R15: 0000000000000001 FS: 0000000000000000(0000) GS:ffff8880b9800000(0063) knlGS:00000000f7f1cb40 CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033 CR2: 000000002e82f000 CR3: 0000000034ff0000 CR4: 00000000003506f0 Call Trace: <TASK> __sk_mem_schedule+0x6c/0xe0 net/core/sock.c:3077 udp_rmem_schedule net/ipv4/udp.c:1539 [inline] __udp_enqueue_schedule_skb+0x776/0xb30 net/ipv4/udp.c:1581 __udpv6_queue_rcv_skb net/ipv6/udp.c:666 [inline] udpv6_queue_rcv_one_skb+0xc39/0x16c0 net/ipv6/udp.c:775 udpv6_queue_rcv_skb+0x194/0xa10 net/ipv6/udp.c:793 __udp6_lib_mcast_deliver net/ipv6/udp.c:906 [inline] __udp6_lib_rcv+0x1bda/0x2bd0 net/ipv6/udp.c:1013 ip6_protocol_deliver_rcu+0x2e7/0x1250 net/ipv6/ip6_input.c:437 ip6_input_finish+0x150/0x2f0 net/ipv6/ip6_input.c:482 NF_HOOK include/linux/netfilter.h:303 [inline] NF_HOOK include/linux/netfilter.h:297 [inline] ip6_input+0xa0/0xd0 net/ipv6/ip6_input.c:491 ip6_mc_input+0x40b/0xf50 net/ipv6/ip6_input.c:585 dst_input include/net/dst.h:468 [inline] ip6_rcv_finish net/ipv6/ip6_input.c:79 [inline] NF_HOOK include/linux/netfilter.h:303 [inline] NF_HOOK include/linux/netfilter.h:297 [inline] ipv6_rcv+0x250/0x380 net/ipv6/ip6_input.c:309 __netif_receive_skb_one_core+0x114/0x180 net/core/dev.c:5491 __netif_receive_skb+0x1f/0x1c0 net/core/dev.c:5605 netif_receive_skb_internal net/core/dev.c:5691 [inline] netif_receive_skb+0x133/0x7a0 net/core/dev.c:5750 tun_rx_batched+0x4b3/0x7a0 drivers/net/tun.c:1553 tun_get_user+0x2452/0x39c0 drivers/net/tun.c:1989 tun_chr_write_iter+0xdf/0x200 drivers/net/tun.c:2035 call_write_iter include/linux/fs.h:1868 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x945/0xd50 fs/read_write.c:584 ksys_write+0x12b/0x250 fs/read_write.c:637 do_syscall_32_irqs_on arch/x86/entry/common.c:112 [inline] __do_fast_syscall_32+0x65/0xf0 arch/x86/entry/common.c:178 do_fast_syscall_32+0x33/0x70 arch/x86/entry/common.c:203 entry_SYSENTER_compat_after_hwframe+0x70/0x82 RIP: 0023:0xf7f21579 Code: b8 01 10 06 03 74 b4 01 10 07 03 74 b0 01 10 08 03 74 d8 01 00 00 00 00 00 00 00 00 00 00 00 00 00 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90 90 90 8d b4 26 00 00 00 00 8d b4 26 00 00 00 00 RSP: 002b:00000000f7f1c590 EFLAGS: 00000282 ORIG_RAX: 0000000000000004 RAX: ffffffffffffffda RBX: 00000000000000c8 RCX: 0000000020000040 RDX: 0000000000000083 RSI: 00000000f734e000 RDI: 0000000000000000 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000296 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK> Modules linked in:
--- net/ipv4/udplite.c | 2 ++ net/ipv6/udplite.c | 2 ++ 2 files changed, 4 insertions(+)
net/ipv4/udplite.c +2 -0
@@ -62,6 +62,8 @@ struct proto udplite_prot = { .get_port = udp_v4_get_port, .memory_allocated = &udp_memory_allocated, .sysctl_mem = sysctl_udp_mem, + .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), .obj_size = sizeof(struct udp_sock), .h.udp_table = &udplite_table, #ifdef CONFIG_COMPAT
net/ipv6/udplite.c +2 -0
@@ -57,6 +57,8 @@ struct proto udplitev6_prot = { .get_port = udp_v6_get_port, .memory_allocated = &udp_memory_allocated, .sysctl_mem = sysctl_udp_mem, + .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), .obj_size = sizeof(struct udp6_sock), .h.udp_table = &udplite_table, #ifdef CONFIG_COMPAT
Greg Kroah-Hartman
maintainerPATCH 142/161 USB: core: Add routines for endpoint checks in old drivers
In reply to Greg Kroah-HartmanFrom: Alan Stern <[email protected]>
commit 13890626501ffda22b18213ddaf7930473da5792 upstream.
Many of the older USB drivers in the Linux USB stack were written based simply on a vendor's device specification. They use the endpoint information in the spec and assume these endpoints will always be present, with the properties listed, in any device matching the given vendor and product IDs.
While that may have been true back then, with spoofing and fuzzing it is not true any more. More and more we are finding that those old drivers need to perform at least a minimum of checking before they try to use any endpoint other than ep0.
To make this checking as simple as possible, we now add a couple of utility routines to the USB core. usb_check_bulk_endpoints() and usb_check_int_endpoints() take an interface pointer together with a list of endpoint addresses (numbers and directions). They check that the interface's current alternate setting includes endpoints with those addresses and that each of these endpoints has the right type:
bulk or interrupt, respectively.
Although we already have usb_find_common_endpoints() and related routines meant for a similar purpose, they are not well suited for this kind of checking. Those routines find endpoints of various kinds, but only one (either the first or the last) of each kind, and they don't verify that the endpoints' addresses agree with what the caller expects.
In theory the new routines could be more general: They could take a particular altsetting as their argument instead of always using the interface's current altsetting. In practice I think this won't matter too much; multiple altsettings tend to be used for transferring media (audio or visual) over isochronous endpoints, not bulk or interrupt. Drivers for such devices will generally require more sophisticated checking than these simplistic routines provide.
--- drivers/usb/core/usb.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb.h | 5 +++ 2 files changed, 81 insertions(+)
drivers/usb/core/usb.c +76 -0
@@ -209,6 +209,82 @@ int usb_find_common_endpoints_reverse(stEXPORT_SYMBOL_GPL (usb_find_common_endpoints_reverse);/** +* usb_find_endpoint() - Given an endpoint address, search for the endpoint's +* usb_host_endpoint structure in an interface's current altsetting. +* @intf: the interface whose current altsetting should be searched +* @ep_addr: the endpoint address (number and direction) to find +* +* Search the altsetting's list of endpoints for one with the specified address. +* +* Return: Pointer to the usb_host_endpoint if found, %NULL otherwise. +*/ +static const struct usb_host_endpoint *usb_find_endpoint ( +const struct usb_interface *intf,unsigned int ep_addr) +{ +int n; +const struct usb_host_endpoint *ep; + + n = intf->cur_altsetting->desc.bNumEndpoints; + ep = intf->cur_altsetting->endpoint; +for (; n >0 ; (--n, ++ep)) { +if (ep->desc.bEndpointAddress == ep_addr) +return ep; + } +return NULL ; +} + +/** +* usb_check_bulk_endpoints - Check whether an interface's current altsetting +* contains a set of bulk endpoints with the given addresses. +* @intf: the interface whose current altsetting should be searched +* @ep_addrs: 0-terminated array of the endpoint addresses (number and +* direction) to look for +* +* Search for endpoints with the specified addresses and check their types. +* +* Return: %true if all the endpoints are found and are bulk, %false otherwise. +*/ +bool usb_check_bulk_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs) +{ +const struct usb_host_endpoint *ep; + +for (; *ep_addrs; ++ep_addrs) { + ep =usb_find_endpoint (intf, *ep_addrs); +if (!ep || !usb_endpoint_xfer_bulk (&ep->desc)) +return false; + } +return true; +} +EXPORT_SYMBOL_GPL (usb_check_bulk_endpoints); + +/** +* usb_check_int_endpoints - Check whether an interface's current altsetting +* contains a set of interrupt endpoints with the given addresses. +* @intf: the interface whose current altsetting should be searched +* @ep_addrs: 0-terminated array of the endpoint addresses (number and +* direction) to look for +* +* Search for endpoints with the specified addresses and check their types. +* +* Return: %true if all the endpoints are found and are interrupt, +* %false otherwise. +*/ +bool usb_check_int_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs) +{ +const struct usb_host_endpoint *ep; + +for (; *ep_addrs; ++ep_addrs) { + ep =usb_find_endpoint (intf, *ep_addrs); +if (!ep || !usb_endpoint_xfer_int (&ep->desc)) +return false; + } +return true; +} +EXPORT_SYMBOL_GPL (usb_check_int_endpoints); + +/** * usb_find_alt_setting() - Given a configuration, find the alternate setting * for the given interface. * @config: the configuration to search (not necessarily the current config).
include/linux/usb.h +5 -0
@@ -279,6 +279,11 @@ void usb_put_intf(struct usb_interface *#define USB_MAXINTERFACES 32#define USB_MAXIADS (USB_MAXINTERFACES/2) +bool usb_check_bulk_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs); +bool usb_check_int_endpoints ( +const struct usb_interface *intf,const u8 *ep_addrs); +/* * USB Resume Timer: Every Host controller driver should drive the resume * signalling on the bus for the amount of time defined by this macro.