5.15.211-rc1 review
Greg Kroah-Hartman
maintainercover 5.15.211-rc1 review
This is the start of the stable review cycle for the 5.15.211 release. There are 95 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 Sat, 04 Jul 2026 15:50:58 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.211-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.15.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.15.211-rc1
Thadeu Lima de Souza Cascardo <[email protected]>
dlm: prevent NPD when writing a positive value to event_done
Giovanni Cabiddu <[email protected]>
crypto: qat - remove unused character device and IOCTLs
Herbert Xu <[email protected]>
crypto: qat - Return pointer directly in adf_ctl_alloc_resources
Thorsten Blum <[email protected]>
crypto: qat - Replace kzalloc() + copy_from_user() with memdup_user()
Bagas Sanjaya <[email protected]>
Documentation: ioctl-number: Extend "Include File" column width
Gil Portnoy <[email protected]>
ksmbd: reject non-VALID session in compound request branch
Joanne Koong <[email protected]>
fuse: re-lock request before replacing page cache folio
Santosh Kalluri <[email protected]>
net: phonet: free phonet_device after RCU grace period
Kuniyuki Iwashima <[email protected]>
phonet: Pass net and ifindex to phonet_address_notify().
Kuniyuki Iwashima <[email protected]>
phonet: Pass ifindex to fill_addr().
Dexuan Cui <[email protected]>
Drivers: hv: vmbus: Improve the logic of reserving fb_mmio on Gen2 VMs
Mukesh Ojha <[email protected]>
misc: fastrpc: Fix NULL pointer dereference in rpmsg callback
Abel Vesa <[email protected]>
misc: fastrpc: Add dma_mask to fastrpc_channel_ctx
Thorsten Blum <[email protected]>
hv: utils: handle and propagate errors in kvp_register
Paolo Abeni <[email protected]>
mptcp: fix missing wakeups in edge scenarios
Michael Bommarito <[email protected]>
NFSv4/pNFS: reject zero-length r_addr in nfs4_decode_mp_ds_addr
Dominik Woźniak <[email protected]>
nfsd: check get_user() return when reading princhashlen
Jeff Layton <[email protected]>
nfsd: fix posix_acl leak on SETACL decode failure
Guannan Wang <[email protected]>
NFSD: Fix SECINFO_NO_NAME decode error cleanup
Steffen Persvold <[email protected]>
fbdev: modedb: Fix misaligned fields in the 1920x1080-60 mode
Ian Bridges <[email protected]>
fbdev: Fix fb_new_modelist to prevent null-ptr-deref in fb_videomode_to_var
Wentao Liang <[email protected]>
power: reset: linkstation-poweroff: fix use-after-free in the linkstation_poweroff_init()
Ashutosh Desai <[email protected]>
KVM: SVM: Fix page overflow in sev_dbg_crypt() for ENCRYPT path
Zhang Cen <[email protected]>
ocfs2: reject oversized group bitmap descriptors
Wentao Liang <[email protected]>
fpga: region: fix use-after-free in child_regions_with_firmware()
Qingshuang Fu <[email protected]>
irqchip/imgpdc: Fix resource leak, add missing chained handler cleanup on remove
Wentao Liang <[email protected]>
pNFS: Fix use-after-free in pnfs_update_layout()
Doruk Tan Ozturk <[email protected]>
tipc: fix slab-use-after-free Read in tipc_aead_decrypt_done
Fan Wu <[email protected]>
hdlc_ppp: sync per-proto timers before freeing hdlc state
Michael Bommarito <[email protected]>
exfat: fix potential use-after-free in exfat_find_dir_entry()
Maciej W. Rozycki <[email protected]>
MIPS: DEC: Prevent initial console buffer from landing in XKPHYS
Dawei Feng <[email protected]>
bpf: use kvfree() for replaced sysctl write buffer
Zhang Cen <[email protected]>
f2fs: validate ACL entry sizes in f2fs_acl_from_disk()
Bitterblue Smith <[email protected]>
wifi: rtlwifi: rtl8821ae: Fix C2H bit location in RX descriptor
Jose Ignacio Tornos Martinez <[email protected]>
wifi: ath11k: fix warning when unbinding
Zenm Chen <[email protected]>
wifi: mt76: mt76x2u: Add support for ELECOM WDC-867SU3S
Shaomin Chen <[email protected]>
keys: Pin request_key_auth payload in instantiate paths
Jarkko Sakkinen <[email protected]>
KEYS: fix overflow in keyctl_pkey_params_get_2()
Doruk Tan Ozturk <[email protected]>
mac802154: llsec: add skb_cow_data() before in-place crypto
Herbert Xu <[email protected]>
crypto: af_alg - Set merge to zero early in af_alg_sendmsg
Yuto Ohnuki <[email protected]>
ext4: add bounds check for inline data length in ext4_read_inline_page
Konstantin Komarov <[email protected]>
ntfs3: reject direct userspace writes to reserved $LX* xattrs
Bjoern Doebel <[email protected]>
ring-buffer: Remove ring_buffer_read_prepare_sync()
Sven Eckelmann <[email protected]>
batman-adv: tvlv: avoid race of cifsnotfound handler state
Sven Eckelmann <[email protected]>
batman-adv: tvlv: enforce 2-byte alignment
Sven Eckelmann <[email protected]>
batman-adv: dat: prevent false sharing between VLANs
Sven Eckelmann <[email protected]>
batman-adv: tt: track roam count per VID
Sven Eckelmann <[email protected]>
batman-adv: tt: don't merge change entries with different VIDs
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: handle overlapping packets
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: prevent parallel modifications of last_recv
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: annotate last_recv_time access with READ/WRITE_ONCE
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: restrict number of unacked list entries
Sven Eckelmann <[email protected]>
batman-adv: v: prevent OGM aggregation on disabled hardif
Sven Eckelmann <[email protected]>
batman-adv: frag: avoid underflow of TTL
Sven Eckelmann <[email protected]>
batman-adv: frag: ensure fragment is writable before modifying TTL
Sven Eckelmann <[email protected]>
batman-adv: fix (m|b)cast csum after decrementing TTL
Sven Eckelmann <[email protected]>
batman-adv: ensure bcast is writable before modifying TTL
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: initialize last_recv_time during init
Sven Eckelmann <[email protected]>
batman-adv: prevent ELP transmission interval underflow
Sven Eckelmann <[email protected]>
batman-adv: bla: annotate lasttime access with READ/WRITE_ONCE
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: add only finished tp_vars to lists
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: handle seqno wrap-around for fast recovery detection
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: fix fast recovery precondition
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: avoid divide-by-zero for dec_cwnd
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: avoid window underflow
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: initialize dec_cwnd explicitly
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: initialize dup_acks explicitly
Sven Eckelmann <[email protected]>
batman-adv: tp_meter: keep unacked list in ascending ordered
Yijia Wang <[email protected]>
kselftest/arm64: signal: Skip SVE signal test if not enough VLs supported
Sean Christopherson <[email protected]>
KVM: x86/mmu: Ensure hugepage is in by slot before checking max mapping level
Petr Machata <[email protected]>
Revert "ptp: add testptp mask test"
Petr Machata <[email protected]>
Revert "selftest/ptp: update ptp selftest to exercise the gettimex options"
Miklos Szeredi <[email protected]>
virtiofs: fix UAF on submount umount
Ruslan Valiyev <[email protected]>
media: vidtv: fix NULL pointer dereference in vidtv_mux_push_si
Yi Yang <[email protected]>
vc_screen: fix null-ptr-deref in vcs_notifier() during concurrent vcs_write
André Draszik <[email protected]>
regulator: core: fix locking in regulator_resolve_supply() error path
Jiexun Wang <[email protected]>
af_unix: Reject SIOCATMARK on non-stream sockets
Mathias Nyman <[email protected]>
xhci: fix memory leak regression when freeing xhci vdev devices depth first
Mingyu Wang <[email protected]>
agp/amd64: Fix broken error propagation in agp_amd64_probe()
Weiming Shi <[email protected]>
net: qualcomm: rmnet: fix endpoint use-after-free in rmnet_dellink()
Weiming Shi <[email protected]>
i2c: stub: Reject I2C block transfers with invalid length
Lord Ulf Henrik Holmberg <[email protected]>
RDMA/bnxt_re: zero shared page before exposing to userspace
Jiacheng Shi <[email protected]>
vfio/iommu_type1: replace kfree with kvfree
Antoniu Miclaus <[email protected]>
iio: light: bh1780: fix PM runtime leak on error path
Sven Eckelmann <[email protected]>
batman-adv: tt: prevent TVLV entry number overflow
Sven Eckelmann <[email protected]>
batman-adv: tt: reject oversized local TVLV buffers
Maíra Canal <[email protected]>
drm/v3d: Skip CSD when it has zeroed workgroups
Maíra Canal <[email protected]>
drm/v3d: Store the active job inside the queue's state
Eric Dumazet <[email protected]>
ip6_vti: set netns_immutable on the fallback device.
Harry Wentland <[email protected]>
drm/amd/display: Bound VBIOS record-chain walk loops
Pedro Tammela <[email protected]>
net/sched: act_pedit: free pedit keys on bail from offset check
Rajat Gupta <[email protected]>
net/sched: fix pedit partial COW leading to page cache corruption
Pedro Tammela <[email protected]>
net/sched: act_pedit: rate limit datapath messages
Pedro Tammela <[email protected]>
net/sched: act_pedit: check static offsets a priori
Jann Horn <[email protected]>
fuse: limit FUSE_NOTIFY_RETRIEVE to uptodate folios
-------------
Diffstat:
Documentation/userspace-api/ioctl/ioctl-number.rst | 447 ++++++++++----------- Makefile | 4 +- arch/mips/dec/prom/console.c | 7 +- arch/x86/kvm/mmu/mmu.c | 19 +- arch/x86/kvm/svm/sev.c | 1 + crypto/af_alg.c | 2 + drivers/char/agp/amd64-agp.c | 2 +- drivers/crypto/qat/qat_common/adf_cfg_common.h | 32 -- drivers/crypto/qat/qat_common/adf_cfg_user.h | 38 -- drivers/crypto/qat/qat_common/adf_common_drv.h | 3 - drivers/crypto/qat/qat_common/adf_ctl_drv.c | 421 +------------------ drivers/crypto/qat/qat_common/adf_dev_mgr.c | 70 ---- drivers/fpga/of-fpga-region.c | 3 +- drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 15 +- drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 15 +- .../drm/amd/display/dc/bios/bios_parser_helper.h | 5 + drivers/gpu/drm/v3d/v3d_drv.h | 8 +- drivers/gpu/drm/v3d/v3d_gem.c | 5 +- drivers/gpu/drm/v3d/v3d_irq.c | 24 +- drivers/gpu/drm/v3d/v3d_sched.c | 36 +- drivers/hv/hv_kvp.c | 25 +- drivers/hv/vmbus_drv.c | 56 ++- drivers/i2c/i2c-stub.c | 5 + drivers/iio/light/bh1780.c | 4 +- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 +- drivers/irqchip/irq-imgpdc.c | 6 + drivers/media/test-drivers/vidtv/vidtv_mux.c | 8 +- drivers/misc/fastrpc.c | 7 +- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 8 +- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 1 + drivers/net/wan/hdlc_ppp.c | 15 +- drivers/net/wireless/ath/ath11k/dp.c | 1 + drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 1 + .../net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 2 +- drivers/power/reset/linkstation-poweroff.c | 2 +- drivers/regulator/core.c | 10 +- drivers/tty/vt/vc_screen.c | 2 +- drivers/usb/host/xhci-mem.c | 2 +- drivers/vfio/vfio_iommu_type1.c | 2 +- drivers/video/fbdev/core/fbmem.c | 12 + drivers/video/fbdev/core/modedb.c | 2 +- fs/dlm/lockspace.c | 2 +- fs/exfat/dir.c | 4 +- fs/ext4/inline.c | 8 + fs/f2fs/acl.c | 18 +- fs/fuse/dev.c | 23 +- fs/fuse/file.c | 8 +- fs/ksmbd/smb2pdu.c | 5 + fs/nfs/pnfs.c | 2 +- fs/nfs/pnfs_nfs.c | 4 +- fs/nfsd/nfs2acl.c | 17 +- fs/nfsd/nfs3acl.c | 17 +- fs/nfsd/nfs4recover.c | 3 +- fs/nfsd/nfs4xdr.c | 3 +- fs/ntfs3/xattr.c | 12 + fs/ocfs2/suballoc.c | 22 + include/keys/request_key_auth-type.h | 2 + include/linux/kvm_host.h | 7 +- include/linux/ring_buffer.h | 4 +- include/net/phonet/pn_dev.h | 2 +- include/net/tc_act/tc_pedit.h | 1 - kernel/bpf/cgroup.c | 2 +- kernel/trace/ring_buffer.c | 74 +--- kernel/trace/trace.c | 14 +- kernel/trace/trace_kdb.c | 8 +- net/batman-adv/bat_iv_ogm.c | 11 +- net/batman-adv/bat_v.c | 1 + net/batman-adv/bat_v_ogm.c | 23 +- net/batman-adv/bridge_loop_avoidance.c | 28 +- net/batman-adv/distributed-arp-table.c | 12 +- net/batman-adv/fragmentation.c | 22 +- net/batman-adv/fragmentation.h | 3 +- net/batman-adv/netlink.c | 10 +- net/batman-adv/routing.c | 64 ++- net/batman-adv/tp_meter.c | 115 ++++-- net/batman-adv/translation-table.c | 40 +- net/batman-adv/tvlv.c | 69 +++- net/batman-adv/types.h | 21 +- net/ipv6/ip6_vti.c | 1 + net/mac802154/llsec.c | 14 + net/mptcp/protocol.c | 4 +- net/phonet/pn_dev.c | 12 +- net/phonet/pn_netlink.c | 23 +- net/sched/act_pedit.c | 101 +++-- net/tipc/crypto.c | 9 + net/unix/af_unix.c | 3 + security/keys/internal.h | 2 + security/keys/keyctl.c | 24 +- security/keys/keyctl_pkey.c | 9 +- security/keys/request_key_auth.c | 33 +- .../testcases/fake_sigreturn_sve_change_vl.c | 2 + tools/testing/selftests/ptp/testptp.c | 79 +--- 92 files changed, 1104 insertions(+), 1223 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/95 fuse: limit FUSE_NOTIFY_RETRIEVE to uptodate folios
5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
[ Upstream commit 4e3d1b2c48ca6c55f1e9ca7f8dccc76f120f276c ]
FUSE_NOTIFY_RETRIEVE must be limited to uptodate folios; !uptodate folios can contain uninitialized data.
Since FUSE_NOTIFY_RETRIEVE is intended to only return data that is already in the page cache and not wait for data from the FUSE daemon, treat !uptodate folios as if they weren't present.
This only has security impact on systems that don't enable automatic zero-initialization of all page allocations via CONFIG_INIT_ON_ALLOC_DEFAULT_ON or init_on_alloc=1.
--- fs/fuse/dev.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/fuse/dev.c +4 -0
@@ -1724,6 +1724,10 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode, page =find_get_page (mapping, index);if (!page)break ; +if (!PageUptodate (page)) { +put_page (page); +break ; + } this_num =min_t (unsigned, num,PAGE_SIZE - offset); ap->pages[ap->num_pages] = page;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 2/95 net/sched: act_pedit: check static offsets a priori
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Tammela <[email protected]>
[ Upstream commit e1201bc781c28766720e78a5e099ffa568be4d74 ]
Static key offsets should always be on 32 bit boundaries. Validate them on create/update time for static offsets and move the datapath validation for runtime offsets only.
iproute2 already errors out if a given offset and data size cannot be packed to a 32 bit boundary. This change will make sure users which create/update pedit instances directly via netlink also error out, instead of finding out when packets are traversing.
--- net/sched/act_pedit.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
net/sched/act_pedit.c +14 -6
@@ -250,8 +250,16 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,memcpy (nparms->tcfp_keys, parm->keys, ksize);for (i =0 ; i < nparms->tcfp_nkeys; ++i) { +u32 offmask = nparms->tcfp_keys[i].offmask;u32 cur = nparms->tcfp_keys[i].off; +/* The AT option can be added to static offsets in the datapath */ +if (!offmask && cur %4 ) { +NL_SET_ERR_MSG_MOD (extack,"Offsets must be on 32bit boundaries" ); + ret = -EINVAL ; + goto put_chain; + } +/* sanitize the shift value for any later use */ nparms->tcfp_keys[i].shift = min_t(size_t, BITS_PER_TYPE(int) - 1,
@@ -260,7 +268,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,/* The AT option can read a single byte, we can bound the actual * value with uchar max. */ - cur += (0xff & nparms->tcfp_keys[i].offmask) >> nparms->tcfp_keys[i].shift; + cur += (0xff & offmask) >> nparms->tcfp_keys[i].shift;/* Each key touches 4 bytes starting from the computed offset */ nparms->tcfp_off_max_hint =
@@ -429,12 +437,12 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, sizeof(_d), &_d);if (!d) goto bad; - offset += (*d & tkey->offmask) >> tkey->shift; - } -if (offset %4 ) { -pr_info ("tc action pedit offset must be on 32 bit boundaries\n" ); - goto bad; + offset += (*d & tkey->offmask) >> tkey->shift; +if (offset %4 ) { +pr_info ("tc action pedit offset must be on 32 bit boundaries\n" ); + goto bad; + } }if (!offset_valid (skb, hoffset + offset)) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 3/95 net/sched: act_pedit: rate limit datapath messages
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Tammela <[email protected]>
[ Upstream commit e3c9673e2f6e1b3aa4bb87c570336e10f364c28a ]
Unbounded info messages in the pedit datapath can flood the printk ring buffer quite easily depending on the action created. As these messages are informational, usually printing some, not all, is enough to bring attention to the real issue.
--- net/sched/act_pedit.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
net/sched/act_pedit.c +5 -7
@@ -429,8 +429,8 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a,u8 *d, _d;if (!offset_valid (skb, hoffset + tkey->at)) { -pr_info ("tc action pedit 'at' offset %d out of bounds\n" , - hoffset + tkey->at); +pr_info_ratelimited ("tc action pedit 'at' offset %d out of bounds\n" , + hoffset + tkey->at); goto bad; } d = skb_header_pointer(skb, hoffset + tkey->at,
@@ -440,14 +440,13 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, offset += (*d & tkey->offmask) >> tkey->shift;if (offset %4 ) { -pr_info ("tc action pedit offset must be on 32 bit boundaries\n" ); +pr_info_ratelimited ("tc action pedit offset must be on 32 bit boundaries\n" ); goto bad; } }if (!offset_valid (skb, hoffset + offset)) { -pr_info ("tc action pedit offset %d out of bounds\n" , - hoffset + offset); +pr_info_ratelimited ("tc action pedit offset %d out of bounds\n" , hoffset + offset); goto bad; }
@@ -464,8 +463,7 @@ static int tcf_pedit_act(struct sk_buff *skb, const struct tc_action *a, val = (*ptr + tkey->val) & ~tkey->mask;break ;default : -pr_info ("tc action pedit bad command (%d)\n" , - cmd); +pr_info_ratelimited ("tc action pedit bad command (%d)\n" , cmd); goto bad; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 4/95 net/sched: fix pedit partial COW leading to page cache corruption
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rajat Gupta <[email protected]>
[ Upstream commit 899ee91156e57784090c5565e4f31bd7dbffbc5a ]
tcf_pedit_act() computes the COW range for skb_ensure_writable() once before the key loop using tcfp_off_max_hint, but the hint does not account for the runtime header offset added by typed keys. This can leave part of the write region un-COW'd.
Fix by moving skb_ensure_writable() inside the per-key loop where the actual write offset is known, and add overflow checking on the offset arithmetic. For negative offsets (e.g. Ethernet header edits at ingress), use skb_cow() to COW the headroom instead. Guard offset_valid() against INT_MIN, where negation is undefined.
Conflicts:
include/net/tc_act/tc_pedit.h
--- include/net/tc_act/tc_pedit.h | 1 - net/sched/act_pedit.c | 77 +++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 37 deletions(-)
include/net/tc_act/tc_pedit.h +0 -1
@@ -14,7 +14,6 @@ struct tcf_pedit_key_ex {struct tcf_pedit_parms {struct tc_pedit_key *tcfp_keys;struct tcf_pedit_key_ex *tcfp_keys_ex; -u32 tcfp_off_max_hint;unsigned char tcfp_nkeys;unsigned char tcfp_flags;struct rcu_head rcu;
net/sched/act_pedit.c +41 -36
155 lines not on this page · raw message
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 5/95 net/sched: act_pedit: free pedit keys on bail from offset check
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Tammela <[email protected]>
[ Upstream commit 1b483d9f5805c7e3d628d4995e97f4311fcb82eb ]
Ido Schimmel reports a memleak on a syzkaller instance:
BUG: memory leak
unreferenced object 0xffff88803d45e400 (size 1024):
comm "syz-executor292", pid 563, jiffies 4295025223 (age 51.781s)
hex dump (first 32 bytes):
28 bd 70 00 fb db df 25 02 00 14 1f ff 02 00 02 (.p....%........
00 32 00 00 1f 00 00 00 ac 14 14 3e 08 00 07 00 .2.........>....
backtrace:
[<ffffffff81bd0f2c>] kmemleak_alloc_recursive include/linux/kmemleak.h:42 [inline]
[<ffffffff81bd0f2c>] slab_post_alloc_hook mm/slab.h:772 [inline]
[<ffffffff81bd0f2c>] slab_alloc_node mm/slub.c:3452 [inline]
[<ffffffff81bd0f2c>] __kmem_cache_alloc_node+0x25c/0x320 mm/slub.c:3491
[<ffffffff81a865d9>] __do_kmalloc_node mm/slab_common.c:966 [inline]
[<ffffffff81a865d9>] __kmalloc+0x59/0x1a0 mm/slab_common.c:980
[<ffffffff83aa85c3>] kmalloc include/linux/slab.h:584 [inline]
[<ffffffff83aa85c3>] tcf_pedit_init+0x793/0x1ae0 net/sched/act_pedit.c:245
[<ffffffff83a90623>] tcf_action_init_1+0x453/0x6e0 net/sched/act_api.c:1394
[<ffffffff83a90e58>] tcf_action_init+0x5a8/0x950 net/sched/act_api.c:1459
[<ffffffff83a96258>] tcf_action_add+0x118/0x4e0 net/sched/act_api.c:1985
[<ffffffff83a96997>] tc_ctl_action+0x377/0x490 net/sched/act_api.c:2044
[<ffffffff83920a8d>] rtnetlink_rcv_msg+0x46d/0xd70 net/core/rtnetlink.c:6395
[<ffffffff83b24305>] netlink_rcv_skb+0x185/0x490 net/netlink/af_netlink.c:2575
[<ffffffff83901806>] rtnetlink_rcv+0x26/0x30 net/core/rtnetlink.c:6413
[<ffffffff83b21cae>] netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
[<ffffffff83b21cae>] netlink_unicast+0x5be/0x8a0 net/netlink/af_netlink.c:1365
[<ffffffff83b2293f>] netlink_sendmsg+0x9af/0xed0 net/netlink/af_netlink.c:1942
[<ffffffff8380c39f>] sock_sendmsg_nosec net/socket.c:724 [inline]
[<ffffffff8380c39f>] sock_sendmsg net/socket.c:747 [inline]
[<ffffffff8380c39f>] ____sys_sendmsg+0x3ef/0xaa0 net/socket.c:2503
[<ffffffff838156d2>] ___sys_sendmsg+0x122/0x1c0 net/socket.c:2557
[<ffffffff8381594f>] __sys_sendmsg+0x11f/0x200 net/socket.c:2586
[<ffffffff83815ab0>] __do_sys_sendmsg net/socket.c:2595 [inline]
[<ffffffff83815ab0>] __se_sys_sendmsg net/socket.c:2593 [inline]
[<ffffffff83815ab0>] __x64_sys_sendmsg+0x80/0xc0 net/socket.c:2593The recently added static offset check missed a free to the key buffer when bailing out on error.
--- net/sched/act_pedit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/sched/act_pedit.c +3 -1
@@ -258,7 +258,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,if (!offmask && cur %4 ) {NL_SET_ERR_MSG_MOD (extack,"Offsets must be on 32bit boundaries" ); ret = -EINVAL ; - goto put_chain; + goto out_free_keys; }/* sanitize the shift value for any later use */
@@ -283,6 +283,8 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,return ret; +out_free_keys: +kfree (nparms->tcfp_keys); put_chain:if (goto_ch)tcf_chain_put_by_act (goto_ch);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 6/95 drm/amd/display: Bound VBIOS record-chain walk loops
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harry Wentland <[email protected]>
[ Upstream commit ff287df16a1a58aca78b08d1f3ee09fc44da0351 ]
[Why & How]
All record-chain walk loops in bios_parser.c and bios_parser2.c use for(;;) and only terminate on a 0xFF record_type sentinel or zero record_size. A malformed VBIOS image missing the terminator record causes unbounded iteration at probe time, potentially hundreds of thousands of iterations with record_size=1. In the final iterations near the BIOS image boundary, struct casts beyond the 2-byte header validated by GET_IMAGE can also read out of bounds.
Cap all 14 record-chain walk loops to BIOS_MAX_NUM_RECORD (256) iterations. The atombios.h defines up to 22 distinct record types and atomfirmware.h has 13. Assuming an average of less than 10 records per type (which is reasonable since most are connector- based) 256 is a generous upper bound.
--- drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 15 ++++++++++----- .../gpu/drm/amd/display/dc/bios/bios_parser2.c | 15 ++++++++++----- .../drm/amd/display/dc/bios/bios_parser_helper.h | 5 +++++ 3 files changed, 25 insertions(+), 10 deletions(-)
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +10 -5
@@ -223,6 +223,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,ATOM_COMMON_RECORD_HEADER *header;ATOM_I2C_RECORD *record;struct bios_parser *bp =BP_FROM_DCB (dcb); +int i;if (!info)return BP_RESULT_BADINPUT ;
@@ -235,7 +236,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, offset =le16_to_cpu (object->usRecordOffset) + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header =GET_IMAGE (ATOM_COMMON_RECORD_HEADER , offset);if (!header)
@@ -294,11 +295,12 @@ static enum bp_result bios_parser_get_device_tag_record( {ATOM_COMMON_RECORD_HEADER *header;uint32_t offset; +int i; offset =le16_to_cpu (object->usRecordOffset) + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header =GET_IMAGE (ATOM_COMMON_RECORD_HEADER , offset);if (!header)
@@ -870,6 +872,7 @@ static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp, {ATOM_COMMON_RECORD_HEADER *header;uint32_t offset; +int i;if (!object) {BREAK_TO_DEBUGGER ();/* Invalid object */
@@ -879,7 +882,7 @@ static ATOM_HPD_INT_RECORD *get_hpd_record(struct bios_parser *bp, offset =le16_to_cpu (object->usRecordOffset) + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header =GET_IMAGE (ATOM_COMMON_RECORD_HEADER , offset);if (!header)
@@ -1572,6 +1575,7 @@ static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record( {ATOM_COMMON_RECORD_HEADER *header;uint32_t offset; +int i;if (!object) {BREAK_TO_DEBUGGER ();/* Invalid object */
@@ -1581,7 +1585,7 @@ static ATOM_ENCODER_CAP_RECORD_V2 *get_encoder_cap_record( offset =le16_to_cpu (object->usRecordOffset) + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header =GET_IMAGE (ATOM_COMMON_RECORD_HEADER , offset);if (!header)
@@ -2665,6 +2669,7 @@ static enum bp_result update_slot_layout_info( unsigned int record_offset) {unsigned int j; +unsigned int n;struct bios_parser *bp;ATOM_BRACKET_LAYOUT_RECORD *record;ATOM_COMMON_RECORD_HEADER *record_header;
@@ -2674,7 +2679,7 @@ static enum bp_result update_slot_layout_info( record =NULL ; record_header =NULL ; -for (;;) { +for (n =0 ; n <BIOS_MAX_NUM_RECORD ; n++) { record_header = (ATOM_COMMON_RECORD_HEADER *)GET_IMAGE (ATOM_COMMON_RECORD_HEADER , record_offset);
drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +10 -5
@@ -296,6 +296,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb,struct atom_i2c_record *record;struct atom_i2c_record dummy_record = {0 };struct bios_parser *bp =BP_FROM_DCB (dcb); +int i;if (!info)return BP_RESULT_BADINPUT ;
@@ -316,7 +317,7 @@ static enum bp_result bios_parser_get_i2c_info(struct dc_bios *dcb, offset = object->disp_recordoffset + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header = GET_IMAGE(struct atom_common_record_header, offset);if (!header)
@@ -446,6 +447,7 @@ static struct atom_hpd_int_record *get_hpd_record( {struct atom_common_record_header *header;uint32_t offset; +int i;if (!object) {BREAK_TO_DEBUGGER ();/* Invalid object */
@@ -455,7 +457,7 @@ static struct atom_hpd_int_record *get_hpd_record( offset =le16_to_cpu (object->disp_recordoffset) + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header = GET_IMAGE(struct atom_common_record_header, offset);if (!header)
@@ -1614,6 +1616,7 @@ static struct atom_encoder_caps_record *get_encoder_cap_record( {struct atom_common_record_header *header;uint32_t offset; +int i;if (!object) {BREAK_TO_DEBUGGER ();/* Invalid object */
@@ -1622,7 +1625,7 @@ static struct atom_encoder_caps_record *get_encoder_cap_record( offset = object->encoder_recordoffset + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header = GET_IMAGE(struct atom_common_record_header, offset);if (!header)
@@ -1651,6 +1654,7 @@ static struct atom_disp_connector_caps_record *get_disp_connector_caps_record( {struct atom_common_record_header *header;uint32_t offset; +int i;if (!object) {BREAK_TO_DEBUGGER ();/* Invalid object */
@@ -1659,7 +1663,7 @@ static struct atom_disp_connector_caps_record *get_disp_connector_caps_record( offset = object->disp_recordoffset + bp->object_info_tbl_offset; -for (;;) { +for (i =0 ; i <BIOS_MAX_NUM_RECORD ; i++) { header = GET_IMAGE(struct atom_common_record_header, offset);if (!header)
@@ -2420,6 +2424,7 @@ static enum bp_result update_slot_layout_info( {unsigned int record_offset;unsigned int j; +unsigned int n;struct atom_display_object_path_v2 *object;struct atom_bracket_layout_record *record;struct atom_common_record_header *record_header;
@@ -2441,7 +2446,7 @@ static enum bp_result update_slot_layout_info( (object->disp_recordoffset) + (unsigned int )(bp->object_info_tbl_offset); -for (;;) { +for (n =0 ; n <BIOS_MAX_NUM_RECORD ; n++) { record_header = (struct atom_common_record_header *) GET_IMAGE(struct atom_common_record_header,
drivers/gpu/drm/amd/display/dc/bios/bios_parser_helper.h +5 -0
@@ -38,4 +38,9 @@ uint32_t bios_get_vga_enabled_displays(struct dc_bios *bios);#define GET_IMAGE (type, offset) ((type *) bios_get_image(&bp->base, offset, sizeof(type))) +/* Upper bound on the number of records in a VBIOS record chain. Prevents +* unbounded looping if the VBIOS image is malformed and lacks a terminator. +*/ +#define BIOS_MAX_NUM_RECORD 256 +#endif
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 7/95 ip6_vti: set netns_immutable on the fallback device.
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit d289d5307762d1838aaece22c6b6fcad9e8865f9 ]
john1988 and Noam Rathaus reported that vti6_init_net() does not set the netns_immutable flag on the per-netns fallback tunnel device (ip6_vti0).
Other similar tunnel drivers (like ip6_tunnel, sit, ip6_gre, and ip_tunnel) correctly set this flag during their fallback device initialization to prevent them from being moved to another network namespace.
[Salvatore Bonaccorso: Backport for version without 0c493da86374 ("net:
rename netns_local to netns_immutable") in v6.15-rc1 and without 05c1280a2bcf ("netdev_features: convert NETIF_F_NETNS_LOCAL to dev->netns_local") in v6.12-rc1 and use NETIF_F_NETNS_LOCAL device feature.]
--- net/ipv6/ip6_vti.c | 1 + 1 file changed, 1 insertion(+)
net/ipv6/ip6_vti.c +1 -0
@@ -1167,6 +1167,7 @@ static int __net_init vti6_init_net(struct net *net) goto err_alloc_dev;dev_net_set (ip6n->fb_tnl_dev, net); ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops; + ip6n->fb_tnl_dev->features |=NETIF_F_NETNS_LOCAL ; err =vti6_fb_tnl_dev_init (ip6n->fb_tnl_dev);if (err <0 )
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 8/95 drm/v3d: Store the active job inside the queues state
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <[email protected]>
[ Upstream commit 0d3768826d38c0ac740f8b45cd13346630535f2b ]
Instead of storing the queue's active job in four different variables, store the active job inside the queue's state. This way, it's possible to access all active jobs using an index based in enum v3d_queue.
Stable-dep-of: 7f93fad5ea0a ("drm/v3d: Skip CSD when it has zeroed workgroups")
--- drivers/gpu/drm/v3d/v3d_drv.h | 8 +++----- drivers/gpu/drm/v3d/v3d_gem.c | 5 +++-- drivers/gpu/drm/v3d/v3d_irq.c | 24 ++++++++++++++---------- drivers/gpu/drm/v3d/v3d_sched.c | 26 ++++++++++++++++++-------- 4 files changed, 38 insertions(+), 25 deletions(-)
drivers/gpu/drm/v3d/v3d_drv.h +3 -5
@@ -35,6 +35,9 @@ struct v3d_queue_state {u64 fence_context;u64 emit_seqno; + +/* Currently active job for this queue */ +struct v3d_job *active_job; };/* Performance monitor object. The perform lifetime is controlled by userspace
@@ -119,11 +122,6 @@ struct v3d_dev {struct work_struct overflow_mem_work; -struct v3d_bin_job *bin_job; -struct v3d_render_job *render_job; -struct v3d_tfu_job *tfu_job; -struct v3d_csd_job *csd_job; -struct v3d_queue_state queue[V3D_MAX_QUEUES ];/* Spinlock used to synchronize the overflow memory
drivers/gpu/drm/v3d/v3d_gem.c +3 -2
@@ -950,14 +950,15 @@ void v3d_gem_destroy(struct drm_device *dev) {struct v3d_dev *v3d =to_v3d_dev (dev); +enum v3d_queue q;v3d_sched_fini (v3d);/* Waiting for jobs to finish would need to be done before * unregistering V3D. */ -WARN_ON (v3d->bin_job); -WARN_ON (v3d->render_job); +for (q =0 ; q <V3D_MAX_QUEUES ; q++) +WARN_ON (v3d->queue[q].active_job);drm_mm_takedown (&v3d->mm);
drivers/gpu/drm/v3d/v3d_irq.c +14 -10
@@ -40,6 +40,8 @@ v3d_overflow_mem_work(struct work_struct *work) container_of(work, struct v3d_dev, overflow_mem_work);struct drm_device *dev = &v3d->drm;struct v3d_bo *bo =v3d_bo_create (dev,NULL /* XXX: GMP */ ,256 *1024 ); +struct v3d_queue_state *queue = &v3d->queue[V3D_BIN ]; +struct v3d_bin_job *bin_job;struct drm_gem_object *obj;unsigned long irqflags;
@@ -59,13 +61,15 @@ v3d_overflow_mem_work(struct work_struct *work)* some binner pool anyway. */ spin_lock_irqsave (&v3d->job_lock, irqflags); -if (!v3d->bin_job) { + bin_job = (struct v3d_bin_job *)queue->active_job; + +if (!bin_job) {spin_unlock_irqrestore (&v3d->job_lock, irqflags); goto out; }drm_gem_object_get (obj); -list_add_tail (&bo->unref_head, &v3d->bin_job->render->unref_list); +list_add_tail (&bo->unref_head, &bin_job->render->unref_list);spin_unlock_irqrestore (&v3d->job_lock, irqflags);V3D_CORE_WRITE (0 ,V3D_PTB_BPOA , bo->node.start <<PAGE_SHIFT );
@@ -99,11 +103,11 @@ v3d_irq(int irq, void *arg)if (intsts &V3D_INT_FLDONE ) {struct v3d_fence *fence = -to_v3d_fence (v3d->bin_job->base.irq_fence); +to_v3d_fence (v3d->queue[V3D_BIN ].active_job->irq_fence);trace_v3d_bcl_irq (&v3d->drm, fence->seqno); - v3d->bin_job =NULL ; + v3d->queue[V3D_BIN ].active_job =NULL ;dma_fence_signal (&fence->base); status =IRQ_HANDLED ;
@@ -111,11 +115,11 @@ v3d_irq(int irq, void *arg)if (intsts &V3D_INT_FRDONE ) {struct v3d_fence *fence = -to_v3d_fence (v3d->render_job->base.irq_fence); +to_v3d_fence (v3d->queue[V3D_RENDER ].active_job->irq_fence);trace_v3d_rcl_irq (&v3d->drm, fence->seqno); - v3d->render_job =NULL ; + v3d->queue[V3D_RENDER ].active_job =NULL ;dma_fence_signal (&fence->base); status =IRQ_HANDLED ;
@@ -123,11 +127,11 @@ v3d_irq(int irq, void *arg)if (intsts &V3D_INT_CSDDONE ) {struct v3d_fence *fence = -to_v3d_fence (v3d->csd_job->base.irq_fence); +to_v3d_fence (v3d->queue[V3D_CSD ].active_job->irq_fence);trace_v3d_csd_irq (&v3d->drm, fence->seqno); - v3d->csd_job =NULL ; + v3d->queue[V3D_CSD ].active_job =NULL ;dma_fence_signal (&fence->base); status =IRQ_HANDLED ;
@@ -162,11 +166,11 @@ v3d_hub_irq(int irq, void *arg)if (intsts &V3D_HUB_INT_TFUC ) {struct v3d_fence *fence = -to_v3d_fence (v3d->tfu_job->base.irq_fence); +to_v3d_fence (v3d->queue[V3D_TFU ].active_job->irq_fence);trace_v3d_tfu_irq (&v3d->drm, fence->seqno); - v3d->tfu_job =NULL ; + v3d->queue[V3D_TFU ].active_job =NULL ;dma_fence_signal (&fence->base); status =IRQ_HANDLED ;
drivers/gpu/drm/v3d/v3d_sched.c +18 -8
@@ -103,14 +103,18 @@ static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job)struct dma_fence *fence;unsigned long irqflags; -if (unlikely (job->base.base.s_fence->finished.error)) +if (unlikely (job->base.base.s_fence->finished.error)) { +spin_lock_irqsave (&v3d->job_lock, irqflags); + v3d->queue[V3D_BIN ].active_job =NULL ; +spin_unlock_irqrestore (&v3d->job_lock, irqflags);return NULL ; + }/* Lock required around bin_job update vs * v3d_overflow_mem_work(). */ spin_lock_irqsave (&v3d->job_lock, irqflags); - v3d->bin_job = job; + v3d->queue[V3D_BIN ].active_job = &job->base;/* Clear out the overflow allocation, so we don't * reuse the overflow attached to a previous job. */
@@ -157,10 +161,12 @@ static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job)struct drm_device *dev = &v3d->drm;struct dma_fence *fence; -if (unlikely (job->base.base.s_fence->finished.error)) +if (unlikely (job->base.base.s_fence->finished.error)) { + v3d->queue[V3D_RENDER ].active_job =NULL ;return NULL ; + } - v3d->render_job = job; + v3d->queue[V3D_RENDER ].active_job = &job->base;/* Can we avoid this flush? We need to be careful of * scheduling, though -- imagine job0 rendering to texture and
@@ -202,10 +208,12 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job)struct drm_device *dev = &v3d->drm;struct dma_fence *fence; -if (unlikely (job->base.base.s_fence->finished.error)) +if (unlikely (job->base.base.s_fence->finished.error)) { + v3d->queue[V3D_TFU ].active_job =NULL ;return NULL ; + } - v3d->tfu_job = job; + v3d->queue[V3D_TFU ].active_job = &job->base; fence =v3d_fence_create (v3d,V3D_TFU );if (IS_ERR (fence))
@@ -244,10 +252,12 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)struct dma_fence *fence;int i; -if (unlikely (job->base.base.s_fence->finished.error)) +if (unlikely (job->base.base.s_fence->finished.error)) { + v3d->queue[V3D_CSD ].active_job =NULL ;return NULL ; + } - v3d->csd_job = job; + v3d->queue[V3D_CSD ].active_job = &job->base;v3d_invalidate_caches (v3d);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 9/95 drm/v3d: Skip CSD when it has zeroed workgroups
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <[email protected]>
[ Upstream commit 7f93fad5ea0affc9e1505dd0f7596c0fdb496213 ]
A compute shader dispatch encodes its workgroup counts in the CFG0..CFG2 registers. Kicking off a dispatch with a zero count in any of the three dimensions is invalid. First, the hardware will process 0 as 65536, while the user-space driver exposes a maximum of 65535. Over that, a submission with a zeroed workgroup dimension should be a no-op.
These zeroed counts can reach the dispatch path through an indirect CSD job, whose workgroup counts are only known once the indirect buffer is read and may legitimately be zero, but such scenario should only result in a no-op.
Overwrite the indirect CSD job workgroup counts with the indirect BO ones, even if they are zeroed, and don't submit the job to the hardware when any of the workgroup counts is zero, so the job completes immediately instead of running the shader.
--- drivers/gpu/drm/v3d/v3d_sched.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/gpu/drm/v3d/v3d_sched.c +10 -0
@@ -257,6 +257,16 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)return NULL ; } +/* The HW interprets a workgroup size of 0 as 65536; however, the +* user-space driver exposes a maximum of 65535. Therefore, a 0 in +* any dimension means that we have no workgroups and the compute +* shader should not be dispatched. +*/ +if (!V3D_GET_FIELD (job->args.cfg[0 ],V3D_CSD_QUEUED_CFG0_NUM_WGS_X ) || + !V3D_GET_FIELD (job->args.cfg[1 ],V3D_CSD_QUEUED_CFG1_NUM_WGS_Y ) || + !V3D_GET_FIELD (job->args.cfg[2 ],V3D_CSD_QUEUED_CFG2_NUM_WGS_Z )) +return NULL ; + v3d->queue[V3D_CSD ].active_job = &job->base;v3d_invalidate_caches (v3d);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 10/95 batman-adv: tt: reject oversized local TVLV buffers
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 1e9fab756f8395096d5bba7be0c373c4c8f5d165 upstream.
The commit 3a359bf5c61d ("batman-adv: reject oversized global TT response buffers") added a check to ensure that a global return buffer size can be stored in an u16. The same buffer handling also exists for the local data buffer but was not touched.
A similar check should be also be in place for the local TVLV buffer. It doesn't have the similar attack surface because it is only generated from locally discovered MAC addresses but the dynamic nature could still cause temporarily to large buffers.
--- net/batman-adv/translation-table.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
net/batman-adv/translation-table.c +5 -3
@@ -939,12 +939,12 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv, {struct batadv_tvlv_tt_vlan_data *tt_vlan;struct batadv_softif_vlan *vlan; +size_t change_offset;u16 num_vlan =0 ;u16 vlan_entries =0 ;u16 total_entries =0 ;u16 tvlv_len;u8 *tt_change_ptr; -int change_offset;spin_lock_bh (&bat_priv->softif_vlan_list_lock);hlist_for_each_entry (vlan, &bat_priv->softif_vlan_list, list) {
@@ -960,8 +960,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,if (*tt_len <0 ) *tt_len =batadv_tt_len (total_entries); - tvlv_len = *tt_len; - tvlv_len += change_offset; +if (check_add_overflow (*tt_len, change_offset, &tvlv_len)) { + tvlv_len =0 ; + goto out; + } *tt_data =kmalloc (tvlv_len,GFP_ATOMIC );if (!*tt_data) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 11/95 batman-adv: tt: prevent TVLV entry number overflow
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 99d9958fa10fb684b2a8e2c48a8d704122721420 upstream.
The helpers to prepare the buffers for the local and global TT based replies are trying to sum up all TT entries which can be found for each VLAN. In theory, this sum can be too big for an u16 and therefore overflow. A too small buffer would then be allocated for the TVLV.
The too small buffer will be handled gracefully by batadv_tt_tvlv_generate() and is not causing a buffer overflow - just a truncated reply. But this overflow shouldn't have happened in the first and the too small buffer should never have been allocated when an overflow was detected.
--- net/batman-adv/translation-table.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
net/batman-adv/translation-table.c +17 -3
@@ -850,11 +850,18 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,u16 total_entries =0 ;u8 *tt_change_ptr;int vlan_entries; +u16 sum_entries;spin_lock_bh (&orig_node->vlan_list_lock);hlist_for_each_entry (vlan, &orig_node->vlan_list, list) { vlan_entries =atomic_read (&vlan->tt.num_entries); - total_entries += vlan_entries; + +if (check_add_overflow (vlan_entries, total_entries, &sum_entries)) { + *tt_len =0 ; + goto out; + } + + total_entries = sum_entries; num_vlan++; }
@@ -941,15 +948,22 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,struct batadv_softif_vlan *vlan;size_t change_offset;u16 num_vlan =0 ; -u16 vlan_entries =0 ;u16 total_entries =0 ;u16 tvlv_len;u8 *tt_change_ptr; +int vlan_entries; +u16 sum_entries;spin_lock_bh (&bat_priv->softif_vlan_list_lock);hlist_for_each_entry (vlan, &bat_priv->softif_vlan_list, list) { vlan_entries =atomic_read (&vlan->tt.num_entries); - total_entries += vlan_entries; + +if (check_add_overflow (vlan_entries, total_entries, &sum_entries)) { + tvlv_len =0 ; + goto out; + } + + total_entries = sum_entries; num_vlan++; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 12/95 iio: light: bh1780: fix PM runtime leak on error path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
commit dd72e6c3cdea05cad24e99710939086f7a113fb5 upstream.
Move pm_runtime_put_autosuspend() before the error check to ensure the PM runtime reference count is always decremented after pm_runtime_get_sync(), regardless of whether the read operation succeeds or fails.
--- drivers/iio/light/bh1780.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/light/bh1780.c +2 -2
@@ -109,10 +109,10 @@ static int bh1780_read_raw(struct iio_dev *indio_dev,case IIO_LIGHT :pm_runtime_get_sync (&bh1780->client->dev); value =bh1780_read_word (bh1780,BH1780_REG_DLOW ); -if (value <0 ) -return value;pm_runtime_mark_last_busy (&bh1780->client->dev);pm_runtime_put_autosuspend (&bh1780->client->dev); +if (value <0 ) +return value; *val = value;return IIO_VAL_INT ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 13/95 vfio/iommu_type1: replace kfree with kvfree
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiacheng Shi <[email protected]>
[ Upstream commit 2bed2ced40c97b8540ff38df0149e8ecb2bf4c65 ]
Variables allocated by kvzalloc should not be freed by kfree. Because they may be allocated by vmalloc.
So we replace kfree with kvfree here.
--- drivers/vfio/vfio_iommu_type1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/vfio/vfio_iommu_type1.c +1 -1
@@ -262,7 +262,7 @@ static int vfio_dma_bitmap_alloc(struct vfio_dma *dma, size_t pgsize)static void vfio_dma_bitmap_free (struct vfio_dma *dma) { -kfree (dma->bitmap); +kvfree (dma->bitmap); dma->bitmap =NULL ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 14/95 RDMA/bnxt_re: zero shared page before exposing to userspace
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lord Ulf Henrik Holmberg <[email protected]>
commit f6b079629becfa977f9c51fe53ad2e6dcc55ef44 upstream.
bnxt_re_alloc_ucontext() allocates uctx->shpg via __get_free_page(GFP_KERNEL). The buddy allocator does not zero pages without __GFP_ZERO, so the page contains stale kernel data from whatever object most recently freed it.
The page is then mapped into userspace via vm_insert_page() under BNXT_RE_MMAP_SH_PAGE in bnxt_re_mmap(). The driver only ever writes 4 bytes (a u32 AVID) at offset BNXT_RE_AVID_OFFT (0x10) inside bnxt_re_create_ah(); the remaining 4092 bytes of the page are exposed to userspace unsanitised, leaking kernel memory contents.
Any user with access to /dev/infiniband/uverbsX on a host with a bnxt_re device (typically rdma group membership) can read this data via a single mmap() at pgoff 0 after IB_USER_VERBS_CMD_GET_CONTEXT.
Other shared pages in the same file already use get_zeroed_page() correctly:
drivers/infiniband/hw/bnxt_re/ib_verbs.c
srq->uctx_srq_page = (void *)get_zeroed_page(GFP_KERNEL);
cq->uctx_cq_page = (void *)get_zeroed_page(GFP_KERNEL);uctx->shpg is the only outlier. Bring it in line with the existing convention by switching to get_zeroed_page().
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +1 -1
@@ -3864,7 +3864,7 @@ int bnxt_re_alloc_ucontext(struct ib_uco uctx->rdev = rdev; - uctx->shpg = (void *)__get_free_page (GFP_KERNEL ); + uctx->shpg = (void *)get_zeroed_page (GFP_KERNEL );if (!uctx->shpg) { rc = -ENOMEM ; goto fail;
Greg Kroah-Hartman
maintainerPATCH 15/95 i2c: stub: Reject I2C block transfers with invalid length
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
commit 6036b5067a8199ba7a2dc7b377d4b9dd276d5f9e upstream.
The I2C_SMBUS_I2C_BLOCK_DATA case in stub_xfer() uses data->block[0] as the transfer length. The existing check only clamps it to avoid overrunning the chip->words[256] register array, but does not validate it against I2C_SMBUS_BLOCK_MAX (32), which is the limit of the union i2c_smbus_data.block buffer (34 bytes total). The driver is a development/test tool (CONFIG_I2C_STUB=m, not built by default) that must be loaded with a chip_addr= parameter.
A local user with access to /dev/i2c-* can issue an I2C_SMBUS ioctl with I2C_SMBUS_I2C_BLOCK_DATA and data->block[0] > 32, causing stub_xfer() to read or write past the end of the union i2c_smbus_data.block buffer:
BUG: KASAN: stack-out-of-bounds in stub_xfer (drivers/i2c/i2c-stub.c:223) Read of size 1 at addr ffff88800abcfd92 by task exploit/81 Call Trace: <TASK> stub_xfer (drivers/i2c/i2c-stub.c:223) __i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:593) i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:536) i2cdev_ioctl_smbus (drivers/i2c/i2c-dev.c:391) i2cdev_ioctl (drivers/i2c/i2c-dev.c:478) __x64_sys_ioctl (fs/ioctl.c:583) do_syscall_64 (arch/x86/entry/syscall_64.c:94) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) </TASK>
The bug exists because i2c-stub implements .smbus_xfer directly, bypassing the I2C_SMBUS_BLOCK_MAX validation in i2c_smbus_xfer_emulated(). The I2C_SMBUS_BLOCK_DATA case in the same function correctly validates against I2C_SMBUS_BLOCK_MAX, but the I2C_SMBUS_I2C_BLOCK_DATA case does not.
Fix by rejecting transfers with data->block[0] == 0 or data->block[0] > I2C_SMBUS_BLOCK_MAX with -EINVAL, consistent with both the I2C_SMBUS_BLOCK_DATA case in the same function and the I2C_SMBUS_I2C_BLOCK_DATA validation in i2c_smbus_xfer_emulated().
--- drivers/i2c/i2c-stub.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/i2c/i2c-stub.c +5 -0
@@ -214,6 +214,11 @@ static s32 stub_xfer(struct i2c_adapter* We ignore banks here, because banked chips don't use I2C * block transfers */ +if (data->block[0 ] ==0 || + data->block[0 ] >I2C_SMBUS_BLOCK_MAX ) { + ret = -EINVAL ; +break ; + }if (data->block[0 ] >256 - command)/* Avoid overrun */ data->block[0 ] =256 - command; len = data->block[0 ];
Greg Kroah-Hartman
maintainerPATCH 16/95 net: qualcomm: rmnet: fix endpoint use-after-free in rmnet_dellink()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <[email protected]>
commit d00c953a8f69921f484b629801766da68f27f658 upstream.
rmnet_dellink() removes the endpoint from the hash table with hlist_del_init_rcu() and then immediately frees it with kfree(). However, RCU readers on the receive path (rmnet_rx_handler -> __rmnet_map_ingress_handler) may still hold a reference to the endpoint and dereference ep->egress_dev after the memory has been freed. The endpoint is a kmalloc-32 object, and the stale read at offset 8 corresponds to the egress_dev pointer.
BUG: unable to handle page fault for address: ffffffffde942eef Oops: 0002 [#1] SMP NOPTI CPU: 1 UID: 0 PID: 137 Comm: poc_write Not tainted 7.0.0+ #4 PREEMPTLAZY RIP: 0010:rmnet_vnd_rx_fixup (rmnet_vnd.c:27) Call Trace: <TASK> __rmnet_map_ingress_handler (rmnet_handlers.c:48 rmnet_handlers.c:101) rmnet_rx_handler (rmnet_handlers.c:129 rmnet_handlers.c:235) __netif_receive_skb_core.constprop.0 (net/core/dev.c:6096) __netif_receive_skb_one_core (net/core/dev.c:6208) netif_receive_skb (net/core/dev.c:6467) tun_get_user (drivers/net/tun.c:1955) tun_chr_write_iter (drivers/net/tun.c:2003) vfs_write (fs/read_write.c:688) ksys_write (fs/read_write.c:740) </TASK>
Add an rcu_head field to struct rmnet_endpoint and replace kfree() with kfree_rcu() so the endpoint memory remains valid through the RCU grace period. Also remove the rmnet_vnd_dellink() call and inline only the nr_rmnet_devs decrement, since rmnet_vnd_dellink() would set ep->egress_dev to NULL during the grace period, creating a data race with lockless readers.
--- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 8 ++++---- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +4 -4
@@ -205,8 +205,8 @@ static void rmnet_dellink(struct net_dev ep =rmnet_get_endpoint (real_port, mux_id);if (ep) {hlist_del_init_rcu (&ep->hlnode); -rmnet_vnd_dellink (mux_id, real_port, ep); -kfree (ep); + real_port->nr_rmnet_devs--; +kfree_rcu (ep, rcu); }netdev_upper_dev_unlink (real_dev, dev);
@@ -230,9 +230,9 @@ static void rmnet_force_unassociate_devihash_for_each_safe (port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {unregister_netdevice_queue (ep->egress_dev, &list);netdev_upper_dev_unlink (real_dev, ep->egress_dev); -rmnet_vnd_dellink (ep->mux_id, port, ep);hlist_del_init_rcu (&ep->hlnode); -kfree (ep); + port->nr_rmnet_devs--; +kfree_rcu (ep, rcu); }rmnet_unregister_real_device (real_dev);unregister_netdevice_many (&list);
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +1 -0
@@ -17,6 +17,7 @@ struct rmnet_endpoint {u8 mux_id;struct net_device *egress_dev;struct hlist_node hlnode; +struct rcu_head rcu; };/* One instance of this structure is instantiated for each real_dev associated
Greg Kroah-Hartman
maintainerPATCH 17/95 agp/amd64: Fix broken error propagation in agp_amd64_probe()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingyu Wang <[email protected]>
commit b08472db93b1ccff84a7adec5779d47f0e9d3a30 upstream.
A NULL pointer dereference was observed in the AMD64 AGP driver when running in a virtualized environment (e.g. qemu/kvm) without a physical AMD northbridge. The crash occurs in amd64_fetch_size() when attempting to dereference the pointer returned by node_to_amd_nb(0).
The root cause of this crash is broken error propagation in agp_amd64_probe(): When no AMD northbridges are found, cache_nbs() correctly returns -ENODEV. However, the probe function erroneously checks the return value against exactly -1, rather than < 0.
As a result, the hardware absence error is masked, allowing the driver to improperly proceed with initialization. It eventually calls agp_add_bridge(), which invokes amd64_fetch_size(). Since the hardware does not exist, node_to_amd_nb(0) returns NULL, leading to a General Protection Fault (GPF) when accessing its ->misc member.
Fix the issue by correcting the error check in agp_amd64_probe() to abort properly when cache_nbs() returns any negative error code. This prevents the driver from erroneously proceeding without hardware, thereby avoiding the subsequent NULL pointer dereference at its source.
--- drivers/char/agp/amd64-agp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/char/agp/amd64-agp.c +1 -1
@@ -546,7 +546,7 @@ static int agp_amd64_probe(struct pci_de/* Fill in the mode register */ pci_read_config_dword (pdev, bridge->capndx+PCI_AGP_STATUS , &bridge->mode); -if (cache_nbs (pdev, cap_ptr) ==-1 ) { +if (cache_nbs (pdev, cap_ptr) <0 ) {agp_put_bridge (bridge);return -ENODEV ; }
Greg Kroah-Hartman
maintainerPATCH 18/95 xhci: fix memory leak regression when freeing xhci vdev devices depth first
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman <[email protected]>
commit edcbe06453ddfde21f6aa763f7cab655f26133cc upstream
Suspend-resume cycle test revealed a memory leak in 6.17-rc3
Turns out the slot_id race fix changes accidentally ends up calling xhci_free_virt_device() with an incorrect vdev parameter. The vdev variable was reused for temporary purposes right before calling xhci_free_virt_device().
Fix this by passing the correct vdev parameter.
The slot_id race fix that caused this regression was targeted for stable, so this needs to be applied there as well.
--- drivers/usb/host/xhci-mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-mem.c +1 -1
@@ -961,7 +961,7 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i out:/* we are now at a leaf device */ xhci_debugfs_remove_slot (xhci, slot_id); -xhci_free_virt_device (xhci, vdev, slot_id); +xhci_free_virt_device (xhci, xhci->devs[slot_id], slot_id); } int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 19/95 af_unix: Reject SIOCATMARK on non-stream sockets
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiexun Wang <[email protected]>
commit d119775f2bad827edc28071c061fdd4a91f889a5 upstream.
SIOCATMARK reports whether the receive queue is at the urgent mark for MSG_OOB.
In AF_UNIX, MSG_OOB is supported only for SOCK_STREAM sockets. SOCK_DGRAM and SOCK_SEQPACKET reject MSG_OOB in sendmsg() and recvmsg(), so they should not support SIOCATMARK either.
Return -EOPNOTSUPP for non-stream sockets before checking the receive queue.
--- net/unix/af_unix.c | 3 +++ 1 file changed, 3 insertions(+)
net/unix/af_unix.c +3 -0
@@ -3040,6 +3040,9 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)struct sk_buff *skb;int answ =0 ; +if (sk->sk_type !=SOCK_STREAM ) +return -EOPNOTSUPP ; + skb =skb_peek (&sk->sk_receive_queue);if (skb && skb ==READ_ONCE (unix_sk (sk)->oob_skb)) answ =1 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 20/95 regulator: core: fix locking in regulator_resolve_supply() error path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <[email protected]>
commit 497330b203d2c59c5ff3fa4c34d14494d7203bc3 upstream.
If late enabling of a supply regulator fails in regulator_resolve_supply(), the code currently triggers a lockdep warning:
WARNING: drivers/regulator/core.c:2649 at _regulator_put+0x80/0xa0, CPU#6: kworker/u32:4/596
...
Call trace:
_regulator_put+0x80/0xa0 (P)
regulator_resolve_supply+0x7cc/0xbe0
regulator_register_resolve_supply+0x28/0xb8as the regulator_list_mutex must be held when calling _regulator_put().
To solve this, simply switch to using regulator_put().
While at it, we should also make sure that no concurrent access happens to our rdev while we clear out the supply pointer. Add appropriate locking to ensure that.
While the code in question will be removed altogether in a follow-up commit, I believe it is still beneficial to have this corrected before removal for future reference.
--- drivers/regulator/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/regulator/core.c +9 -1
@@ -2139,8 +2139,16 @@ static int regulator_resolve_supply(struif (rdev->use_count) { ret =regulator_enable (rdev->supply);if (ret <0 ) { -_regulator_put (rdev->supply); +struct regulator *supply; + +regulator_lock_two (rdev, rdev->supply->rdev, &ww_ctx); + + supply = rdev->supply; rdev->supply =NULL ; + +regulator_unlock_two (rdev, supply->rdev, &ww_ctx); + +regulator_put (supply); goto out; } }
Greg Kroah-Hartman
maintainerPATCH 21/95 vc_screen: fix null-ptr-deref in vcs_notifier() during concurrent vcs_write
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yi Yang <[email protected]>
commit a287620312dc6dcb9a093417a0e589bf30fcf38a upstream.
A KASAN null-ptr-deref was observed in vcs_notifier():
BUG: KASAN: null-ptr-deref in vcs_notifier+0x98/0x130
Read of size 2 at addr qmp_cmd_name: qmp_capabilities, arguments: {}The issue is a race condition in vcs_write(). When the console_lock is temporarily dropped (to copy data from userspace), the vc_data pointer obtained from vcs_vc() may become stale. After re-acquiring the lock, vcs_vc() is called again to re-validate the pointer. If the vc has been deallocated in the meantime, vcs_vc() returns NULL, and the while loop breaks (with written > 0). However, after the loop, vcs_scr_updated(vc) is still called with the now-NULL vc pointer, leading to a null pointer dereference in the notifier chain (vcs_notifier dereferences param->vc).
Fix this by adding a NULL check for vc before calling vcs_scr_updated().
--- drivers/tty/vt/vc_screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/vt/vc_screen.c +1 -1
@@ -699,7 +699,7 @@ vcs_write(struct file *file, const char } *ppos += written; ret = written; -if (written) +if (written && vc)vcs_scr_updated (vc); unlock_out:
Greg Kroah-Hartman
maintainerPATCH 22/95 media: vidtv: fix NULL pointer dereference in vidtv_mux_push_si
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruslan Valiyev <[email protected]>
commit 7d8bf3d8f91073f4db347ed3aa6302b56107499c upstream.
syzbot reported a general protection fault invidtv_psi_ts_psi_write_into [1].
vidtv_mux_get_pid_ctx() can return NULL, but vidtv_mux_push_si() does not check for this before dereferencing the returned pointer to access the continuity counter. This leads to a general protection fault when accessing a near-NULL address.
The root cause is that vidtv_mux_pid_ctx_init() does not check the return value of vidtv_mux_create_pid_ctx_once() for PMT section PIDs. If the allocation fails, the PID context is never created, but init returns success. The subsequent vidtv_mux_push_si() call then gets NULL from vidtv_mux_get_pid_ctx() and crashes.
Fix both the root cause (add error check in vidtv_mux_pid_ctx_init for PMT PIDs) and add defensive NULL checks in vidtv_mux_push_si for all vidtv_mux_get_pid_ctx() calls.
[1]
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] Workqueue: events vidtv_mux_tick RIP: 0010:vidtv_psi_ts_psi_write_into+0x54a/0xbc0 drivers/media/test-drivers/vidtv/vidtv_psi.c:197 Call Trace: <TASK> vidtv_psi_table_header_write_into drivers/media/test-drivers/vidtv/vidtv_psi.c:799 [inline] vidtv_psi_pmt_write_into+0x3b2/0xa70 drivers/media/test-drivers/vidtv/vidtv_psi.c:1231 vidtv_mux_push_si+0x932/0xe80 drivers/media/test-drivers/vidtv/vidtv_mux.c:196 vidtv_mux_tick+0xe9b/0x1480 drivers/media/test-drivers/vidtv/vidtv_mux.c:408
--- drivers/media/test-drivers/vidtv/vidtv_mux.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/media/test-drivers/vidtv/vidtv_mux.c +7 -1
@@ -101,7 +101,8 @@ static int vidtv_mux_pid_ctx_init(struct/* add a ctx for all PMT sections */ while (p) { pid =vidtv_psi_get_pat_program_pid (p); -vidtv_mux_create_pid_ctx_once (m, pid); +if (!vidtv_mux_create_pid_ctx_once (m, pid)) + goto free; p = p->next; }
@@ -170,6 +171,9 @@ static u32 vidtv_mux_push_si(struct vidt nit_ctx =vidtv_mux_get_pid_ctx (m,VIDTV_NIT_PID ); eit_ctx =vidtv_mux_get_pid_ctx (m,VIDTV_EIT_PID ); +if (!pat_ctx || !sdt_ctx || !nit_ctx || !eit_ctx) +return 0 ; + pat_args.offset = m->mux_buf_offset; pat_args.continuity_counter = &pat_ctx->cc;
@@ -186,6 +190,8 @@ static u32 vidtv_mux_push_si(struct vidt } pmt_ctx =vidtv_mux_get_pid_ctx (m, pmt_pid); +if (!pmt_ctx) +continue ; pmt_args.offset = m->mux_buf_offset; pmt_args.pmt = m->si.pmt_secs[i];
Greg Kroah-Hartman
maintainerPATCH 23/95 virtiofs: fix UAF on submount umount
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <[email protected]>
commit 06b41351779e9289e8785694ade9042ae85e41ea upstream.
iput() called from fuse_release_end() can Oops if the super block has already been destroyed. Normally this is prevented by waiting for num_waiting to go down to zero before commencing with super block shutdown.
This only works, however, for the last submount instance, as the wait counter is per connection, not per superblock.
Revert to using synchronous release requests for the auto_submounts case, which is virtiofs only at this time.
--- fs/fuse/file.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
fs/fuse/file.c +7 -1
@@ -358,8 +358,14 @@ void fuse_file_release(struct inode *ino* aio and closes the fd before the aio completes. Since aio takes its * own ref to the file, the IO completion has to drop the ref, which is * how the fuse server can end up closing its clients' files. +* +* Exception is virtio-fs, which is not affected by the above (server is +* on host, cannot close open files in guest). Virtio-fs needs sync +* release, because the num_waiting mechanism to wait for all requests +* before commencing with fs shutdown doesn't work if submounts are +* used. */ -fuse_file_put (ff, false); +fuse_file_put (ff, ff->fm->fc->auto_submounts); }void fuse_release_common (struct file *file,bool isdir)
Greg Kroah-Hartman
maintainerPATCH 24/95 Revert "selftest/ptp: update ptp selftest to exercise the gettimex options"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <[email protected]>
This reverts commit 6b32d042aa8255e964ebed860e24adccb204fcbc, which is commit 3d07b691ee707c00afaf365440975e81bb96cd9b upstream.
The cited commit allows testptp to set a configurable clock_id. That is done via a PTP_SYS_OFFSET_EXTENDED ioctl call, whose argument is struct ptp_sys_offset_extended, where the clock_id is set. However, this Linux version does not support the ptp_sys_offset_extended.clockid field, and the test case cannot be built against this tree's own UAPI headers.
The reverted commit was introduced to resolve a missing dependency of commit bef3a83a9a67 ("testptp: Add option to open PHC in readonly mode"), which is 76868642e427 upstream. My suspicion is that the only conflict between the two is the getopt string, and there is otherwise no direct dependency between the two.
This patch therefore reverts the cited commit, with hand-resolving the getopt string to include 'r' (as introduced by c6dc458227a3), but not 'y' (introduced by 06954f715deb).
--- tools/testing/selftests/ptp/testptp.c | 62 +++------------------------ 1 file changed, 5 insertions(+), 57 deletions(-)
tools/testing/selftests/ptp/testptp.c +5 -57
@@ -147,7 +147,6 @@ static void usage(char *progname)" -T val set the ptp clock time to 'val' seconds\n" " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n" " -X get a ptp clock cross timestamp\n" -" -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n" " -z test combinations of rising/falling external time stamp flags\n" , progname, PTP_MAX_SAMPLES); }
@@ -192,7 +191,6 @@ int main(int argc, char *argv[])int readonly =0 ;int settime =0 ;int channel =-1 ; -clockid_t ext_clockid =CLOCK_REALTIME ;int64_t t1, t2, tp;int64_t interval, offset;
@@ -202,7 +200,7 @@ int main(int argc, char *argv[]) progname =strrchr (argv[0 ],'/' ); progname = progname ?1 +progname : argv[0 ]; -while (EOF != (c =getopt (argc, argv,"cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z" ))) { +while (EOF != (c =getopt (argc, argv,"cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xz" ))) {switch (c) {case 'c' : capabilities =1 ;
@@ -285,21 +283,6 @@ int main(int argc, char *argv[])case 'X' : getcross =1 ;break ; -case 'y' : -if (!strcasecmp (optarg,"realtime" )) - ext_clockid =CLOCK_REALTIME ; -else if (!strcasecmp (optarg,"monotonic" )) - ext_clockid =CLOCK_MONOTONIC ; -else if (!strcasecmp (optarg,"monotonic-raw" )) - ext_clockid =CLOCK_MONOTONIC_RAW ; -else { -fprintf (stderr, -"type needs to be realtime, monotonic or monotonic-raw; was given %s\n" , - optarg); -return -1 ; - } -break ; -case 'z' : flagtest =1 ;break ;
@@ -590,7 +573,6 @@ int main(int argc, char *argv[]) } soe->n_samples = getextended; - soe->clockid = ext_clockid;if (ioctl (fd,PTP_SYS_OFFSET_EXTENDED , soe)) {perror ("PTP_SYS_OFFSET_EXTENDED" );
@@ -599,46 +581,12 @@ int main(int argc, char *argv[]) getextended);for (i =0 ; i < getextended; i++) { -switch (ext_clockid) { -case CLOCK_REALTIME : -printf ("sample #%2d: real time before: %lld.%09u\n" , - i, soe->ts[i][0 ].sec, - soe->ts[i][0 ].nsec); -break ; -case CLOCK_MONOTONIC : -printf ("sample #%2d: monotonic time before: %lld.%09u\n" , - i, soe->ts[i][0 ].sec, - soe->ts[i][0 ].nsec); -break ; -case CLOCK_MONOTONIC_RAW : -printf ("sample #%2d: monotonic-raw time before: %lld.%09u\n" , - i, soe->ts[i][0 ].sec, - soe->ts[i][0 ].nsec); -break ; -default : -break ; - } +printf ("sample #%2d: system time before: %lld.%09u\n" , + i, soe->ts[i][0 ].sec, soe->ts[i][0 ].nsec);printf (" phc time: %lld.%09u\n" , soe->ts[i][1 ].sec, soe->ts[i][1 ].nsec); -switch (ext_clockid) { -case CLOCK_REALTIME : -printf (" real time after: %lld.%09u\n" , - soe->ts[i][2 ].sec, - soe->ts[i][2 ].nsec); -break ; -case CLOCK_MONOTONIC : -printf (" monotonic time after: %lld.%09u\n" , - soe->ts[i][2 ].sec, - soe->ts[i][2 ].nsec); -break ; -case CLOCK_MONOTONIC_RAW : -printf (" monotonic-raw time after: %lld.%09u\n" , - soe->ts[i][2 ].sec, - soe->ts[i][2 ].nsec); -break ; -default : -break ; - } +printf (" system time after: %lld.%09u\n" , + soe->ts[i][2 ].sec, soe->ts[i][2 ].nsec); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 25/95 Revert "ptp: add testptp mask test"
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <[email protected]>
This reverts commit 8510559c0fa1e228b18fcf77cfbcf5b970793a8a, which is commit 26285e689c6cd2cf3849568c83b2ebe53f467143 upstream.
The reverted commit extends the selftest to test timestamp event queue mask manipulation in testptp. It exercises masks PTP_MASK_CLEAR_ALL and PTP_MASK_EN_SINGLE, introduced in commit c5a445b1e934 ("ptp: support event queue reader channel masks"), which is not on this stable branch. The test case thus cannot be built against this tree's own UAPI headers.
The reverted commit was introduced to resolve a missing dependency of commit bef3a83a9a67 ("testptp: Add option to open PHC in readonly mode"), which is 76868642e427 upstream. The only conflict between the two is the getopt string, and there is otherwise no direct dependency between the two.
This patch therefore reverts the cited commit, with hand-resolving the getopt string to include 'r' (as introduced by c6dc458227a3), but not 'F' (introduced by c1c50689799d).
--- tools/testing/selftests/ptp/testptp.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-)
tools/testing/selftests/ptp/testptp.c +1 -18
@@ -121,7 +121,6 @@ static void usage(char *progname)" -d name device to open\n" " -e val read 'val' external time stamp events\n" " -f val adjust the ptp clock frequency by 'val' ppb\n" -" -F chan Enable single channel mask and keep device open for debugfs verification.\n" " -g get the ptp clock time\n" " -h prints this message\n" " -i val index for event/trigger\n"
@@ -190,7 +189,6 @@ int main(int argc, char *argv[])int seconds =0 ;int readonly =0 ;int settime =0 ; -int channel =-1 ;int64_t t1, t2, tp;int64_t interval, offset;
@@ -200,7 +198,7 @@ int main(int argc, char *argv[]) progname =strrchr (argv[0 ],'/' ); progname = progname ?1 +progname : argv[0 ]; -while (EOF != (c =getopt (argc, argv,"cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xz" ))) { +while (EOF != (c =getopt (argc, argv,"cd:e:f:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xz" ))) {switch (c) {case 'c' : capabilities =1 ;
@@ -214,9 +212,6 @@ int main(int argc, char *argv[])case 'f' : adjfreq =atoi (optarg);break ; -case 'F' : - channel =atoi (optarg); -break ;case 'g' : gettime =1 ;break ;
@@ -616,18 +611,6 @@ int main(int argc, char *argv[])free (xts); } -if (channel >=0 ) { -if (ioctl (fd,PTP_MASK_CLEAR_ALL )) { -perror ("PTP_MASK_CLEAR_ALL" ); - }else if (ioctl (fd,PTP_MASK_EN_SINGLE , (unsigned int *)&channel)) { -perror ("PTP_MASK_EN_SINGLE" ); - }else { -printf ("Channel %d exclusively enabled. Check on debugfs.\n" , channel); -printf ("Press any key to continue\n." ); -getchar (); - } - } -close (fd);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 26/95 KVM: x86/mmu: Ensure hugepage is in by slot before checking max mapping level
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit ef057cbf825e03b63f6edf5980f96abf3c53089d upstream.
When recovering hugepages in the shadow MMU, verify that the base gfn of the shadow page is actually contained within the target memslot, *before* querying the max mapping level given the shadow page's gfn. Failure to pre-check the validity of the gfn can lead to an out-of-bounds access to the slot's lpage_info (which typically manifests as a host #PF because the lpage_info is vmalloc'd) if the guest creates a hugepage mapping (in its PTEs) that extends "below" the bounds of a memslot.
When faulting in memory for a guest, and the size of the guest mapping is greater than KVM's (current) max mapping, then KVM will create a "direct" shadow page (direct in that there are no gPTEs to shadow, and so the target gfn is a direct calculation given the base gfn of the shadow page). The hugepage recovery flow looks for such direct shadow pages, as forcing 4KiB mappings when dirty logging generates the guest > host mapping size case. When the 4KiB restriction is lifted, then KVM can replace the shadow page with a hugepage.
But if KVM originally used a smaller mapping than the guest because the range of memory covered by the guest hugepage exceeds the bounds of a memslot, then KVM will link a direct shadow page with a gfn that is outside the bounds of the memslot being used to fault in memory. The rmap entry added for the leaf mapping is correct and within bounds, but the gfn of the leaf SPTE's parent shadow page will be out of bounds.
BUG: unable to handle page fault for address: ffffc90000806ffc #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 100000067 P4D 100000067 PUD 1002a7067 PMD 10612f067 PTE 0 Oops: Oops: 0000 [#1] SMP CPU: 13 UID: 1000 PID: 757 Comm: mmu_stress_test Not tainted 7.1.0-rc1-48ce1e26eace-x86_pir_to_irr_comments-vm #341 PREEMPT Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:kvm_mmu_max_mapping_level+0x79/0x2b0 [kvm] Call Trace: <TASK> kvm_mmu_recover_huge_pages+0x21b/0x320 [kvm] kvm_set_memslot+0x1ee/0x590 [kvm] kvm_set_memory_region.part.0+0x3a1/0x4d0 [kvm] kvm_vm_ioctl+0x9bf/0x15d0 [kvm] __x64_sys_ioctl+0x8a/0xd0 do_syscall_64+0xb7/0xbb0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x7f21c0f1a9bf </TASK>
Don't bother pre-checking the bounds of the potential hugepage, i.e. don't check that e.g. sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level + 1) is also within the memslot, as the checks performed by kvm_mmu_max_mapping_level() are a superset of the basic bounds checks. I.e. pre-checking the full range would be a dubious micro-optimization.
--- arch/x86/kvm/mmu/mmu.c | 19 +++++++++++++------ include/linux/kvm_host.h | 7 ++++++- 2 files changed, 19 insertions(+), 7 deletions(-)
arch/x86/kvm/mmu/mmu.c +13 -6
@@ -5839,13 +5839,20 @@ restart: pfn =spte_to_pfn (*sptep);/* -* We cannot do huge page mapping for indirect shadow pages, -* which are found on the last rmap (level = 1) when not using -* tdp; such shadow pages are synced with the page table in -* the guest, and the guest page table is using 4K page size -* mapping if the indirect sp has level = 1. +* Direct shadow page can be replaced by a hugepage if the host +* mapping level allows it and the memslot maps all of the host +* hugepage. Note! If the memslot maps only part of the +* hugepage, sp->gfn may be below slot->base_gfn, and querying +* the max mapping level would cause an out-of-bounds lpage_info +* access. So the gfn bounds check *must* be done first. +* +* Indirect shadow pages are created when the guest page tables +* are using 4K pages. Since the host mapping is always +* constrained by the page size in the guest, indirect shadow +* pages are never collapsible. */ -if (sp->role.direct && !kvm_is_reserved_pfn (pfn) && +if (sp->role.direct &&is_gfn_in_memslot (slot, sp->gfn) && + !kvm_is_reserved_pfn (pfn) && sp->role.level <kvm_mmu_max_mapping_level (kvm, slot, sp->gfn, pfn,PG_LEVEL_NUM )) {pte_list_remove (kvm, rmap_head, sptep);
include/linux/kvm_host.h +6 -1
@@ -1312,6 +1312,11 @@ int kvm_request_irq_source_id(struct kvmvoid kvm_free_irq_source_id (struct kvm *kvm,int irq_source_id);bool kvm_arch_irqfd_allowed (struct kvm *kvm,struct kvm_irqfd *args); +static inline bool is_gfn_in_memslot (const struct kvm_memory_slot *slot,gfn_t gfn) +{ +return gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages; +} +/* * Returns a pointer to the memslot at slot_index if it contains gfn. * Otherwise returns NULL.
@@ -1332,7 +1337,7 @@ try_get_memslot(struct kvm_memslots *slo slot_index =array_index_nospec (slot_index, slots->used_slots); slot = &slots->memslots[slot_index]; -if (gfn >= slot->base_gfn && gfn < slot->base_gfn + slot->npages) +if (is_gfn_in_memslot (slot, gfn))return slot;else return NULL ;
Greg Kroah-Hartman
maintainerPATCH 27/95 kselftest/arm64: signal: Skip SVE signal test if not enough VLs supported
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yijia Wang <[email protected]>
[ Upstream commit 78c09c0f4df89fabdcfb3e5e53d3196cf67f64ef ]
On platform where SVE is supported but there are less than 2 VLs available the signal SVE change test should be skipped instead of failing.
--- .../arm64/signal/testcases/fake_sigreturn_sve_change_vl.c | 2 ++ 1 file changed, 2 insertions(+)
tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c +2 -0
@@ -6,6 +6,7 @@* supported and is expected to segfault. */ +#include <kselftest.h> #include <signal.h> #include <ucontext.h> #include <sys/prctl.h>
@@ -40,6 +41,7 @@ static bool sve_get_vls(struct tdescr *td)/* We need at least two VLs */ if (nvls <2 ) {fprintf (stderr,"Only %d VL supported\n" , nvls); + td->result =KSFT_SKIP ;return false; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 28/95 batman-adv: tp_meter: keep unacked list in ascending ordered
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 5aa8651527ea0b610e7a09fb3b8204c1398b9525 upstream.
When batadv_tp_handle_out_of_order inserts a new entry in the list of unacked (out of order) packets, it searches from the entry with the newest sequence number towards oldest sequence number. If an entry is found which is older than the newly entry, the new entry has to be added after the found one to keep the ascending order.
But for this operation list_add_tail() was used. But this function adds an entry _before_ another one. As result, the list would contain a lot of swapped sequence numbers. The consumer of this list (batadv_tp_ack_unordered()) would then fail to correctly ack packets.
--- net/batman-adv/tp_meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/batman-adv/tp_meter.c +1 -1
@@ -1325,7 +1325,7 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,* one is attached _after_ it. In this way the list is kept in * ascending order */ -list_add_tail (&new->list, &un->list); +list_add (&new->list, &un->list); added = true;break ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 29/95 batman-adv: tp_meter: initialize dup_acks explicitly
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit b2b68b32a715e0328662801576974aa37b942b00 upstream.
When an ack with a sequence number equal to the last_acked is received, the dup_acks counter is increased to decide whether fast retransmit should be performed. Only when the sequence numbers are not equal, the dup_acks is set to the initial value (0).
But if the initial packet would have the sequence number BATADV_TP_FIRST_SEQ, dup_acks would not be initialized and atomic_inc would operate on an undefined starting value. It is therefore required to have it explicitly initialized during the start of the sender session.
--- net/batman-adv/tp_meter.c | 1 + 1 file changed, 1 insertion(+)
net/batman-adv/tp_meter.c +1 -0
@@ -1045,6 +1045,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, tp_vars->icmp_uid = icmp_uid; tp_vars->last_sent =BATADV_TP_FIRST_SEQ ; +atomic_set (&tp_vars->dup_acks,0 );atomic_set (&tp_vars->last_acked,BATADV_TP_FIRST_SEQ ); tp_vars->fast_recovery = false; tp_vars->recover =BATADV_TP_FIRST_SEQ ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 30/95 batman-adv: tp_meter: initialize dec_cwnd explicitly
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit febfb1b86224489535312296ecfa3d4bf467f339 upstream.
When batadv_tp_update_cwnd() is called, dec_cwnd is increased. But dec_cwnd is only initialixed (to 0) when a duplicate Ack was received or when cwnd is below the ss_threshold.
Just initialize the cwnd during the initialization to avoid any potential access of uninitialized data.
--- net/batman-adv/tp_meter.c | 2 ++ 1 file changed, 2 insertions(+)
net/batman-adv/tp_meter.c +2 -0
@@ -1055,6 +1055,8 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,* soft_interface, hence its MTU */ tp_vars->cwnd =BATADV_TP_PLEN *3 ; + tp_vars->dec_cwnd =0 ; +/* at the beginning initialise the SS threshold to the biggest possible * window size, hence the AWND size */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 31/95 batman-adv: tp_meter: avoid window underflow
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 765947b81fb54b6ebb0bc1cfe55c0fa399e002b8 upstream.
In batadv_tp_avail(), win_left is calculated with 32-bit unsigned
arithmetic: win_left = win_limit - tp_vars->last_sent;
During Fast Recovery, cwnd is inflated and last_sent advances rapidly. When Fast Recovery ends, cwnd drops abruptly back to ss_threshold. If the newly shrunk win_limit is less than last_sent, the unsigned subtraction will underflow, wrapping to a massive positive value. Instead of returning that the window is full (unavailable), it returns that the sender can continue sending.
To handle this situation, it must be checked whether the windows end sequence number (win_limit) has to be compared with the last sent sequence number. If it would be before the last sent sequence number, then more acks are needed before the transmission can be started again.
--- net/batman-adv/tp_meter.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/batman-adv/tp_meter.c +6 -1
@@ -817,10 +817,15 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,static bool batadv_tp_avail (struct batadv_tp_vars *tp_vars,size_t payload_len) { +u32 last_sent =READ_ONCE (tp_vars->last_sent);u32 win_left, win_limit; win_limit =atomic_read (&tp_vars->last_acked) + tp_vars->cwnd; - win_left = win_limit - tp_vars->last_sent; + +if (batadv_seq_before (last_sent, win_limit)) + win_left = win_limit - last_sent; +else + win_left =0 ;return win_left >= payload_len; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 32/95 batman-adv: tp_meter: avoid divide-by-zero for dec_cwnd
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 33ccd52f3cc9ed46ce395199f89aa3234dc83314 upstream.
The cwnd is always MSS <= cwnd <= 0x20000000. But the calculation in batadv_tp_update_cwnd() assumes unsigned 32 bit arithmetics.
((mss * 8) ** 2) / (cwnd * 8)
In case cwnd is actually 0x20000000, it will be shifted by 3 bit to the left end up at 0x100000000 or U32_MAX + 1. It will therefore wrap around and be 0 - resulting in:
((mss * 8) ** 2) / 0
This is of course invalid and cannot be calculated. The calculation should must be simplified to avoid this overflow:
(mss ** 2) * 8 / cwnd
It will keep the precision enhancement from the scaling (by 8) but avoid the overflow in the divisor.
In theory, there could still be an overflow in the dividend. It is at the moment fixed to BATADV_TP_PLEN in batadv_tp_recv_ack() - so it is not an imminent problem. But allowing it to use the whole u32 bit range, would mean that it can still use up to 67 bits. To keep this calculation safe for 32 bit arithmetic, mss must never use more than floor((32 - 3) / 2) bits - or in other words: must never be larger than 16383.
--- net/batman-adv/tp_meter.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/batman-adv/tp_meter.c +4 -1
@@ -154,9 +154,12 @@ static void batadv_tp_update_cwnd(struct batadv_tp_vars *tp_vars, u32 mss)return ; } +/* prevent overflow in (mss * mss) << 3 */ + mss =min_t (u32, mss, (1U <<14 ) -1 ); +/* increment CWND at least of 1 (section 3.1 of RFC5681) */ tp_vars->dec_cwnd +=max_t (u32,1U <<3 , - ((mss * mss) <<6 ) / (tp_vars->cwnd <<3 )); + ((mss * mss) <<3 ) / tp_vars->cwnd);if (tp_vars->dec_cwnd < (mss <<3 )) {spin_unlock_bh (&tp_vars->cwnd_lock);return ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 33/95 batman-adv: tp_meter: fix fast recovery precondition
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 2b0d08f08ed3b2174f05c43089ec65f3543a025b upstream.
The fast recovery precondition checks if the recover (initialized to BATADV_TP_FIRST_SEQ) is bigger than the received ack. But since recover is only updated when this check is successful, it will never enter the fast recovery mode.
According to RFC6582 Section 3.2 step 2, the check should actually be different:
Quoted 3 lines
When the third duplicate ACK is received, the TCP sender first checks the value of recover to see if the Cumulative Acknowledgment field covers more than recover
The precondition must therefore check if recover is smaller than the received ack - basically swapping the operands of the current check.
--- net/batman-adv/tp_meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/batman-adv/tp_meter.c +1 -1
@@ -733,7 +733,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,if (atomic_read (&tp_vars->dup_acks) !=3 ) goto out; -if (recv_ack >= tp_vars->recover) +if (tp_vars->recover >= recv_ack) goto out;/* if this is the third duplicate ACK do Fast Retransmit */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 34/95 batman-adv: tp_meter: handle seqno wrap-around for fast recovery detection
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit f54c85ed42a1b27a516cf2a4728f5a612b799e07 upstream.
The recover variable and the last_sent sequence number are initialized on purpose as a really high value which will wrap-around after the first 2000 bytes. The fast recovery precondition must therefore not use simple integer comparisons but use helpers which are aware of the sequence number wrap-arounds.
--- net/batman-adv/tp_meter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/batman-adv/tp_meter.c +1 -1
@@ -733,7 +733,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,if (atomic_read (&tp_vars->dup_acks) !=3 ) goto out; -if (tp_vars->recover >= recv_ack) +if (!batadv_seq_before (tp_vars->recover, recv_ack)) goto out;/* if this is the third duplicate ACK do Fast Retransmit */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 35/95 batman-adv: tp_meter: add only finished tp_vars to lists
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 15ccbf685222274f5add1387af58c2a41a95f81e upstream.
When the receiver variables (aka "session") are initialized, then they are added to the list of sessions before the timer is set up. A RCU protected reader could therefore find the entry and run mod_setup before batadv_tp_init_recv() finished the timer initialization.
The same is true for batadv_tp_start(), which must first initialize the finish_work and the test_length to avoid a similar problem.
--- net/batman-adv/tp_meter.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
net/batman-adv/tp_meter.c +9 -9
@@ -1096,21 +1096,21 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, tp_vars->prerandom_offset =0 ;spin_lock_init (&tp_vars->prerandom_lock); -kref_get (&tp_vars->refcount); -hlist_add_head_rcu (&tp_vars->list, &bat_priv->tp_list); -spin_unlock_bh (&bat_priv->tp_list_lock); - tp_vars->test_length = test_length;if (!tp_vars->test_length) tp_vars->test_length =BATADV_TP_DEF_TEST_LENGTH ; +/* init work item for finished tp tests */ +INIT_DELAYED_WORK (&tp_vars->finish_work, batadv_tp_sender_finish); + +kref_get (&tp_vars->refcount); +hlist_add_head_rcu (&tp_vars->list, &bat_priv->tp_list); +spin_unlock_bh (&bat_priv->tp_list_lock); +batadv_dbg (BATADV_DBG_TP_METER , bat_priv,"Meter: starting throughput meter towards %pM (length=%ums)\n" , dst, test_length); -/* init work item for finished tp tests */ -INIT_DELAYED_WORK (&tp_vars->finish_work, batadv_tp_sender_finish); -/* start tp kthread. This way the write() call issued from userspace can * happily return and avoid to block */
@@ -1430,10 +1430,10 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,INIT_LIST_HEAD (&tp_vars->unacked_list);kref_get (&tp_vars->refcount); -hlist_add_head_rcu (&tp_vars->list, &bat_priv->tp_list); +timer_setup (&tp_vars->timer, batadv_tp_receiver_shutdown,0 );kref_get (&tp_vars->refcount); -timer_setup (&tp_vars->timer, batadv_tp_receiver_shutdown,0 ); +hlist_add_head_rcu (&tp_vars->list, &bat_priv->tp_list);batadv_tp_reset_receiver_timer (tp_vars);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 36/95 batman-adv: bla: annotate lasttime access with READ/WRITE_ONCE
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 98b0fb191c878a64cbaebfe231d96d57576acf8c upstream.
The lasttime field for claim, backbone_gw, and loopdetect tracks the jiffies value of the most recent activity and is used to detect timeouts. These accesses are not consistently protected by a lock, so READ_ONCE/WRITE_ONCE must be used to prevent data races caused by compiler optimizations.
--- net/batman-adv/bridge_loop_avoidance.c | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-)
net/batman-adv/bridge_loop_avoidance.c +14 -14
@@ -511,7 +511,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, u8 *orig,return NULL ; entry->vid = vid; - entry->lasttime = jiffies; +WRITE_ONCE (entry->lasttime, jiffies); entry->crc =BATADV_BLA_CRC_INIT ; entry->bat_priv = bat_priv;spin_lock_init (&entry->crc_lock);
@@ -579,7 +579,7 @@ batadv_bla_update_own_backbone_gw(struct batadv_priv *bat_priv,if (unlikely (!backbone_gw))return ; - backbone_gw->lasttime = jiffies; +WRITE_ONCE (backbone_gw->lasttime, jiffies);batadv_backbone_gw_put (backbone_gw); }
@@ -713,7 +713,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,ether_addr_copy (claim->addr, mac);spin_lock_init (&claim->backbone_lock); claim->vid = vid; - claim->lasttime = jiffies; +WRITE_ONCE (claim->lasttime, jiffies);kref_get (&backbone_gw->refcount); claim->backbone_gw = backbone_gw;kref_init (&claim->refcount);
@@ -735,7 +735,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,return ; } }else { - claim->lasttime = jiffies; +WRITE_ONCE (claim->lasttime, jiffies);if (claim->backbone_gw == backbone_gw)/* no need to register a new backbone */ goto claim_free_ref;
@@ -768,7 +768,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,spin_lock_bh (&backbone_gw->crc_lock); backbone_gw->crc ^=crc16 (0 , claim->addr,ETH_ALEN );spin_unlock_bh (&backbone_gw->crc_lock); - backbone_gw->lasttime = jiffies; +WRITE_ONCE (backbone_gw->lasttime, jiffies); claim_free_ref:batadv_claim_put (claim);
@@ -857,7 +857,7 @@ static bool batadv_handle_announce(struct batadv_priv *bat_priv, u8 *an_addr,return true;/* handle as ANNOUNCE frame */ - backbone_gw->lasttime = jiffies; +WRITE_ONCE (backbone_gw->lasttime, jiffies); crc =ntohs (*((__force __be16 *)(&an_addr[4 ]))); batadv_dbg(BATADV_DBG_BLA, bat_priv,
@@ -1252,7 +1252,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now) head, hash_entry) {if (now) goto purge_now; -if (!batadv_has_timed_out (backbone_gw->lasttime, +if (!batadv_has_timed_out (READ_ONCE (backbone_gw->lasttime),BATADV_BLA_BACKBONE_TIMEOUT ))continue ;
@@ -1333,7 +1333,7 @@ static void batadv_bla_purge_claims(struct batadv_priv *bat_priv, primary_if->net_dev->dev_addr)) goto skip; -if (!batadv_has_timed_out (claim->lasttime, +if (!batadv_has_timed_out (READ_ONCE (claim->lasttime),BATADV_BLA_CLAIM_TIMEOUT )) goto skip;
@@ -1493,7 +1493,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)eth_random_addr (bat_priv->bla.loopdetect_addr); bat_priv->bla.loopdetect_addr[0 ] =0xba ; bat_priv->bla.loopdetect_addr[1 ] =0xbe ; - bat_priv->bla.loopdetect_lasttime = jiffies; +WRITE_ONCE (bat_priv->bla.loopdetect_lasttime, jiffies);atomic_set (&bat_priv->bla.loopdetect_next,BATADV_BLA_LOOPDETECT_PERIODS );
@@ -1514,7 +1514,7 @@ static void batadv_bla_periodic_work(struct work_struct *work) primary_if->net_dev->dev_addr))continue ; - backbone_gw->lasttime = jiffies; +WRITE_ONCE (backbone_gw->lasttime, jiffies);batadv_bla_send_announce (bat_priv, backbone_gw);if (send_loopdetect)
@@ -1899,7 +1899,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,/* If the packet came too late, don't forward it on the mesh * but don't consider that as loop. It might be a coincidence. */ -if (batadv_has_timed_out (bat_priv->bla.loopdetect_lasttime, +if (batadv_has_timed_out (READ_ONCE (bat_priv->bla.loopdetect_lasttime),BATADV_BLA_LOOPDETECT_TIMEOUT ))return true;
@@ -2015,7 +2015,7 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,if (own_claim) {/* ... allow it in any case */ - claim->lasttime = jiffies; +WRITE_ONCE (claim->lasttime, jiffies); goto allow; }
@@ -2117,7 +2117,7 @@ bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,/* if yes, the client has roamed and we have * to unclaim it. */ -if (batadv_has_timed_out (claim->lasttime,100 )) { +if (batadv_has_timed_out (READ_ONCE (claim->lasttime),100 )) {/* only unclaim if the last claim entry is * older than 100 ms to make sure we really * have a roaming client here.
@@ -2371,7 +2371,7 @@ batadv_bla_backbone_dump_entry(struct sk_buff *msg, u32 portid, backbone_crc = backbone_gw->crc;spin_unlock_bh (&backbone_gw->crc_lock); - msecs =jiffies_to_msecs (jiffies - backbone_gw->lasttime); + msecs =jiffies_to_msecs (jiffies -READ_ONCE (backbone_gw->lasttime));if (is_own)if (nla_put_flag (msg,BATADV_ATTR_BLA_OWN )) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 37/95 batman-adv: prevent ELP transmission interval underflow
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 5e50d4b8ae3ea622122d3c6a38d7f6fe68dfddca upstream.
batadv_v_elp_start_timer() enqeues a delayed work. The time when it starts is randomly chosen between (elp_interval - BATADV_JITTER) and (elp_interval + BATADV_JITTER). The configured elp_interval must therefore be larger or equal to BATADV_JITTER to avoid that it causes an underflow of the unsigned integer. If this would happen, then a "fast" ELP interval would turn into a "day long" delay.
At the same time, it must not be larger than the maximum value the variable can store.
--- net/batman-adv/netlink.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/batman-adv/netlink.c +7 -1
@@ -941,9 +941,15 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb,#ifdef CONFIG_BATMAN_ADV_BATMAN_V if (info->attrs[BATADV_ATTR_ELP_INTERVAL ]) { +u32 elp_interval; + attr = info->attrs[BATADV_ATTR_ELP_INTERVAL ]; + elp_interval =nla_get_u32 (attr); + + elp_interval =min_t (u32, elp_interval,INT_MAX ); + elp_interval =max_t (u32, elp_interval,BATADV_JITTER ); -atomic_set (&hard_iface->bat_v.elp_interval,nla_get_u32 (attr)); +atomic_set (&hard_iface->bat_v.elp_interval, elp_interval); }if (info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE ]) {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 38/95 batman-adv: tp_meter: initialize last_recv_time during init
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 811cb00fa8cdc3f0a7f6eefc000a6888367c8c8f upstream.
The last_recv_time is the most important indicator for a receiver session to figure out whether a session timed out or not. But this information was only initialized after the session was added to the tp_receiver_list and after the timer was started.
In the worst case, the timer (function) could have tried to access this information before the actual initialization was reached. Like rest of the variables of the tp_meter receiver session, this field has to be filled out before any other (parallel running) context has the chance to access it.
--- net/batman-adv/tp_meter.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
net/batman-adv/tp_meter.c +7 -3
@@ -1403,8 +1403,10 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, tp_vars =batadv_tp_list_find_session (bat_priv, icmp->orig, icmp->session,BATADV_TP_RECEIVER ); -if (tp_vars) +if (tp_vars) { + tp_vars->last_recv_time = jiffies; goto out_unlock; + }if (!atomic_add_unless (&bat_priv->tp_num,1 ,BATADV_TP_MAX_NUM )) { batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
@@ -1432,6 +1434,8 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,kref_get (&tp_vars->refcount);timer_setup (&tp_vars->timer, batadv_tp_receiver_shutdown,0 ); + tp_vars->last_recv_time = jiffies; +kref_get (&tp_vars->refcount);hlist_add_head_rcu (&tp_vars->list, &bat_priv->tp_list);
@@ -1480,9 +1484,9 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, icmp->orig); goto out; } - } - tp_vars->last_recv_time = jiffies; + tp_vars->last_recv_time = jiffies; + }/* if the packet is a duplicate, it may be the case that an ACK has been * lost. Resend the ACK
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 39/95 batman-adv: ensure bcast is writable before modifying TTL
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 4cd6d3a4b96a8576f1fed8f9f9f17c2dc2978e0c upstream.
Before batman-adv is allowed to write to an skb, it either has to have its own copy of the skb or used skb_cow() to ensure that the data part is not shared.
The old implementation used a shared queue and created copies before attempting to write to it. But with the new implementation, the broadcast packet is already modified when it gets received. Potentially writing to shared buffers in this process.
Adding a skb_cow() right before this operation avoids this and can at the same time prepare it for the modifications required to rebroadcast the packet.
--- net/batman-adv/routing.c | 6 ++++++ 1 file changed, 6 insertions(+)
net/batman-adv/routing.c +6 -0
@@ -1198,6 +1198,12 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,if (batadv_is_my_mac (bat_priv, bcast_packet->orig)) goto free_skb; +/* create a copy of the skb, if needed, to modify it. */ +if (skb_cow (skb,ETH_HLEN ) <0 ) + goto free_skb; + + bcast_packet = (struct batadv_bcast_packet *)skb->data; +if (bcast_packet->ttl-- <2 ) goto free_skb;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 40/95 batman-adv: fix (m|b)cast csum after decrementing TTL
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit e728bbdf32660c8f32b8f5e8d09427a2c131ad60 upstream.
The broadcast and multicast packets can be received at the same time by the local system and forwarded to other nodes. Both are simply decrementing the TTL at the beginning of the receive path - independent of chosen paths (receive/forward). But such a modification of the data conflicts with the hw csum. This is not a problem when the packet is directly forwarded but can cause errors in the local receive path.
Such a problem can then trigger a "hw csum failure". The receiver path must therefore ensure that the csum is fixed for each modification of the payload before batadv_interface_rx() is reached.
Since all batman-adv packet types with a ttl have it as u8 at offset 2, a helper can be used for all of them. But it is only used at the moment for batadv_bcast_packet and batadv_mcast_packet because they are the only ones which deliver the packet locally but unconditionally modify the TTL.
--- net/batman-adv/routing.c | 55 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-)
net/batman-adv/routing.c +54 -1
@@ -8,6 +8,7 @@#include "main.h" #include <linux/atomic.h> +#include <linux/build_bug.h> #include <linux/byteorder/generic.h> #include <linux/compiler.h> #include <linux/errno.h>
@@ -205,6 +206,58 @@ bool batadv_check_management_packet(struct sk_buff *skb,return true; } +/** +* batadv_skb_decrement_ttl() - decrement ttl in a batman-adv header, csum-safe +* @skb: the received packet with @skb->data pointing to the batman-adv header +* +* Supports the following packet types, all of which carry the TTL at offset 2: +* +* - batadv_ogm_packet +* - batadv_ogm2_packet +* - batadv_icmp_header +* - batadv_icmp_packet +* - batadv_icmp_tp_packet +* - batadv_icmp_packet_rr +* - batadv_unicast_packet +* - batadv_frag_packet +* - batadv_bcast_packet +* - batadv_mcast_packet +* - batadv_coded_packet +* - batadv_unicast_tvlv_packet +* +* Return: true if the packet may be forwarded (ttl decremented), +* false if it must be dropped (ttl would expire) +*/ +static bool batadv_skb_decrement_ttl (struct sk_buff *skb) +{ +static const size_t ttl_offset =2 ; +u8 *ttl_pos; + +BUILD_BUG_ON (offsetof(struct batadv_ogm_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_ogm2_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_icmp_header , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_icmp_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_icmp_tp_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_icmp_packet_rr , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_unicast_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_frag_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_bcast_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_coded_packet , ttl) != ttl_offset); +BUILD_BUG_ON (offsetof(struct batadv_unicast_tvlv_packet , ttl) != ttl_offset); + + ttl_pos = skb->data + ttl_offset; + +/* would expire on this hop -> drop, leave header + csum untouched */ +if (*ttl_pos <2 ) +return false; + +skb_postpull_rcsum (skb, ttl_pos,1 ); + (*ttl_pos)--; +skb_postpush_rcsum (skb, ttl_pos,1 ); + +return true; +} +/** * batadv_recv_my_icmp_packet() - receive an icmp packet locally * @bat_priv: the bat priv with all the soft interface information
@@ -1204,7 +1257,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, bcast_packet = (struct batadv_bcast_packet *)skb->data; -if (bcast_packet->ttl-- <2 ) +if (!batadv_skb_decrement_ttl (skb)) goto free_skb; orig_node =batadv_orig_hash_find (bat_priv, bcast_packet->orig);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 41/95 batman-adv: frag: ensure fragment is writable before modifying TTL
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit b7293c6e8c15b2db77809b25cf8389e35331b27a upstream.
Before batman-adv is allowed to write to an skb, it either has to have its own copy of the skb or use skb_cow() to ensure that the data part is not shared. But batadv_frag_skb_fwd() modifies the TTL even when it is shared.
Adding a skb_cow() right before this operation avoids this and can at the same time prepare it for the modifications required to forward the fragment.
--- net/batman-adv/fragmentation.c | 15 ++++++++++++++- net/batman-adv/fragmentation.h | 3 ++- net/batman-adv/routing.c | 3 +-- 3 files changed, 17 insertions(+), 4 deletions(-)
net/batman-adv/fragmentation.c +14 -1
@@ -385,6 +385,8 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,* @skb: skb to forward * @recv_if: interface that the skb is received on * @orig_node_src: originator that the skb is received from +* @rx_result: set to NET_RX_SUCCESS when the fragment was forwarded and +* NET_RX_DROP when it was dropped; only valid when true is returned * * Look up the next-hop of the fragments payload and check if the merged packet * will exceed the MTU towards the next-hop. If so, the fragment is forwarded
@@ -394,7 +396,8 @@ bool batadv_frag_skb_buffer(struct sk_buff **skb,*/ bool batadv_frag_skb_fwd (struct sk_buff *skb,struct batadv_hard_iface *recv_if, -struct batadv_orig_node *orig_node_src) +struct batadv_orig_node *orig_node_src, +int *rx_result) {struct batadv_priv *bat_priv =netdev_priv (recv_if->soft_iface);struct batadv_orig_node *orig_node_dst;
@@ -417,12 +420,22 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,*/ total_size =ntohs (packet->total_size);if (total_size > neigh_node->if_incoming->net_dev->mtu) { +if (skb_cow (skb,ETH_HLEN ) <0 ) { +kfree_skb (skb); + *rx_result =NET_RX_DROP ; + ret = true; + goto out; + } + + packet = (struct batadv_frag_packet *)skb->data; +batadv_inc_counter (bat_priv,BATADV_CNT_FRAG_FWD );batadv_add_counter (bat_priv,BATADV_CNT_FRAG_FWD_BYTES , skb->len +ETH_HLEN ); packet->ttl--;batadv_send_unicast_skb (skb, neigh_node); + *rx_result =NET_RX_SUCCESS ; ret = true; }
net/batman-adv/fragmentation.h +2 -1
@@ -19,7 +19,8 @@ void batadv_frag_purge_orig(struct batadv_orig_node *orig, bool (*check_cb)(struct batadv_frag_table_entry *));bool batadv_frag_skb_fwd (struct sk_buff *skb,struct batadv_hard_iface *recv_if, -struct batadv_orig_node *orig_node_src); +struct batadv_orig_node *orig_node_src, +int *rx_result);bool batadv_frag_skb_buffer (struct sk_buff **skb,struct batadv_orig_node *orig_node); int batadv_frag_send_packet(struct sk_buff *skb,
net/batman-adv/routing.c +1 -2
@@ -1174,10 +1174,9 @@ int batadv_recv_frag_packet(struct sk_buff *skb,/* Route the fragment if it is not for us and too big to be merged. */ if (!batadv_is_my_mac (bat_priv, frag_packet->dest) && -batadv_frag_skb_fwd (skb, recv_if, orig_node_src)) { +batadv_frag_skb_fwd (skb, recv_if, orig_node_src, &ret)) {/* skb was consumed */ skb =NULL ; - ret =NET_RX_SUCCESS ; goto put_orig_node; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 42/95 batman-adv: frag: avoid underflow of TTL
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 493d9d2528e1a09b090e4b37f0f553def7bd5ce9 upstream.
Packets with a TTL are using it to limit the amount of time this packet can be forwarded. But for batadv_frag_packet, the TTL was always only reduced but it was never evaluated. It could even underflow without any effect.
Check the TTL in batadv_frag_skb_fwd() before attempting to prepare it for forwarding. This keeps it in sync with the not fragmented unicast packet.
--- net/batman-adv/fragmentation.c | 7 +++++++ 1 file changed, 7 insertions(+)
net/batman-adv/fragmentation.c +7 -0
@@ -420,6 +420,13 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,*/ total_size =ntohs (packet->total_size);if (total_size > neigh_node->if_incoming->net_dev->mtu) { +if (packet->ttl <2 ) { +kfree_skb (skb); + *rx_result =NET_RX_DROP ; + ret = true; + goto out; + } +if (skb_cow (skb,ETH_HLEN ) <0 ) {kfree_skb (skb); *rx_result =NET_RX_DROP ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 43/95 batman-adv: v: prevent OGM aggregation on disabled hardif
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit d11c00b95b2a3b3934007fc003dccc6fdcc061ad upstream.
When an interface gets disabled, the worker is correctly disabled by batadv_hardif_disable_interface() -> ... -> batadv_v_ogm_iface_disable(). In this process, the skb aggr_list is also freed.
But batadv_v_ogm_send_meshif() can still queue new skbs (via batadv_v_ogm_queue_on_if()) to the aggr_list. This will only stop after all cores can no longer find the RCU protected list of hard interfaces. These queued skbs will never be freed or consumed by batadv_v_ogm_aggr_work.
The batadv_v_ogm_iface_disable() function must block batadv_v_ogm_queue_on_if() to avoid leak of skbs.
--- net/batman-adv/bat_v.c | 1 + net/batman-adv/bat_v_ogm.c | 12 ++++++++++++ net/batman-adv/types.h | 6 ++++++ 3 files changed, 19 insertions(+)
net/batman-adv/bat_v.c +1 -0
@@ -838,6 +838,7 @@ void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface) hard_iface->bat_v.aggr_len =0 ;skb_queue_head_init (&hard_iface->bat_v.aggr_list); + hard_iface->bat_v.aggr_list_enabled = false;INIT_DELAYED_WORK (&hard_iface->bat_v.aggr_wq, batadv_v_ogm_aggr_work); }
net/batman-adv/bat_v_ogm.c +12 -0
@@ -255,11 +255,18 @@ static void batadv_v_ogm_queue_on_if(struct batadv_priv *bat_priv, }spin_lock_bh (&hard_iface->bat_v.aggr_list.lock); +if (!hard_iface->bat_v.aggr_list_enabled) { +kfree_skb (skb); + goto unlock; + } +if (!batadv_v_ogm_queue_left (skb, hard_iface))batadv_v_ogm_aggr_send (bat_priv, hard_iface); hard_iface->bat_v.aggr_len +=batadv_v_ogm_len (skb);__skb_queue_tail (&hard_iface->bat_v.aggr_list, skb); + +unlock:spin_unlock_bh (&hard_iface->bat_v.aggr_list.lock); }
@@ -422,6 +429,10 @@ int batadv_v_ogm_iface_enable(struct batadv_hard_iface *hard_iface) {struct batadv_priv *bat_priv =netdev_priv (hard_iface->soft_iface); +spin_lock_bh (&hard_iface->bat_v.aggr_list.lock); + hard_iface->bat_v.aggr_list_enabled = true; +spin_unlock_bh (&hard_iface->bat_v.aggr_list.lock); +batadv_v_ogm_start_queue_timer (hard_iface);batadv_v_ogm_start_timer (bat_priv);
@@ -437,6 +448,7 @@ void batadv_v_ogm_iface_disable(struct batadv_hard_iface *hard_iface)cancel_delayed_work_sync (&hard_iface->bat_v.aggr_wq);spin_lock_bh (&hard_iface->bat_v.aggr_list.lock); + hard_iface->bat_v.aggr_list_enabled = false;batadv_v_ogm_aggr_list_free (hard_iface);spin_unlock_bh (&hard_iface->bat_v.aggr_list.lock); }
net/batman-adv/types.h +6 -0
@@ -130,6 +130,12 @@ struct batadv_hard_iface_bat_v {/** @aggr_list: queue for to be aggregated OGM packets */ struct sk_buff_head aggr_list; +/** +* @aggr_list_enabled: aggr_list is active and new skbs can be +* enqueued. Protected by aggr_list.lock after initialization +*/ + bool aggr_list_enabled:1; +/** @aggr_len: size of the OGM aggregate (excluding ethernet header) */ unsigned int aggr_len;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 44/95 batman-adv: tp_meter: restrict number of unacked list entries
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit e7c775110e1858e5a7471a23a9c9658c0af9df89 upstream.
When the unacked_list is unbound, an attacker could send messages with small lengths and appropriated seqno + gaps to force the receiver to allocate more and more unacked_list entries. And the end either causing an out-of-memory situation or increase the management overhead for the (large) list that significant portions of CPU cycles are wasted in searching through the list.
When limiting the list to a specific number, it is important to still correctly add a new entry to the list. But if the list became larger than the limit, the last entry of the list (with the highest seqno) must be dropped to still allow the earlier seqnos to finish and therefore to continue the process. Otherwise, the process might get stuck with too high seqnos which are not handled by batadv_tp_ack_unordered().
--- net/batman-adv/tp_meter.c | 23 ++++++++++++++++++++++- net/batman-adv/types.h | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-)
net/batman-adv/tp_meter.c +22 -1
@@ -87,6 +87,11 @@#define BATADV_TP_PLEN (BATADV_TP_PACKET_LEN - ETH_HLEN - \ sizeof(struct batadv_unicast_packet)) +/** +* BATADV_TP_MAX_UNACKED - maximum number of packets a receiver didn't yet ack +*/ +#define BATADV_TP_MAX_UNACKED 100 +static u8 batadv_tp_prerandom[4096 ]__read_mostly ;/**
@@ -1195,6 +1200,7 @@ static void batadv_tp_receiver_shutdown(struct timer_list *t)list_for_each_entry_safe (un, safe, &tp_vars->unacked_list, list) {list_del (&un->list);kfree (un); + tp_vars->unacked_count--; }spin_unlock_bh (&tp_vars->unacked_lock);
@@ -1308,6 +1314,7 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,/* if the list is empty immediately attach this new object */ if (list_empty (&tp_vars->unacked_list)) {list_add (&new->list, &tp_vars->unacked_list); + tp_vars->unacked_count++; goto out; }
@@ -1338,12 +1345,24 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,*/ list_add (&new->list, &un->list); added = true; + tp_vars->unacked_count++;break ; }/* received packet with smallest seqno out of order; add it to front */ -if (!added) +if (!added) {list_add (&new->list, &tp_vars->unacked_list); + tp_vars->unacked_count++; + } + +/* remove the last (biggest) unacked seqno when list is too large */ +if (tp_vars->unacked_count >BATADV_TP_MAX_UNACKED ) { + un =list_last_entry (&tp_vars->unacked_list, + struct batadv_tp_unacked, list); +list_del (&un->list); +kfree (un); + tp_vars->unacked_count--; + } out:spin_unlock_bh (&tp_vars->unacked_lock);
@@ -1380,6 +1399,7 @@ static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)list_del (&un->list);kfree (un); + tp_vars->unacked_count--; }spin_unlock_bh (&tp_vars->unacked_lock); }
@@ -1430,6 +1450,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,spin_lock_init (&tp_vars->unacked_lock);INIT_LIST_HEAD (&tp_vars->unacked_list); + tp_vars->unacked_count =0 ;kref_get (&tp_vars->refcount);timer_setup (&tp_vars->timer, batadv_tp_receiver_shutdown,0 );
net/batman-adv/types.h +3 -0
@@ -1494,6 +1494,9 @@ struct batadv_tp_vars {/** @unacked_lock: protect unacked_list */ spinlock_t unacked_lock; +/** @unacked_count: number of unacked entries */ +size_t unacked_count; +/** @last_recv_time: time (jiffies) a msg was received */ unsigned long last_recv_time;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 45/95 batman-adv: tp_meter: annotate last_recv_time access with READ/WRITE_ONCE
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit d67c728f07fca2ee6ffdc6dd4421cf2e8691f4d1 upstream.
The last_recv_time field for batadv_tp_receiver tracks the jiffies value of the most recent activity and is used to detect timeouts. These accesses are not consistently protected by a lock, so READ_ONCE/WRITE_ONCE must be used to prevent data races caused by compiler optimizations.
--- net/batman-adv/tp_meter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/batman-adv/tp_meter.c +4 -4
@@ -1183,7 +1183,7 @@ static void batadv_tp_receiver_shutdown(struct timer_list *t) bat_priv = tp_vars->bat_priv;/* if there is recent activity rearm the timer */ -if (!batadv_has_timed_out (tp_vars->last_recv_time, +if (!batadv_has_timed_out (READ_ONCE (tp_vars->last_recv_time),BATADV_TP_RECV_TIMEOUT )) {/* reset the receiver shutdown timer */ batadv_tp_reset_receiver_timer (tp_vars);
@@ -1424,7 +1424,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, tp_vars =batadv_tp_list_find_session (bat_priv, icmp->orig, icmp->session,BATADV_TP_RECEIVER );if (tp_vars) { - tp_vars->last_recv_time = jiffies; +WRITE_ONCE (tp_vars->last_recv_time, jiffies); goto out_unlock; }
@@ -1455,7 +1455,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv,kref_get (&tp_vars->refcount);timer_setup (&tp_vars->timer, batadv_tp_receiver_shutdown,0 ); - tp_vars->last_recv_time = jiffies; +WRITE_ONCE (tp_vars->last_recv_time, jiffies);kref_get (&tp_vars->refcount);hlist_add_head_rcu (&tp_vars->list, &bat_priv->tp_list);
@@ -1506,7 +1506,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, goto out; } - tp_vars->last_recv_time = jiffies; +WRITE_ONCE (tp_vars->last_recv_time, jiffies); }/* if the packet is a duplicate, it may be the case that an ACK has been
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 46/95 batman-adv: tp_meter: prevent parallel modifications of last_recv
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 6dde0cfcb36e4d5b3de35b75696937478441eed4 upstream.
When last_recv is updated to store the last receive sequence number, it is assuming that nothing is modifying in parallel while:
* check for outdated packets is done
* out of order check is performed (and packets are stored in out-of-order queue)
* the out-of-order queue was searched for closed gaps
* sequence number for next ack is calculated
Nothing of that was actually protected. It could therefore happen that the last_recv was updated multiple times in parallel and the final sequence number was calculated with deltas which had no connection to the sequence number they were added to.
Lock this whole region with the same lock which was already used to protect the unacked (out-of-order) list.
--- net/batman-adv/tp_meter.c | 22 +++++++++++++--------- net/batman-adv/types.h | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-)
net/batman-adv/tp_meter.c +13 -9
@@ -1294,6 +1294,7 @@ static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,*/ static bool batadv_tp_handle_out_of_order (struct batadv_tp_vars *tp_vars,const struct sk_buff *skb) + __must_hold(&tp_vars->unacked_lock) {const struct batadv_icmp_tp_packet *icmp;struct batadv_tp_unacked *un, *new;
@@ -1310,12 +1311,11 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars, payload_len = skb->len -sizeof (struct batadv_unicast_packet ); new->len = payload_len; -spin_lock_bh (&tp_vars->unacked_lock);/* if the list is empty immediately attach this new object */ if (list_empty (&tp_vars->unacked_list)) {list_add (&new->list, &tp_vars->unacked_list); tp_vars->unacked_count++; - goto out; +return true; }/* otherwise loop over the list and either drop the packet because this
@@ -1364,9 +1364,6 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars, tp_vars->unacked_count--; } -out: -spin_unlock_bh (&tp_vars->unacked_lock); -return true; }
@@ -1376,6 +1373,7 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars,* @tp_vars: the private data of the current TP meter session */ static void batadv_tp_ack_unordered (struct batadv_tp_vars *tp_vars) + __must_hold(&tp_vars->unacked_lock) {struct batadv_tp_unacked *un, *safe;u32 to_ack;
@@ -1383,7 +1381,6 @@ static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)/* go through the unacked packet list and possibly ACK them as * well */ -spin_lock_bh (&tp_vars->unacked_lock);list_for_each_entry_safe (un, safe, &tp_vars->unacked_list, list) {/* the list is ordered, therefore it is possible to stop as soon * there is a gap between the last acked seqno and the seqno of
@@ -1401,7 +1398,6 @@ static void batadv_tp_ack_unordered(struct batadv_tp_vars *tp_vars)kfree (un); tp_vars->unacked_count--; } -spin_unlock_bh (&tp_vars->unacked_lock); }/**
@@ -1481,6 +1477,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,const struct batadv_icmp_tp_packet *icmp;struct batadv_tp_vars *tp_vars;size_t packet_size; +u32 to_ack;u32 seqno; icmp = (struct batadv_icmp_tp_packet *)skb->data;
@@ -1509,6 +1506,8 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,WRITE_ONCE (tp_vars->last_recv_time, jiffies); } +spin_lock_bh (&tp_vars->unacked_lock); +/* if the packet is a duplicate, it may be the case that an ACK has been * lost. Resend the ACK */
@@ -1520,8 +1519,10 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,/* exit immediately (and do not send any ACK) if the packet has * not been enqueued correctly */ -if (!batadv_tp_handle_out_of_order (tp_vars, skb)) +if (!batadv_tp_handle_out_of_order (tp_vars, skb)) { +spin_unlock_bh (&tp_vars->unacked_lock); goto out; + }/* send a duplicate ACK */ goto send_ack;
@@ -1535,11 +1536,14 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,batadv_tp_ack_unordered (tp_vars); send_ack: + to_ack = tp_vars->last_recv; +spin_unlock_bh (&tp_vars->unacked_lock); +/* send the ACK. If the received packet was out of order, the ACK that * is going to be sent is a duplicate (the sender will count them and * possibly enter Fast Retransmit as soon as it has reached 3) */ -batadv_tp_send_ack (bat_priv, icmp->orig, tp_vars->last_recv, +batadv_tp_send_ack (bat_priv, icmp->orig, to_ack, icmp->timestamp, icmp->session, icmp->uid); out:batadv_tp_vars_put (tp_vars);
net/batman-adv/types.h +1 -1
@@ -1491,7 +1491,7 @@ struct batadv_tp_vars {/** @unacked_list: list of unacked packets (meta-info only) */ struct list_head unacked_list; -/** @unacked_lock: protect unacked_list */ +/** @unacked_lock: protect unacked_list + &batadv_tp_receiver.last_recv */ spinlock_t unacked_lock;/** @unacked_count: number of unacked entries */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 47/95 batman-adv: tp_meter: handle overlapping packets
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit cbde75c38b21f022891525078622587ad557b7c1 upstream.
If the size of the packets would change during the transmission, it could happen that some retries of packets are overlapping. In this case, precise comparisons of sequence numbers by the receiver would be wrong. It is then necessary to check if the start sequence number to the end sequence number ("seqno + length") would contain a new range.
If this is the case then this is enough to accept this packet. In all other cases, the packet still has to be dropped (and not acked).
--- net/batman-adv/tp_meter.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
net/batman-adv/tp_meter.c +11 -14
@@ -1284,7 +1284,8 @@ static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,/** * batadv_tp_handle_out_of_order() - store an out of order packet * @tp_vars: the private data of the current TP meter session -* @skb: the buffer containing the received packet +* @seqno: sequence number of new received packet +* @payload_len: length of the received packet * * Store the out of order packet in the unacked list for late processing. This * packets are kept in this list so that they can be ACKed at once as soon as
@@ -1293,22 +1294,17 @@ static int batadv_tp_send_ack(struct batadv_priv *bat_priv, const u8 *dst,* Return: true if the packed has been successfully processed, false otherwise */ static bool batadv_tp_handle_out_of_order (struct batadv_tp_vars *tp_vars, -const struct sk_buff *skb) +u32 seqno,u32 payload_len) __must_hold(&tp_vars->unacked_lock) { -const struct batadv_icmp_tp_packet *icmp;struct batadv_tp_unacked *un, *new; -u32 payload_len;bool added = false; new =kmalloc (sizeof (*new),GFP_ATOMIC );if (unlikely (!new))return false; - icmp = (struct batadv_icmp_tp_packet *)skb->data; - - new->seqno =ntohl (icmp->seqno); - payload_len = skb->len -sizeof (struct batadv_unicast_packet ); + new->seqno = seqno; new->len = payload_len;/* if the list is empty immediately attach this new object */
@@ -1476,7 +1472,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, {const struct batadv_icmp_tp_packet *icmp;struct batadv_tp_vars *tp_vars; -size_t packet_size; +u32 payload_len;u32 to_ack;u32 seqno;
@@ -1511,15 +1507,17 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv,/* if the packet is a duplicate, it may be the case that an ACK has been * lost. Resend the ACK */ -if (batadv_seq_before (seqno, tp_vars->last_recv)) + payload_len = skb->len -sizeof (struct batadv_unicast_packet ); + to_ack = seqno + payload_len; +if (batadv_seq_before (to_ack, tp_vars->last_recv)) goto send_ack;/* if the packet is out of order enqueue it */ -if (ntohl (icmp->seqno) != tp_vars->last_recv) { +if (batadv_seq_before (tp_vars->last_recv, seqno)) {/* exit immediately (and do not send any ACK) if the packet has * not been enqueued correctly */ -if (!batadv_tp_handle_out_of_order (tp_vars, skb)) { +if (!batadv_tp_handle_out_of_order (tp_vars, seqno, payload_len)) {spin_unlock_bh (&tp_vars->unacked_lock); goto out; }
@@ -1529,8 +1527,7 @@ static void batadv_tp_recv_msg(struct batadv_priv *bat_priv, }/* if everything was fine count the ACKed bytes */ - packet_size = skb->len -sizeof (struct batadv_unicast_packet ); - tp_vars->last_recv += packet_size; + tp_vars->last_recv = to_ack;/* check if this ordered message filled a gap.... */ batadv_tp_ack_unordered (tp_vars);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 48/95 batman-adv: tt: dont merge change entries with different VIDs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit f08e06c2d5c3e2434e7c773f2213f4a7dce6bc1e upstream.
batadv_tt_local_event() merges/cancels events for the same client which would conflict or be duplicates. The matching of the queued events only compares the MAC address - the VLAN ID stored in each event is ignored.
If a MAC would now appear on multiple VID, the two ADD change events (for VID 1 and VID 2) would be merged to a single vid event. The remote can therefore not calculate the correct TT table and desync. A full translation table exchange is required to recover from this state.
A check of VID is therefore necessary to avoid such wrong merges/cancels.
--- net/batman-adv/translation-table.c | 3 +++ 1 file changed, 3 insertions(+)
net/batman-adv/translation-table.c +3 -0
@@ -485,6 +485,9 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,if (!batadv_compare_eth (entry->change.addr, common->addr))continue ; +if (entry->change.vid != tt_change_node->change.vid) +continue ; +/* DEL+ADD in the same orig interval have no effect and can be * removed to avoid silly behaviour on the receiver side. The * other way around (ADD+DEL) can happen in case of roaming of
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 49/95 batman-adv: tt: track roam count per VID
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 12407d5f61c2653a64f2ff4b22f3c267f8420ef1 upstream.
batadv_tt_check_roam_count() is supposed to track roaming of a TT entry. But TT entries are for a MAC + VID. The VID was completely missed and thus leads to incorrect detection of ROAM counts when a client MAC exists in multiple VLANs.
--- net/batman-adv/translation-table.c | 9 +++++++-- net/batman-adv/types.h | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-)
net/batman-adv/translation-table.c +7 -2
@@ -3517,6 +3517,7 @@ static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)* batadv_tt_check_roam_count() - check if a client has roamed too frequently * @bat_priv: the bat priv with all the soft interface information * @client: mac address of the roaming client +* @vid: VLAN identifier * * This function checks whether the client already reached the * maximum number of possible roaming phases. In this case the ROAMING_ADV
@@ -3524,7 +3525,7 @@ static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)* * Return: true if the ROAMING_ADV can be sent, false otherwise */ -static bool batadv_tt_check_roam_count (struct batadv_priv *bat_priv,u8 *client) +static bool batadv_tt_check_roam_count (struct batadv_priv *bat_priv,u8 *client,u16 vid) {struct batadv_tt_roam_node *tt_roam_node;bool ret = false;
@@ -3537,6 +3538,9 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, u8 *client)if (!batadv_compare_eth (tt_roam_node->addr, client))continue ; +if (tt_roam_node->vid != vid) +continue ; +if (batadv_has_timed_out (tt_roam_node->first_time,BATADV_ROAMING_MAX_TIME ))continue ;
@@ -3558,6 +3562,7 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv, u8 *client)atomic_set (&tt_roam_node->counter,BATADV_ROAMING_MAX_COUNT -1 );ether_addr_copy (tt_roam_node->addr, client); + tt_roam_node->vid = vid;list_add (&tt_roam_node->list, &bat_priv->tt.roam_list); ret = true;
@@ -3594,7 +3599,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, u8 *client,/* before going on we have to check whether the client has * already roamed to us too many times */ -if (!batadv_tt_check_roam_count (bat_priv, client)) +if (!batadv_tt_check_roam_count (bat_priv, client, vid)) goto out; batadv_dbg(BATADV_DBG_TT, bat_priv,
net/batman-adv/types.h +3 -0
@@ -2034,6 +2034,9 @@ struct batadv_tt_roam_node {/** @addr: mac address of the client in the roaming phase */ u8 addr[ETH_ALEN ]; +/** @vid: VLAN identifier */ +u16 vid; +/** * @counter: number of allowed roaming events per client within a single * OGM interval (changes are committed with each OGM)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 50/95 batman-adv: dat: prevent false sharing between VLANs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 20d7658b74169f86d4ac01b9185b3eadddf71f28 upstream.
The local hash of DAT entries is supposed to be VLAN (VID) aware. But the adding to the hash and the search in the hash were not checking the VID information of the hash entries. The entries would therefore only be correctly separated when batadv_hash_dat() didn't select the same buckets for different VIDs.
--- net/batman-adv/distributed-arp-table.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
net/batman-adv/distributed-arp-table.c +9 -3
@@ -215,10 +215,13 @@ static void batadv_dat_purge(struct work_struct *work)*/ static bool batadv_compare_dat (const struct hlist_node *node,const void *data2) { - const void *data1 = container_of(node, struct batadv_dat_entry, - hash_entry); +const struct batadv_dat_entry *entry1; +const struct batadv_dat_entry *entry2; -return memcmp (data1, data2,sizeof (__be32)) ==0 ; + entry1 = container_of(node, struct batadv_dat_entry, hash_entry); + entry2 = data2; + +return entry1->ip == entry2->ip && entry1->vid == entry2->vid; }/**
@@ -345,6 +348,9 @@ batadv_dat_entry_hash_find(struct batadv_priv *bat_priv, __be32 ip,if (dat_entry->ip != ip)continue ; +if (dat_entry->vid != vid) +continue ; +if (!kref_get_unless_zero (&dat_entry->refcount))continue ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 51/95 batman-adv: tvlv: enforce 2-byte alignment
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 32a6799255525d6ea4da0f7e9e0e521ad9560a46 upstream.
The fields of an aggregated OGM(v2) are accessed assuming (at least) 2-byte alignment, so a following OGM must start at an even offset. As the header length is even, an odd tvlv_len would misalign it and trigger unaligned accesses on strict-alignment architectures.
Such a misaligned TVLV/OGM/OGMv2 is not created by a normal participant in the mesh. Therefore, reject such malformed packets.
--- net/batman-adv/bat_iv_ogm.c | 11 ++++++++++- net/batman-adv/bat_v_ogm.c | 11 ++++++++++- net/batman-adv/tvlv.c | 6 ++++++ 3 files changed, 26 insertions(+), 2 deletions(-)
net/batman-adv/bat_iv_ogm.c +10 -1
@@ -311,14 +311,23 @@ batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, const struct batadv_ogm_packet *ogm_packet) {int next_buff_pos =0 ; +u16 tvlv_len;/* check if there is enough space for the header */ next_buff_pos += buff_pos +sizeof (*ogm_packet);if (next_buff_pos > packet_len)return false; + tvlv_len =ntohs (ogm_packet->tvlv_len); + +/* the fields of an aggregated OGM are accessed assuming (at least) +* 2-byte alignment, so a following OGM must start at an even offset. +*/ +if (tvlv_len &1 ) +return false; +/* check if there is enough space for the optional TVLV */ - next_buff_pos +=ntohs (ogm_packet->tvlv_len); + next_buff_pos += tvlv_len;return next_buff_pos <= packet_len; }
net/batman-adv/bat_v_ogm.c +10 -1
@@ -854,14 +854,23 @@ batadv_v_ogm_aggr_packet(int buff_pos, int packet_len, const struct batadv_ogm2_packet *ogm2_packet) {int next_buff_pos =0 ; +u16 tvlv_len;/* check if there is enough space for the header */ next_buff_pos += buff_pos +sizeof (*ogm2_packet);if (next_buff_pos > packet_len)return false; + tvlv_len =ntohs (ogm2_packet->tvlv_len); + +/* the fields of an aggregated OGMv2 are accessed assuming (at least) +* 2-byte alignment, so a following OGMv2 must start at an even offset. +*/ +if (tvlv_len &1 ) +return false; +/* check if there is enough space for the optional TVLV */ - next_buff_pos +=ntohs (ogm2_packet->tvlv_len); + next_buff_pos += tvlv_len;return next_buff_pos <= packet_len; }
net/batman-adv/tvlv.c +6 -0
@@ -448,6 +448,12 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,if (tvlv_value_cont_len > tvlv_value_len)break ; +/* the next tvlv header is accessed assuming (at least) 2-byte +* alignment, so it must start at an even offset. +*/ +if (tvlv_value_cont_len &1 ) +break ; + tvlv_handler =batadv_tvlv_handler_get (bat_priv, tvlv_hdr->type, tvlv_hdr->version);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 52/95 batman-adv: tvlv: avoid race of cifsnotfound handler state
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit edb557b2ba38fea2c5eb710cf366c797e187218c upstream.
TVLV handlers can have the flag BATADV_TVLV_HANDLER_OGM_CIFNOTFND set to signal that the OGM handler should be called (with NULL for data) when the specific TVLV container was not found in the OGM. This is used by:
* DAT
* GW
* Multicast (OGM + Tracker)
The state whether the handler was executed was stored in the struct batadv_tvlv_handler. But the TVLV processing is started without any lock. Multiple parallel contexts processing TVLVs would therefore overwrite each others BATADV_TVLV_HANDLER_OGM_CALLED flag in the shared batadv_tvlv_handler.
Drop the shared BATADV_TVLV_HANDLER_OGM_CALLED flag and instead determine, per TVLV buffer, whether a matching container was present by scanning the packet's buffer.
--- net/batman-adv/tvlv.c | 63 ++++++++++++++++++++++++++++++++++++++---- net/batman-adv/types.h | 7 ----- 2 files changed, 57 insertions(+), 13 deletions(-)
net/batman-adv/tvlv.c +57 -6
@@ -394,7 +394,6 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv, tvlv_handler->ogm_handler (bat_priv, orig_node,BATADV_NO_FLAGS , tvlv_value, tvlv_value_len); - tvlv_handler->flags |=BATADV_TVLV_HANDLER_OGM_CALLED ; }else {if (!src)return NET_RX_SUCCESS ;
@@ -413,6 +412,48 @@ static int batadv_tvlv_call_handler(struct batadv_priv *bat_priv,return NET_RX_SUCCESS ; } +/** +* batadv_tvlv_containers_contain() - check if a tvlv buffer holds a container +* @tvlv_value: tvlv content +* @tvlv_value_len: tvlv content length +* @type: tvlv container type to look for +* @version: tvlv container version to look for +* +* Return: true if a container of the given type and version is present in the +* tvlv buffer, false otherwise. +*/ +static bool batadv_tvlv_containers_contain (void *tvlv_value, +u16 tvlv_value_len,u8 type, +u8 version) +{ +struct batadv_tvlv_hdr *tvlv_hdr; +u16 tvlv_value_cont_len; + +while (tvlv_value_len >=sizeof (*tvlv_hdr)) { + tvlv_hdr = tvlv_value; + tvlv_value_cont_len =ntohs (tvlv_hdr->len); + tvlv_value = tvlv_hdr +1 ; + tvlv_value_len -=sizeof (*tvlv_hdr); + +if (tvlv_value_cont_len > tvlv_value_len) +break ; + +/* the next tvlv header is accessed assuming (at least) 2-byte +* alignment, so it must start at an even offset. +*/ +if (tvlv_value_cont_len &1 ) +break ; + +if (tvlv_hdr->type == type && tvlv_hdr->version == version) +return true; + + tvlv_value = (u8 *)tvlv_value + tvlv_value_cont_len; + tvlv_value_len -= tvlv_value_cont_len; + } + +return false; +} +/** * batadv_tvlv_containers_process() - parse the given tvlv buffer to call the * appropriate handlers
@@ -433,7 +474,9 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv, u8 *src, u8 *dst, void *tvlv_value, u16 tvlv_value_len) { +u16 tvlv_value_start_len = tvlv_value_len;struct batadv_tvlv_handler *tvlv_handler; +void *tvlv_value_start = tvlv_value;struct batadv_tvlv_hdr *tvlv_hdr;u16 tvlv_value_cont_len;u8 cifnotfound =BATADV_TVLV_HANDLER_OGM_CIFNOTFND ;
@@ -473,12 +516,20 @@ int batadv_tvlv_containers_process(struct batadv_priv *bat_priv,rcu_read_lock ();hlist_for_each_entry_rcu (tvlv_handler, &bat_priv->tvlv.handler_list, list) { -if ((tvlv_handler->flags &BATADV_TVLV_HANDLER_OGM_CIFNOTFND ) && - !(tvlv_handler->flags &BATADV_TVLV_HANDLER_OGM_CALLED )) - tvlv_handler->ogm_handler (bat_priv, orig_node, - cifnotfound,NULL ,0 ); +if (!(tvlv_handler->flags &BATADV_TVLV_HANDLER_OGM_CIFNOTFND )) +continue ; - tvlv_handler->flags &= ~BATADV_TVLV_HANDLER_OGM_CALLED ; +/* if the corresponding container was present then the handler +* was already called from the loop above +*/ +if (batadv_tvlv_containers_contain (tvlv_value_start, + tvlv_value_start_len, + tvlv_handler->type, + tvlv_handler->version)) +continue ; + + tvlv_handler->ogm_handler (bat_priv, orig_node, + cifnotfound,NULL ,0 ); }rcu_read_unlock ();
net/batman-adv/types.h +0 -7
@@ -2447,13 +2447,6 @@ enum batadv_tvlv_handler_flags {* will call this handler even if its type was not found (with no data) */ BATADV_TVLV_HANDLER_OGM_CIFNOTFND = BIT(1), - -/** -* @BATADV_TVLV_HANDLER_OGM_CALLED: interval tvlv handling flag - the -* API marks a handler as being called, so it won't be called if the -* BATADV_TVLV_HANDLER_OGM_CIFNOTFND flag was set -*/ - BATADV_TVLV_HANDLER_OGM_CALLED = BIT(2), };#endif /* _NET_BATMAN_ADV_TYPES_H_ */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 53/95 ring-buffer: Remove ring_buffer_read_prepare_sync()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjoern Doebel <[email protected]>
[ Upstream commit 119a5d573622ae90ba730d18acfae9bb75d77b9a ]
When the ring buffer was first introduced, reading the non-consuming "trace" file required disabling the writing of the ring buffer. To make sure the writing was fully disabled before iterating the buffer with a non-consuming read, it would set the disable flag of the buffer and then call an RCU synchronization to make sure all the buffers were synchronized.
The function ring_buffer_read_start() originally would initialize the iterator and call an RCU synchronization, but this was for each individual per CPU buffer where this would get called many times on a machine with many CPUs before the trace file could be read. The commit 72c9ddfd4c5bf ("ring-buffer: Make non-consuming read less expensive with lots of cpus.") separated ring_buffer_read_start into ring_buffer_read_prepare(), ring_buffer_read_sync() and then ring_buffer_read_start() to allow each of the per CPU buffers to be prepared, call the read_buffer_read_sync() once, and then the ring_buffer_read_start() for each of the CPUs which made things much faster.
The commit 1039221cc278 ("ring-buffer: Do not disable recording when there is an iterator") removed the requirement of disabling the recording of the ring buffer in order to iterate it, but it did not remove the synchronization that was happening that was required to wait for all the buffers to have no more writers. It's now OK for the buffers to have writers and no synchronization is needed.
Remove the synchronization and put back the interface for the ring buffer iterator back before commit 72c9ddfd4c5bf was applied.
[[email protected]: move patch section using guard() macro into a separate block to address declaration after statement warning.]
--- include/linux/ring_buffer.h | 4 +-- kernel/trace/ring_buffer.c | 72 ++++++++----------------------------- kernel/trace/trace.c | 14 +++----- kernel/trace/trace_kdb.c | 8 ++--- 4 files changed, 22 insertions(+), 76 deletions(-)
include/linux/ring_buffer.h +1 -3
@@ -130,9 +130,7 @@ ring_buffer_consume(struct trace_buffer *buffer, int cpu, u64 *ts, unsigned long *lost_events);struct ring_buffer_iter * -ring_buffer_read_prepare (struct trace_buffer *buffer,int cpu,gfp_t flags); -void ring_buffer_read_prepare_sync (void ); -void ring_buffer_read_start (struct ring_buffer_iter *iter); +ring_buffer_read_start (struct trace_buffer *buffer,int cpu,gfp_t flags);void ring_buffer_read_finish (struct ring_buffer_iter *iter); struct ring_buffer_event *
kernel/trace/ring_buffer.c +14 -58
93 lines not on this page · raw message
kernel/trace/trace.c +4 -10
@@ -4803,21 +4803,15 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)if (iter->cpu_file ==RING_BUFFER_ALL_CPUS ) {for_each_tracing_cpu (cpu) { iter->buffer_iter[cpu] = -ring_buffer_read_prepare (iter->array_buffer->buffer, - cpu,GFP_KERNEL ); - } -ring_buffer_read_prepare_sync (); -for_each_tracing_cpu (cpu) { -ring_buffer_read_start (iter->buffer_iter[cpu]); +ring_buffer_read_start (iter->array_buffer->buffer, + cpu,GFP_KERNEL );tracing_iter_reset (iter, cpu); } }else { cpu = iter->cpu_file; iter->buffer_iter[cpu] = -ring_buffer_read_prepare (iter->array_buffer->buffer, - cpu,GFP_KERNEL ); -ring_buffer_read_prepare_sync (); -ring_buffer_read_start (iter->buffer_iter[cpu]); +ring_buffer_read_start (iter->array_buffer->buffer, + cpu,GFP_KERNEL );tracing_iter_reset (iter, cpu); }
kernel/trace/trace_kdb.c +3 -5
@@ -43,17 +43,15 @@ static void ftrace_dump_buf(int skip_entries, long cpu_file)if (cpu_file ==RING_BUFFER_ALL_CPUS ) {for_each_tracing_cpu (cpu) { iter.buffer_iter[cpu] = -ring_buffer_read_prepare (iter.array_buffer->buffer, - cpu,GFP_ATOMIC ); -ring_buffer_read_start (iter.buffer_iter[cpu]); +ring_buffer_read_start (iter.array_buffer->buffer, + cpu,GFP_ATOMIC );tracing_iter_reset (&iter, cpu); } }else { iter.cpu_file = cpu_file; iter.buffer_iter[cpu_file] = -ring_buffer_read_prepare (iter.array_buffer->buffer, +ring_buffer_read_start (iter.array_buffer->buffer, cpu_file,GFP_ATOMIC ); -ring_buffer_read_start (iter.buffer_iter[cpu_file]);tracing_iter_reset (&iter, cpu_file); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 54/95 ntfs3: reject direct userspace writes to reserved $LX* xattrs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Komarov <[email protected]>
commit 5b08dccecf825cbf905f348bc6ccb497507e28e2 upstream.
NTFS3 uses $LXUID, $LXGID, $LXMOD and $LXDEV as internal WSL permission metadata and reloads them into i_uid, i_gid and i_mode from ntfs_get_wsl_perm().
Because the empty-prefix xattr handler also lets file owners call setxattr() on these names directly, an unprivileged writer on a writable ntfs3 mount can plant root ownership and S_ISUID on their own file and gain euid 0 after inode reload.
Reject direct userspace writes to the reserved $LX* names. Internal ntfs3 metadata updates are unchanged because ntfs_save_wsl_perm() writes them via ntfs_set_ea() directly.
--- fs/ntfs3/xattr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
fs/ntfs3/xattr.c +12 -0
@@ -844,6 +844,12 @@ out:return err; } +static bool ntfs_is_reserved_lxattr (const char *name) +{ +return !strcmp (name,"$LXUID" ) || !strcmp (name,"$LXGID" ) || + !strcmp (name,"$LXMOD" ) || !strcmp (name,"$LXDEV" ); +} +/* * ntfs_setxattr - inode_operations::setxattr */
@@ -949,6 +955,12 @@ set_new_fa: goto out; } +/* Do not allow non privileged users to change $LXUID/$LXGID... */ +if (ntfs_is_reserved_lxattr (name) && !capable (CAP_SYS_ADMIN )) { + err = -EPERM ; + goto out; + } +/* Deal with NTFS extended attribute. */ err =ntfs_set_ea (inode, name, name_len, value, size, flags);
Greg Kroah-Hartman
maintainerPATCH 55/95 ext4: add bounds check for inline data length in ext4_read_inline_page
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuto Ohnuki <[email protected]>
[ Upstream commit 356227096eb66e41b23caf7045e6304877322edf ]
ext4_read_inline_page() does not validate that the inline data length fits within a page before copying data. If the inline size exceeds PAGE_SIZE due to filesystem corruption, this could lead to a kernel memory write beyond the page boundary.
Add a bounds check after computing len, returning -EFSCORRUPTED if the value exceeds PAGE_SIZE.
The upstream commit replaced a BUG_ON(len > PAGE_SIZE) in ext4_read_inline_folio(). In 6.1 and earlier, the function is still named ext4_read_inline_page() and the BUG_ON was never present, so this patch adds the bounds check directly.
--- fs/ext4/inline.c | 8 ++++++++ 1 file changed, 8 insertions(+)
fs/ext4/inline.c +8 -0
@@ -517,6 +517,14 @@ static int ext4_read_inline_page(struct inode *inode, struct page *page) goto out; len =min_t (size_t,ext4_get_inline_size (inode),i_size_read (inode)); +if (len >PAGE_SIZE ) { +ext4_error_inode (inode, __func__, __LINE__,0 , +"inline size %zu exceeds PAGE_SIZE" , len); + ret = -EFSCORRUPTED ; +brelse (iloc.bh); + goto out; + } + kaddr =kmap_atomic (page); ret =ext4_read_inline_data (inode, kaddr, len, &iloc);flush_dcache_page (page);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 56/95 crypto: af_alg - Set merge to zero early in af_alg_sendmsg
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
commit 9574b2330dbd2b5459b74d3b5e9619d39299fc6f upstream.
If an error causes af_alg_sendmsg to abort, ctx->merge may contain a garbage value from the previous loop. This may then trigger a crash on the next entry into af_alg_sendmsg when it attempts to do a merge that can't be done.
Fix this by setting ctx->merge to zero near the start of the loop.
--- crypto/af_alg.c | 2 ++ 1 file changed, 2 insertions(+)
crypto/af_alg.c +2 -0
@@ -892,6 +892,8 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,continue ; } + ctx->merge =0 ; +if (!af_alg_writable (sk)) { err =af_alg_wait_for_wmem (sk, msg->msg_flags);if (err)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 57/95 mac802154: llsec: add skb_cow_data() before in-place crypto
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <[email protected]>
commit 84a04eb5b210643bd67aab81ff805d32f62aa865 upstream.
llsec_do_encrypt_unauth(), llsec_do_encrypt_auth(), llsec_do_decrypt_unauth(), and llsec_do_decrypt_auth() all perform in-place cryptographic transformations on skb data. They build a scatterlist with sg_init_one() pointing into the skb's linear data area and then pass the same scatterlist as both src and dst to the crypto API (e.g. crypto_skcipher_encrypt/decrypt, crypto_aead_encrypt/decrypt).
On the RX path, __ieee802154_rx_handle_packet() clones the received skb before handing it to each subscriber via ieee802154_subif_frame(). The cloned skb shares the same underlying data buffer via reference counting. When llsec_do_decrypt() subsequently modifies this shared buffer in place, it corrupts data that other clones -- potentially belonging to other sockets or subsystems -- still reference.
On the TX path, similar data sharing can occur when an skb's head has been cloned (skb_cloned() returns true).
The fix is to call skb_cow_data() before performing any in-place crypto operation. skb_cow_data() ensures that the skb's data area is not
shared: if the skb head is cloned or the data spans multiple fragments, it copies the data into a private buffer that can be safely modified in place. This is the same pattern used by:
- ESP (net/ipv4/esp4.c, net/ipv6/esp6.c)
- MACsec (drivers/net/macsec.c)
- WireGuard (drivers/net/wireguard/receive.c)
- TIPC (net/tipc/crypto.c)
Without this guard, in-place crypto on shared skb data leads to:
- Silent data corruption of other skb clones
- Use-after-free when the crypto API scatterwalk writes through a page that has already been freed by another clone's kfree_skb()
- Kernel crashes under concurrent 802.15.4 traffic with security enabled (KASAN/KMSAN reports slab-use-after-free)
Found by 0sec (https://0sec.ai) using automated source analysis.
--- net/mac802154/llsec.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
net/mac802154/llsec.c +14 -0
@@ -710,6 +710,7 @@ int mac802154_llsec_encrypt(struct mac80 {struct ieee802154_hdr hdr;int rc, authlen, hlen; +struct sk_buff *trailer;struct mac802154_llsec_key *key;u32 frame_ctr;
@@ -766,6 +767,12 @@ int mac802154_llsec_encrypt(struct mac80 skb->mac_len =ieee802154_hdr_push (skb, &hdr);skb_reset_mac_header (skb); + rc =skb_cow_data (skb,0 , &trailer); +if (rc <0 ) { +llsec_key_put (key); +return rc; + } + rc =llsec_do_encrypt (skb, sec, &hdr, key);llsec_key_put (key);
@@ -905,6 +912,13 @@ llsec_do_decrypt(struct sk_buff *skb, coconst struct ieee802154_hdr *hdr, struct mac802154_llsec_key *key, __le64 dev_addr) { + struct sk_buff *trailer; +int err; + + err =skb_cow_data (skb,0 , &trailer); +if (err <0 ) +return err; +if (hdr->sec.level ==IEEE802154_SCF_SECLEVEL_ENC )return llsec_do_decrypt_unauth (skb, sec, hdr, key, dev_addr);else
Greg Kroah-Hartman
maintainerPATCH 58/95 KEYS: fix overflow in keyctl_pkey_params_get_2()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <[email protected]>
commit cb481e59ea6cae3b7796ac1d7a22b6b24c3f3c0b upstream.
The length for the internal output buffer is calculated incorrectly, which can result overflow when a too small buffer is provided.
Fix the bug by allocating internal output with the size of the maximum length of the cryptographic primitive instead of caller provided size.
--- security/keys/keyctl_pkey.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
security/keys/keyctl_pkey.c +8 -1
@@ -138,28 +138,35 @@ static int keyctl_pkey_params_get_2(consif (uparams.in_len > info.max_dec_size || uparams.out_len > info.max_enc_size)return -EINVAL ; + + params->out_len = info.max_enc_size;break ;case KEYCTL_PKEY_DECRYPT :if (uparams.in_len > info.max_enc_size || uparams.out_len > info.max_dec_size)return -EINVAL ; + + params->out_len = info.max_dec_size;break ;case KEYCTL_PKEY_SIGN :if (uparams.in_len > info.max_data_size || uparams.out_len > info.max_sig_size)return -EINVAL ; + + params->out_len = info.max_sig_size;break ;case KEYCTL_PKEY_VERIFY :if (uparams.in_len > info.max_data_size || uparams.in2_len > info.max_sig_size)return -EINVAL ; + + params->out_len = info.max_sig_size;break ;default :BUG (); } params->in_len = uparams.in_len; - params->out_len = uparams.out_len;/* Note: same as in2_len */ return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 59/95 keys: Pin request_key_auth payload in instantiate paths
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shaomin Chen <[email protected]>
commit fd15b457a86939c38aa12116adabd8ff686c5e51 upstream.
A: request_key() B: KEYCTL_INSTANTIATE_IOV
================ =========================
create auth key
store rka in auth key
wait for helper
get auth key
load rka from auth key
copy user payload
sleep on #PF
helper completed
detach and free rka
destroy auth key
wake up
use rka->target_key
**USE-AFTER-FREE**Give request_key_auth payloads a refcount. Take a payload reference while authkey->sem stabilizes the payload and revocation state. Hold that reference across the instantiate and reject paths. Drop the auth key owning reference from revoke and destroy.
[jarkko: Replaced the first two paragraphs of text with an actual
concurrency scenario.]
--- include/keys/request_key_auth-type.h | 2 ++ security/keys/internal.h | 2 ++ security/keys/keyctl.c | 24 ++++++++++++++++++------ security/keys/request_key_auth.c | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 8 deletions(-)
include/keys/request_key_auth-type.h +2 -0
@@ -9,12 +9,14 @@#define _KEYS_REQUEST_KEY_AUTH_TYPE_H#include <linux/key.h> +#include <linux/refcount.h> /* * Authorisation record for request_key(). */ struct request_key_auth {struct rcu_head rcu; +refcount_t usage;struct key *target_key;struct key *dest_keyring;const struct cred *cred;
security/keys/internal.h +2 -0
@@ -217,6 +217,8 @@ extern struct key *request_key_auth_new(const void *callout_info, size_t callout_len, struct key *dest_keyring); +struct request_key_auth *request_key_auth_get (struct key *authkey); +void request_key_auth_put (struct request_key_auth *rka);extern struct key *key_get_instantiation_authkey (key_serial_t target_id);
security/keys/keyctl.c +18 -6
@@ -1196,9 +1196,13 @@ static long keyctl_instantiate_key_commoif (!instkey) goto error; - rka = instkey->payload.data[0 ]; -if (rka->target_key->serial != id) + rka =request_key_auth_get (instkey); +if (!rka) { + ret = -EKEYREVOKED ; goto error; + } +if (rka->target_key->serial != id) + goto error_put_rka;/* pull the payload in if one was supplied */ payload =NULL ;
@@ -1207,7 +1211,7 @@ static long keyctl_instantiate_key_commo ret = -ENOMEM ; payload =kvmalloc (plen,GFP_KERNEL );if (!payload) - goto error; + goto error_put_rka; ret = -EFAULT ;if (!copy_from_iter_full (payload, plen, from))
@@ -1233,6 +1237,8 @@ static long keyctl_instantiate_key_commo error2:kvfree_sensitive (payload, plen); +error_put_rka: +request_key_auth_put (rka); error:return ret; }
@@ -1358,15 +1364,19 @@ long keyctl_reject_key(key_serial_t id,if (!instkey) goto error; - rka = instkey->payload.data[0 ]; -if (rka->target_key->serial != id) + rka =request_key_auth_get (instkey); +if (!rka) { + ret = -EKEYREVOKED ; goto error; + } +if (rka->target_key->serial != id) + goto error_put_rka;/* find the destination keyring if present (which must also be * writable) */ ret =get_instantiation_keyring (ringid, rka, &dest_keyring);if (ret <0 ) - goto error; + goto error_put_rka;/* instantiate the key and link it into a keyring */ ret = key_reject_and_link(rka->target_key, timeout, error,
@@ -1379,6 +1389,8 @@ long keyctl_reject_key(key_serial_t id,if (ret ==0 )keyctl_change_reqkey_auth (NULL ); +error_put_rka: +request_key_auth_put (rka); error:return ret; }
security/keys/request_key_auth.c +31 -2
@@ -23,6 +23,7 @@ static void request_key_auth_describe(costatic void request_key_auth_revoke (struct key *);static void request_key_auth_destroy (struct key *);static long request_key_auth_read (const struct key *,char *,size_t ); +static void request_key_auth_rcu_disposal (struct rcu_head *);/* * The request-key authorisation key type definition.
@@ -116,6 +117,31 @@ static void free_request_key_auth(struct }/* +* Take a reference to the request-key authorisation payload so callers can +* drop authkey->sem before doing operations that may sleep. +*/ +struct request_key_auth *request_key_auth_get (struct key *authkey) +{ +struct request_key_auth *rka; + +down_read (&authkey->sem); + rka =dereference_key_locked (authkey); +if (rka && !test_bit (KEY_FLAG_REVOKED , &authkey->flags)) +refcount_inc (&rka->usage); +else + rka =NULL ; +up_read (&authkey->sem); + +return rka; +} + +void request_key_auth_put (struct request_key_auth *rka) +{ +if (rka &&refcount_dec_and_test (&rka->usage)) +call_rcu (&rka->rcu, request_key_auth_rcu_disposal); +} + +/* * Dispose of the request_key_auth record under RCU conditions */ static void request_key_auth_rcu_disposal (struct rcu_head *rcu)
@@ -136,8 +162,10 @@ static void request_key_auth_revoke(strustruct request_key_auth *rka =dereference_key_locked (key);kenter ("{%d}" , key->serial); +if (!rka) +return ;rcu_assign_keypointer (key,NULL ); -call_rcu (&rka->rcu, request_key_auth_rcu_disposal); +request_key_auth_put (rka); }/*
@@ -150,7 +178,7 @@ static void request_key_auth_destroy(strkenter ("{%d}" , key->serial);if (rka) {rcu_assign_keypointer (key,NULL ); -call_rcu (&rka->rcu, request_key_auth_rcu_disposal); +request_key_auth_put (rka); } }
@@ -174,6 +202,7 @@ struct key *request_key_auth_new(struct rka =kzalloc (sizeof (*rka),GFP_KERNEL );if (!rka) goto error; +refcount_set (&rka->usage,1 ); rka->callout_info =kmemdup (callout_info, callout_len,GFP_KERNEL );if (!rka->callout_info) goto error_free_rka;
Greg Kroah-Hartman
maintainerPATCH 60/95 wifi: mt76: mt76x2u: Add support for ELECOM WDC-867SU3S
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zenm Chen <[email protected]>
commit f4ce0664e9f0387873b181777891741c33e19465 upstream.
Add the ID 056e:400a to the table to support an additional MT7612U
adapter: ELECOM WDC-867SU3S.
Compile tested only.
--- drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c +1 -0
@@ -16,6 +16,7 @@ static const struct usb_device_id mt76x2 { USB_DEVICE(0x0e8d, 0x7612) }, /* Aukey USBAC1200 - Alfa AWUS036ACM */ { USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */ { USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */ + { USB_DEVICE(0x056e, 0x400a) }, /* ELECOM WDC-867SU3S */ { USB_DEVICE(0x0e8d, 0x7632) }, /* HC-M7662BU1 */ { USB_DEVICE(0x0471, 0x2126) }, /* LiteOn WN4516R module, nonstandard USB connector */ { USB_DEVICE(0x0471, 0x7600) }, /* LiteOn WN4519R module, nonstandard USB connector */
Greg Kroah-Hartman
maintainerPATCH 61/95 wifi: ath11k: fix warning when unbinding
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Ignacio Tornos Martinez <[email protected]>
commit 8b7a26b6681922a38cd5a7829ace61f8e54df9b7 upstream.
If there is an error during some initialization related to firmware, the buffers dp->tx_ring[i].tx_status are released.
However this is released again when the device is unbinded (ath11k_pci), and we get:
WARNING: CPU: 0 PID: 6231 at mm/slub.c:4368 free_large_kmalloc+0x57/0x90 Call Trace:
free_large_kmallocath11k_dp_freeath11k_core_deinitath11k_pci_remove
...
The issue is always reproducible from a VM because the MSI addressing initialization is failing.
In order to fix the issue, just set the buffers to NULL after releasing in order to avoid the double free.
--- drivers/net/wireless/ath/ath11k/dp.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/ath/ath11k/dp.c +1 -0
@@ -1003,6 +1003,7 @@ void ath11k_dp_free(struct ath11k_base *idr_destroy (&dp->tx_ring[i].txbuf_idr);spin_unlock_bh (&dp->tx_ring[i].tx_idr_lock);kfree (dp->tx_ring[i].tx_status); + dp->tx_ring[i].tx_status =NULL ; }/* Deinit any SOC level resource */
Greg Kroah-Hartman
maintainerPATCH 62/95 wifi: rtlwifi: rtl8821ae: Fix C2H bit location in RX descriptor
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bitterblue Smith <[email protected]>
commit 83d38df6929118c3f996b9e3351c2d5014073d87 upstream.
Bit 28 of double word 2 in the RX descriptor indicates if the packet is a normal 802.11 frame, or a message from the wifi firmware to the driver (Card 2 Host).
Commit f5678bfe1cdc ("rtlwifi: rtl8821ae: Replace local bit manipulation macros") mistakenly made the driver look for this bit in double word 1, causing packet loss and Bluetooth coexistence problems.
--- drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h +1 -1
@@ -291,7 +291,7 @@ static inline int get_rx_desc_paggr(__lestatic inline int get_rx_status_desc_rpt_sel (__le32 *__pdesc) { -return le32_get_bits (*(__pdesc +1 ),BIT (28 )); +return le32_get_bits (*(__pdesc +2 ),BIT (28 )); }static inline int get_rx_desc_rxmcs (__le32 *__pdesc)
Greg Kroah-Hartman
maintainerPATCH 63/95 f2fs: validate ACL entry sizes in f2fs_acl_from_disk()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Cen <[email protected]>
commit c4810ada31e80cbe4011467c4f3b1e93f94134f3 upstream.
f2fs_acl_count() only validates the aggregate ACL xattr length. A malformed ACL can still place ACL_USER or ACL_GROUP in a slot that only contains struct f2fs_acl_entry_short bytes, and f2fs_acl_from_disk() then reads entry->e_id before verifying that a full entry fits.
Require a short entry before reading e_tag and e_perm, and require a full entry before reading e_id for ACL_USER and ACL_GROUP. Return -EFSCORRUPTED from these new truncated-entry checks, while keeping the pre-existing -EINVAL paths unchanged.
Validation reproduced this kernel report:
KASAN slab-out-of-bounds in __f2fs_get_acl+0x6fb/0x7e0
RIP: 0033:0x7f4b835ea7aa The buggy address belongs to the object at ffff888114589960 which belongs to the cache kmalloc-8 of size 8 The buggy address is located 0 bytes to the right of allocated 8-byte region [ffff888114589960, ffff888114589968) Read of size 4 Call trace: dump_stack_lvl+0x66/0xa0 (?:?) print_report+0xce/0x630 (?:?) __f2fs_get_acl+0x6fb/0x7e0 (fs/f2fs/acl.c:169) srso_alias_return_thunk+0x5/0xfbef5 (?:?) __virt_addr_valid+0x224/0x430 (?:?) kasan_report+0xe0/0x110 (?:?) __f2fs_get_acl+0x5/0x7e0 (fs/f2fs/acl.c:169) __get_acl+0x281/0x380 (?:?) vfs_get_acl+0x10b/0x190 (?:?) do_get_acl+0x2a/0x410 (?:?) do_get_acl+0x9/0x410 (?:?) do_getxattr+0xe8/0x260 (?:?) filename_getxattr+0xd1/0x140 (?:?) do_getname+0x2d/0x2d0 (?:?) path_getxattrat+0x16c/0x200 (?:?) lock_release+0xc8/0x290 (?:?) cgroup_update_frozen+0x9d/0x320 (?:?) lockdep_hardirqs_on_prepare+0xea/0x1a0 (?:?) trace_hardirqs_on+0x1a/0x170 (?:?) _raw_spin_unlock_irq+0x28/0x50 (?:?) do_syscall_64+0x115/0x6a0 (arch/x86/entry/syscall_64.c:87) entry_SYSCALL_64_after_hwframe+0x77/0x7f (?:?)
--- fs/f2fs/acl.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
fs/f2fs/acl.c +16 -2
@@ -46,6 +46,7 @@ static inline int f2fs_acl_count(size_tstatic struct posix_acl *f2fs_acl_from_disk (const char *value,size_t size) {int i, count; +int err = -EINVAL ;struct posix_acl *acl;struct f2fs_acl_header *hdr = (struct f2fs_acl_header *)value;struct f2fs_acl_entry *entry = (struct f2fs_acl_entry *)(hdr +1 );
@@ -69,8 +70,11 @@ static struct posix_acl *f2fs_acl_from_dfor (i =0 ; i < count; i++) { -if ((char *)entry > end) +if (unlikely ((char *)entry + +sizeof (struct f2fs_acl_entry_short ) > end)) { + err = -EFSCORRUPTED ; goto fail; + } acl->a_entries[i].e_tag =le16_to_cpu (entry->e_tag); acl->a_entries[i].e_perm =le16_to_cpu (entry->e_perm);
@@ -85,6 +89,11 @@ static struct posix_acl *f2fs_acl_from_dbreak ;case ACL_USER : +if (unlikely ((char *)entry + +sizeof (struct f2fs_acl_entry ) > end)) { + err = -EFSCORRUPTED ; + goto fail; + } acl->a_entries[i].e_uid =make_kuid (&init_user_ns,le32_to_cpu (entry->e_id));
@@ -92,6 +101,11 @@ static struct posix_acl *f2fs_acl_from_d sizeof(struct f2fs_acl_entry));break ;case ACL_GROUP : +if (unlikely ((char *)entry + +sizeof (struct f2fs_acl_entry ) > end)) { + err = -EFSCORRUPTED ; + goto fail; + } acl->a_entries[i].e_gid =make_kgid (&init_user_ns,le32_to_cpu (entry->e_id));
@@ -107,7 +121,7 @@ static struct posix_acl *f2fs_acl_from_dreturn acl; fail:posix_acl_release (acl); -return ERR_PTR (-EINVAL ); +return ERR_PTR (err); } static void *f2fs_acl_to_disk(struct f2fs_sb_info *sbi,
Greg Kroah-Hartman
maintainerPATCH 64/95 bpf: use kvfree() for replaced sysctl write buffer
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawei Feng <[email protected]>
commit 4c21b5927d4364bfe7365f2700da5fea0ed0d004 upstream.
proc_sys_call_handler() allocates its temporary sysctl buffer with kvzalloc() and passes it to __cgroup_bpf_run_filter_sysctl(). Since kvzalloc() may fall back to vmalloc() for large allocations, freeing that buffer with kfree() is wrong and can corrupt memory.
Use kvfree() to safely handle both kmalloc and kvzalloc()/vmalloc allocations.
The bug was first flagged by an experimental analysis tool we are developing for kernel memory-management bugs while analyzing v6.13-rc1. The tool is still under development and is not yet publicly available. Manual inspection confirms that the bug is still present in v7.1-rc5.
Reproduced the bug based on v7.1-rc4 in a QEMU x86_64 guest booted with KASAN and CONFIG_FAILSLAB enabled. To exercise the replacement path, the test tree also included the accompanying fix for the stale ret == 1 check in __cgroup_bpf_run_filter_sysctl(). The reproducer confines failslab injections to the proc_sys_call_handler() range, uses stacktrace-depth=32, and injects fail-nth=1 while writing 8191 bytes to /proc/sys/kernel/domainname from a task in the target cgroup. Under that setup, fail-nth=1 triggered the fault:
BUG: unable to handle page fault for address: ffffeb0200024d48 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 SMP KASAN NOPTI CPU: 2 UID: 0 PID: 209 Comm: repro_proc_sys_ Not tainted 7.1.0-rc4-00686-g97625979a5d4 PREEMPT(lazy) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 RIP: 0010:kfree+0x6e/0x510 ... Call Trace: <TASK> ? __cgroup_bpf_run_filter_sysctl+0x626/0xc30 __cgroup_bpf_run_filter_sysctl+0x74d/0xc30 ? __pfx___cgroup_bpf_run_filter_sysctl+0x10/0x10 ? srso_return_thunk+0x5/0x5f ? __kvmalloc_node_noprof+0x345/0x870 ? proc_sys_call_handler+0x250/0x480 ? srso_return_thunk+0x5/0x5f proc_sys_call_handler+0x3a2/0x480 ? __pfx_proc_sys_call_handler+0x10/0x10 ? srso_return_thunk+0x5/0x5f ? selinux_file_permission+0x39f/0x500 ? srso_return_thunk+0x5/0x5f ? lock_is_held_type+0x9e/0x120 vfs_write+0x98e/0x1000 ... </TASK>
With this fix applied on top of the same test setup, rerunning the reproducer with fail-nth=1 yields no corresponding Oops reports.
--- kernel/bpf/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/cgroup.c +1 -1
@@ -1359,7 +1359,7 @@ int __cgroup_bpf_run_filter_sysctl(struckfree (ctx.cur_val);if (ret ==1 && ctx.new_updated) { -kfree (*buf); +kvfree (*buf); *buf = ctx.new_val; *pcount = ctx.new_len; }else {
Greg Kroah-Hartman
maintainerPATCH 65/95 MIPS: DEC: Prevent initial console buffer from landing in XKPHYS
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit 7fb13fd35110ebe95eb053faf79d018f51144d85 upstream.
In 64-bit configurations calling the initial console output handler from a kernel thread other than the initial one will result in a situation where the stack has been placed in the XKPHYS 64-bit memory segment and consequently so has been the buffer allocated there that is used as the argument corresponding to the `%s' output conversion specifier for the firmware's printf() entry point.
This 64-bit address will then be truncated by 32-bit firmware, resulting in an attempt to access the wrong memory location, which in turn will cause all kinds of unpredictable behaviour, such as a kernel crash:
Console: colour dummy device 160x64
Calibrating delay loop... 49.36 BogoMIPS (lpj=192512)
pid_max: default: 32768 minimum: 301
CPU 0 Unable to handle kernel paging request at virtual address 000000000203bd00, epc == ffffffffbfc08364, ra == ffffffffbfc08800 Oops[#1]:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc2-00254-gfb649bda6f56-dirty #121
$ 0 : 0000000000000000 0000000000000001 0000000000000023 ffffffff80684ba0
$ 4 : 000000000203bd00 ffffffffbfc0f3b4 ffffffffffffffff 0000000000000073
$ 8 : 0a303d7469000000 0000000000000000 0000000000000073 ffffffffbfc0f473
$12 : 0000000000000002 0000000000000000 ffffffff80684c1c 0000000000000000
$16 : 0000000000000000 ffffffff80596dc9 0000000000000000 ffffffffbfc09240
$20 : ffffffff80684c40 ffffffffbfc0f400 000000000000002d 000000000000002b
$24 : ffffffffffffffbf 000000000203bd00
$28 : ffffffff805f0000 ffffffff80684b58 0000000000000030 ffffffffbfc08800
Hi : 0000000000000000
Lo : 0000000000000aa8
epc : ffffffffbfc08364 0xffffffffbfc08364
ra : ffffffffbfc08800 0xffffffffbfc08800
Status: 140120e2 KX SX UX KERNEL EXL
Cause : 00000008 (ExcCode 02)
BadVA : 000000000203bd00
PrId : 00000430 (R4000SC)
Modules linked in:
Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____), tls=0000000000000000)
Stack : 0000000000000000 0000000000000000 0000000000000000 0000004d0000004d
80684cc0806a2a40 80596dc80000004d 8061000000000000 bfc0850c80684c38
0000000000000000 000000000203bd00 0000000000000000 0000000000000000
0000000000000000 00000000bfc0f3b4 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000002500000000 0000000000000000 0000000000000000 802c1a7400000000
0203bd0080596dc8 0203bd4d69000000 6c61632000000018 5f746567646e6172
6c616320625f6d6f 5f736e5f6d6f7266 206361323778302b 303d74696e726320
806a0a38806b0000 806a0a38806b0000 00000000806b0000 80683c58806b0000
...
Call Trace:
Code: a082ffff 03e00008 00601021 <80820000> 00001821 10400005 24840001 80820000 24630001
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Fatal exception in interrupt KN04 V2.1k (PC: 0xa0026768, SP: 0x806848e8)
Quoted 1 line
Quoted 1 line
In this case the pointer in $4 was truncated from 0x980000000203bd00 to 0x000000000203bd00.
This may happen when no final console driver has been enabled in the configuration and consequently the initial console continues being used late into bootstrap or with an upcoming change that will switch the zs driver to use a platform device, which in turn will make the console handover happen only after other kernel threads have already been started.
Fix the issue by making the buffer static and initdata, and therefore placed in the CKSEG0 32-bit compatibility segment, observing that the console output handler is called with the console lock held, implying no need for this code to be reentrant. Add an assertion to verify the buffer actually has been placed in a compatibility segment.
--- arch/mips/dec/prom/console.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/mips/dec/prom/console.c +5 -2
@@ -2,8 +2,9 @@/* * DECstation PROM-based early console support. * -* Copyright (C) 2004, 2007 Maciej W. Rozycki +* Copyright (C) 2004, 2007, 2026 Maciej W. Rozycki */ +#include <linux/bug.h> #include <linux/console.h> #include <linux/init.h> #include <linux/kernel.h>
@@ -14,9 +15,11 @@static void __init prom_console_write (struct console *con,const char *s,unsigned int c) { -char buf[81 ]; +static char buf[81 ]__initdata = {0 };unsigned int chunk =sizeof (buf) -1 ; +BUG_ON ((long )buf != (int )(long )buf); +while (c >0 ) {if (chunk > c) chunk = c;
Greg Kroah-Hartman
maintainerPATCH 66/95 exfat: fix potential use-after-free in exfat_find_dir_entry()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit 3f5f8ee9917cc2b9076ac533492d8a200edcabb8 upstream.
In exfat_find_dir_entry(), the buffer_head obtained from exfat_get_dentry() is released with brelse(bh) before the fall-through TYPE_EXTEND branch reads the directory entry through ep (which points into bh->b_data):
brelse(bh);
if (entry_type == TYPE_EXTEND) {
...
len = exfat_extract_uni_name(ep, entry_uniname);
...
}After brelse() drops our reference, nothing guarantees that the underlying page backing bh->b_data remains valid for the subsequent exfat_extract_uni_name() read. This is the same pattern fixed in commit fc961522ddbd ("exfat: Fix potential use after free in exfat_load_upcase_table()").
Move brelse(bh) so it runs after ep is no longer dereferenced on each branch.
Confirmed on QEMU x86_64 with CONFIG_KASAN=y + CONFIG_DEBUG_PAGEALLOC=y
+ CONFIG_PAGE_POISONING=y on linux-next, using a crafted exFAT image (long filename with same-hash collisions forcing the TYPE_EXTEND path). With a debug-only invalidate_bdev() inserted between brelse(bh) and the ep read to make the stale-deref window deterministic, the unpatched kernel faults:
BUG: KASAN: use-after-free in exfat_find_dir_entry+0x133b/0x15a0 BUG: unable to handle page fault for address: ffff88801a5fa0c2 Oops: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN NOPTI RIP: 0010:exfat_find_dir_entry+0x1188/0x15a0
With this patch applied, the same instrumented harness completes cleanly under the same sanitizer stack. I have not reproduced a crash on an uninstrumented kernel under ordinary reclaim; the instrumented A/B establishes the lifetime violation and that the patch closes it, not an unaided triggerability claim.
--- fs/exfat/dir.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
fs/exfat/dir.c +3 -1
@@ -1048,12 +1048,12 @@ rewind:continue ; } -brelse (bh);if (entry_type ==TYPE_EXTEND ) {unsigned short entry_uniname[16 ], unichar;if (step !=DIRENT_STEP_NAME || name_len >=MAX_NAME_LENGTH ) { +brelse (bh); step =DIRENT_STEP_FILE ;continue ; }
@@ -1064,6 +1064,7 @@ rewind: uniname +=EXFAT_FILE_NAME_LEN ; len =exfat_extract_uni_name (ep, entry_uniname); +brelse (bh); name_len += len; unichar = *(uniname+len);
@@ -1082,6 +1083,7 @@ rewind:continue ; } +brelse (bh);if (entry_type & (TYPE_CRITICAL_SEC |TYPE_BENIGN_SEC )) {if (step ==DIRENT_STEP_SECD ) {
Greg Kroah-Hartman
maintainerPATCH 67/95 hdlc_ppp: sync per-proto timers before freeing hdlc state
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <[email protected]>
commit c78a4e41ab5ead6193ad8a2dd92e8906bae659fa upstream.
Each PPP control protocol (LCP/IPCP/IPV6CP) embedded in struct ppp registers a timer via timer_setup(). That struct ppp is the hdlc->state allocation, which detach_hdlc_protocol() frees with kfree() in both teardown paths: unregister_hdlc_device() and the re-attach inside attach_hdlc_protocol().
The ppp proto never registered a .detach callback, so detach_hdlc_protocol() performs no timer synchronization before the kfree(). The only cancel, timer_delete(&proto->timer) in ppp_cp_event(), is partial (it does not wait for a running callback) and only runs on the ->CLOSED transition; ppp_stop()/ppp_close() do not sync either. A ppp_timer callback already executing (blocked on ppp->lock) survives the kfree and then dereferences proto->state / ppp->lock in freed memory, leading to a use-after-free.
Fix this by adding a .detach helper that calls timer_shutdown_sync() on every per-proto timer. detach_hdlc_protocol() invokes proto->detach(dev) before kfree(hdlc->state), so timer_shutdown_sync()
now runs on both free paths.timer_shutdown_sync() is used instead of timer_delete_sync() because the keepalive path re-arms the timer through add_timer()/mod_timer() and shutdown blocks any re-activation during teardown.
Initialize the per-protocol timers in ppp_ioctl() when the protocol is attached, and remove the now-redundant timer_setup() from ppp_start(), so that the timers are initialized exactly once at attach time and ppp_timer_release() never operates on uninitialized timer_list structures. attach_hdlc_protocol() uses kmalloc() (not kzalloc), so struct ppp's protos[i].timer is uninitialized garbage until the first timer_setup(); without this init-at-attach, attaching the PPP protocol without ever bringing the device up would leave timer_shutdown_sync() operating on uninitialized memory in .detach. Moving the init out of ppp_start() (which only runs on NETDEV_UP) into the attach path makes the initialization unconditional and avoids initializing the same timer_list twice.
This bug was found by static analysis.
--- drivers/net/wan/hdlc_ppp.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
drivers/net/wan/hdlc_ppp.c +13 -2
@@ -621,7 +621,6 @@ static void ppp_start(struct net_devicestruct proto *proto = &ppp->protos[i]; proto->dev = dev; -timer_setup (&proto->timer, ppp_timer,0 ); proto->state =CLOSED ; } ppp->protos[IDX_LCP ].pid =PID_LCP ;
@@ -641,6 +640,15 @@ static void ppp_close(struct net_deviceppp_tx_flush (); } +static void ppp_timer_release (struct net_device *dev) +{ +struct ppp *ppp =get_ppp (dev); +int i; + +for (i =0 ; i <IDX_COUNT ; i++) +timer_shutdown_sync (&ppp->protos[i].timer); +} +static struct hdlc_proto proto = { .start = ppp_start, .stop = ppp_stop,
@@ -649,6 +657,7 @@ static struct hdlc_proto proto = { .ioctl = ppp_ioctl, .netif_rx = ppp_rx, .module = THIS_MODULE, + .detach = ppp_timer_release, };static const struct header_ops ppp_header_ops = {
@@ -659,7 +668,7 @@ static int ppp_ioctl(struct net_device * {hdlc_device *hdlc =dev_to_hdlc (dev);struct ppp *ppp; -int result; +int i, result;switch (ifs->type) {case IF_GET_PROTO :
@@ -687,6 +696,8 @@ static int ppp_ioctl(struct net_device *return result; ppp =get_ppp (dev); +for (i =0 ; i <IDX_COUNT ; i++) +timer_setup (&ppp->protos[i].timer, ppp_timer,0 );spin_lock_init (&ppp->lock); ppp->req_timeout =2 ; ppp->cr_retries =10 ;
Greg Kroah-Hartman
maintainerPATCH 68/95 tipc: fix slab-use-after-free Read in tipc_aead_decrypt_done
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <[email protected]>
commit bda3348872a2ef0d19f2df6aa8cb5025adce2f20 upstream.
tipc_aead_decrypt() goes straight from tipc_bearer_hold(b) to crypto_aead_decrypt(req) without taking a reference on the netns, unlike the encrypt path. When crypto_aead_decrypt() is offloaded asynchronously (e.g. the SIMD aead wrapper queuing to cryptd), the cryptd worker runs tipc_aead_decrypt_done() later. If the bearer's netns is torn down in the meantime, cleanup_net() -> tipc_exit_net() -> tipc_crypto_stop() frees the per-netns tipc_crypto, and the completion then reads it:tipc_aead_decrypt_done() dereferences aead->crypto->stats and aead->crypto->net, and tipc_crypto_rcv_complete() dereferences aead->crypto->aead[] and the node table -- reading freed memory.
Decoded KASAN splat (v7.1-rc7, CONFIG_KASAN_INLINE + TIPC + TIPC_CRYPTO):
BUG: KASAN: slab-use-after-free in tipc_aead_decrypt_done (net/tipc/crypto.c:999) Read of size 8 at addr ffff8881056258a8 by task kworker/u16:2/51 Workqueue: events_unbound Call Trace: tipc_aead_decrypt_done (net/tipc/crypto.c:999) process_one_work (kernel/workqueue.c:3314) worker_thread (kernel/workqueue.c:3397 kernel/workqueue.c:3478) kthread (kernel/kthread.c:436) ret_from_fork (arch/x86/kernel/process.c:158) ret_from_fork_asm (arch/x86/entry/entry_64.S:245) Allocated by task 169: __kasan_kmalloc (mm/kasan/common.c:398 mm/kasan/common.c:415) tipc_crypto_start (net/tipc/crypto.c:1502) tipc_init_net (net/tipc/core.c:72) ops_init (net/core/net_namespace.c:137) setup_net (net/core/net_namespace.c:446) copy_net_ns (net/core/net_namespace.c:579) create_new_namespaces (kernel/nsproxy.c:132) __x64_sys_unshare (kernel/fork.c:3316) do_syscall_64 (arch/x86/entry/syscall_64.c:63) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121) Freed by task 8: kfree (mm/slub.c:6566) tipc_exit_net (net/tipc/core.c:119) cleanup_net (net/core/net_namespace.c:704) process_one_work (kernel/workqueue.c:3314) kthread (kernel/kthread.c:436)
This is the same class of bug that commit e279024617134 ("net/tipc: fix slab-use-after-free Read in tipc_aead_encrypt_done") fixed for the encrypt side. The encrypt path takes maybe_get_net(aead->crypto->net) before crypto_aead_encrypt() and drops it with put_net() on the synchronous return paths and in tipc_aead_encrypt_done(); the -EINPROGRESS/-EBUSY return keeps the reference for the async callback to release. The decrypt path was left without the equivalent guard.
Mirror the encrypt-side fix on the decrypt path: take a net reference before crypto_aead_decrypt() (failing with -ENODEV and the matching bearer put if it cannot be acquired), keep it across the -EINPROGRESS/-EBUSY async return, and drop it with put_net() on the synchronous success/error return and at the end of tipc_aead_decrypt_done().
Reproduced under KASAN on v7.1-rc7: a UDP bearer with a cluster key is flooded with crafted encrypted frames from an unknown peer (driving the cluster-key decrypt path) while the bearer's netns is repeatedly torn down. The completion must run asynchronously to outlive tipc_crypto_stop(); on x86 the stock aesni gcm(aes) now decrypts synchronously, so the async path was exercised via cryptd offload. The unguarded aead->crypto dereference in tipc_aead_decrypt_done() is the unpatched upstream path; tipc_aead_decrypt() still lacks maybe_get_net(aead->crypto->net), so the completion can outlive the free on any config where crypto_aead_decrypt() goes async.
Found by 0sec automated security-research tooling (https://0sec.ai).
--- net/tipc/crypto.c | 9 +++++++++ 1 file changed, 9 insertions(+)
net/tipc/crypto.c +9 -0
@@ -961,12 +961,20 @@ static int tipc_aead_decrypt(struct net goto exit; } +/* Get net to avoid freed tipc_crypto when delete namespace */ +if (!maybe_get_net (net)) { +tipc_bearer_put (b); + rc = -ENODEV ; + goto exit; + } +/* Now, do decrypt */ rc =crypto_aead_decrypt (req);if (rc == -EINPROGRESS || rc == -EBUSY )return rc;tipc_bearer_put (b); +put_net (net); exit:kfree (ctx);
@@ -1004,6 +1012,7 @@ static void tipc_aead_decrypt_done(struc }tipc_bearer_put (b); +put_net (net); }static inline int tipc_ehdr_size (struct tipc_ehdr *ehdr)
Greg Kroah-Hartman
maintainerPATCH 69/95 pNFS: Fix use-after-free in pnfs_update_layout()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit 13e198a90ca4050f4bee8a3f23680389a6563ccc upstream.
When hitting the NFS_LAYOUT_RETURN branch in pnfs_update_layout(), the code calls pnfs_prepare_to_retry_layoutget(lo). If it succeeds, pnfs_put_layout_hdr(lo) is called before trace_pnfs_update_layout(), which still references 'lo'. This results in a use-after-free when the tracepoint accesses lo's fields.
Fix this by moving the tracepoint call before pnfs_put_layout_hdr(lo).
--- fs/nfs/pnfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/nfs/pnfs.c +1 -1
@@ -2067,11 +2067,11 @@ lookup_again:dprintk ("%s wait for layoutreturn\n" , __func__); lseg =ERR_PTR (pnfs_prepare_to_retry_layoutget (lo));if (!IS_ERR (lseg)) { -pnfs_put_layout_hdr (lo);dprintk ("%s retrying\n" , __func__);trace_pnfs_update_layout (ino, pos, count, iomode, lo, lseg,PNFS_UPDATE_LAYOUT_RETRY ); +pnfs_put_layout_hdr (lo); goto lookup_again; } trace_pnfs_update_layout(ino, pos, count, iomode, lo, lseg,
Greg Kroah-Hartman
maintainerPATCH 70/95 irqchip/imgpdc: Fix resource leak, add missing chained handler cleanup on remove
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingshuang Fu <[email protected]>
commit 37738fdf2ab1e504d1c63ce5bc0aeb6452d8f057 upstream.
The driver allocates domain generic chips using irq_alloc_domain_generic_chips() during probe and sets up chained handlers using irq_set_chained_handler_and_data(). However, on driver removal, the generic chips are not freed and the chained handlers are not removed.
The generic chips remain on the global gc_list and may later be accessed by generic interrupt chip suspend, resume, or shutdown callbacks after the driver has been removed, potentially resulting in a use-after-free and kernel crash.
The chained handlers that were installed in probe for peripheral and syswake interrupts are also left dangling, which can lead to spurious interrupts accessing freed memory.
Fix these issues by:
- Setting IRQ_DOMAIN_FLAG_DESTROY_GC flag in domain->flags, so the core code automatically removes generic chips when irq_domain_remove() is called
- Clearing all chained handlers with NULL in pdc_intc_remove()
--- drivers/irqchip/irq-imgpdc.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/irqchip/irq-imgpdc.c +6 -0
@@ -378,6 +378,7 @@ static int pdc_intc_probe(struct platfordev_err (&pdev->dev,"cannot add IRQ domain\n" );return -ENOMEM ; } + priv->domain->flags |=IRQ_DOMAIN_FLAG_DESTROY_GC ;/* * Set up 2 generic irq chips with 2 chip types.
@@ -465,6 +466,11 @@ static int pdc_intc_remove(struct platfo {struct pdc_intc_priv *priv =platform_get_drvdata (pdev); +for (unsigned int i =0 ; i < priv->nr_perips; ++i) +irq_set_chained_handler_and_data (priv->perip_irqs[i],NULL ,NULL ); + +irq_set_chained_handler_and_data (priv->syswake_irq,NULL ,NULL ); +irq_domain_remove (priv->domain);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 71/95 fpga: region: fix use-after-free in child_regions_with_firmware()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit 54f3c5643ec523a04b6ec0e7c19eb10f5ebebdd3 upstream.
Move of_node_put(child_region) after the error print to avoid accessing freed memory when pr_err() references child_region.
--- drivers/fpga/of-fpga-region.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/fpga/of-fpga-region.c +1 -2
@@ -166,11 +166,10 @@ static int child_regions_with_firmware(s fpga_region_of_match); } -of_node_put (child_region); -if (ret)pr_err ("firmware-name not allowed in child FPGA region: %pOF" , child_region); +of_node_put (child_region);return ret; }
Greg Kroah-Hartman
maintainerPATCH 72/95 ocfs2: reject oversized group bitmap descriptors
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Cen <[email protected]>
commit 9bd541e09dffff27e5bec0f9f45b0228173a5375 upstream.
ocfs2_validate_gd_parent() only bounds bg_bits against the parent allocator's chain geometry. A malicious descriptor can still claim a bg_size/bg_bits pair that exceeds the bitmap bytes that physically fit in the group descriptor block, so later bitmap scans and bit updates can run past bg_bitmap.
Add a physical-cap check based on ocfs2_group_bitmap_size() for the parent allocator type and reject descriptors whose bg_size or bg_bits exceed that capacity. Keep the existing chain geometry check so both the on-disk bitmap layout and the allocator metadata must agree before the descriptor is used.
Validation reproduced this kernel report:
KASAN use-after-free in _find_next_bit+0x7f/0xc0
Read of size 8 Call trace: dump_stack_lvl+0x66/0xa0 (?:?) print_report+0xd0/0x630 (?:?) _find_next_bit+0x7f/0xc0 (?:?) srso_alias_return_thunk+0x5/0xfbef5 (?:?) __virt_addr_valid+0x188/0x2f0 (?:?) kasan_report+0xe4/0x120 (?:?) ocfs2_find_max_contig_free_bits+0x35/0x70 (fs/ocfs2/suballoc.c:1375) ocfs2_block_group_set_bits+0x472/0x4b0 (fs/ocfs2/suballoc.c:1457) ocfs2_cluster_group_search+0x16b/0x440 (fs/ocfs2/suballoc.c:86) ocfs2_bg_discontig_fix_result+0x1ef/0x230 (fs/ocfs2/suballoc.c:1786) ocfs2_search_chain+0x8f8/0x10a0 (fs/ocfs2/suballoc.c:1886) get_page_from_freelist+0x70e/0x2370 (?:?) lock_release+0xc6/0x290 (?:?) do_raw_spin_unlock+0x9a/0x100 (?:?) kasan_unpoison+0x27/0x60 (?:?) __bfs+0x147/0x240 (?:?) get_page_from_freelist+0x83d/0x2370 (?:?) ocfs2_claim_suballoc_bits+0x38c/0xe70 (fs/ocfs2/suballoc.c:96) sched_domains_numa_masks_clear+0x70/0xd0 (?:?) check_irq_usage+0xe8/0xb70 (?:?) __ocfs2_claim_clusters+0x18d/0x4c0 (fs/ocfs2/suballoc.c:2497) check_path+0x24/0x50 (?:?) rcu_is_watching+0x20/0x50 (?:?) check_prev_add+0xfd/0xd00 (?:?) ocfs2_add_clusters_in_btree+0x17d/0x810 (fs/ocfs2/suballoc.c:?) __folio_batch_add_and_move+0x1f5/0x3d0 (?:?) ocfs2_add_inode_data+0xd9/0x120 (fs/ocfs2/suballoc.c:?) filemap_add_folio+0x105/0x1f0 (?:?) ocfs2_write_begin_nolock+0x29f7/0x2f80 (fs/ocfs2/suballoc.c:3043) ocfs2_read_inode_block+0xb5/0x110 (fs/ocfs2/suballoc.c:?) down_write+0xf5/0x180 (?:?) ocfs2_write_begin+0x180/0x240 (fs/ocfs2/suballoc.c:?) __mark_inode_dirty+0x758/0x9a0 (?:?) inode_to_bdi+0x41/0x90 (?:?) balance_dirty_pages_ratelimited_flags+0xf8/0x1d0 (?:?) generic_perform_write+0x252/0x440 (?:?) mnt_put_write_access_file+0x16/0x70 (?:?) file_update_time_flags+0xe4/0x200 (?:?) ocfs2_file_write_iter+0x80a/0x1320 (fs/ocfs2/suballoc.c:?) lock_acquire+0x184/0x2f0 (?:?) ksys_write+0xd2/0x170 (?:?) apparmor_file_permission+0xf5/0x310 (?:?) read_zero+0x8d/0x140 (?:?) lock_is_held_type+0x8f/0x100 (?:?)
--- fs/ocfs2/suballoc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
fs/ocfs2/suballoc.c +22 -0
@@ -201,8 +201,16 @@ static int ocfs2_validate_gd_parent(stru int resize) {unsigned int max_bits; +unsigned int max_bitmap_bits; +unsigned int max_bitmap_size; +int suballocator;struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; + suballocator =le64_to_cpu (di->i_blkno) !=OCFS2_SB (sb)->bitmap_blkno; + max_bitmap_size =ocfs2_group_bitmap_size (sb, suballocator, +OCFS2_SB (sb)->s_feature_incompat); + max_bitmap_bits = max_bitmap_size *8 ; +if (di->i_blkno != gd->bg_parent_dinode) { do_error("Group descriptor #%llu has bad parent pointer (%llu, expected %llu)\n", (unsigned long long)bh->b_blocknr,
@@ -210,6 +218,20 @@ static int ocfs2_validate_gd_parent(stru (unsigned long long)le64_to_cpu(di->i_blkno)); } +if (le16_to_cpu (gd->bg_size) > max_bitmap_size) { +do_error ("Group descriptor #%llu has bitmap size %u but physical max of %u\n" , + (unsigned long long )bh->b_blocknr, +le16_to_cpu (gd->bg_size), + max_bitmap_size); + } + +if (le16_to_cpu (gd->bg_bits) > max_bitmap_bits) { +do_error ("Group descriptor #%llu has bit count %u but physical max of %u\n" , + (unsigned long long )bh->b_blocknr, +le16_to_cpu (gd->bg_bits), + max_bitmap_bits); + } + max_bits =le16_to_cpu (di->id2.i_chain.cl_cpg) *le16_to_cpu (di->id2.i_chain.cl_bpc);if (le16_to_cpu (gd->bg_bits) > max_bits) { do_error("Group descriptor #%llu has bit count of %u\n",
Greg Kroah-Hartman
maintainerPATCH 73/95 KVM: SVM: Fix page overflow in sev_dbg_crypt() for ENCRYPT path
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ashutosh Desai <[email protected]>
commit 78ee2d50185a037b3d2452a97f3dad69c3f7f389 upstream.
In sev_dbg_crypt(), the per-iteration transfer length is bounded by the source page offset (PAGE_SIZE - s_off) but not by the destination page offset (PAGE_SIZE - d_off). When d_off > s_off, the encrypt path (__sev_dbg_encrypt_user) performs a read-modify-write using a single-page intermediate buffer (dst_tpage):
1. __sev_dbg_decrypt() expands the size to round_up(len + (d_off & 15), 16) before issuing the PSP command. If len + (d_off & 15) > PAGE_SIZE, the PSP writes beyond the end of the 4096-byte dst_tpage allocation.
2. The subsequent memcpy()/copy_from_user() into page_address(dst_tpage) + (d_off & 15) of 'len' bytes overflows by up to 15 bytes under the same condition.
Trigger example: s_off = 0, d_off = 1, debug.len = PAGE_SIZE - the PSP is instructed to write round_up(4097, 16) = 4112 bytes to a 4096-byte buffer.
Fix by also bounding len by (PAGE_SIZE - d_off), the same check that sev_send_update_data() already performs for its single-page guest region.
==================================================================
BUG: KASAN: slab-use-after-free in sev_dbg_crypt+0x993/0xd10 [kvm_amd]
Write of size 4095 at addr ff110062293bb009 by task sev_dbg_test/228214
CPU: 96 UID: 0 PID: 228214 Comm: sev_dbg_test Tainted: G U W 7.0.0-smp--5ce9b0c48211-dbg #156 PREEMPTLAZY
Tainted: [U]=USER, [W]=WARN
Hardware name: Google Astoria/astoria, BIOS 0.20250817.1-0 08/25/2025
Call Trace:
<TASK>
dump_stack_lvl+0x54/0x70
print_report+0xbc/0x260
kasan_report+0xa2/0xd0
kasan_check_range+0x25f/0x2c0
__asan_memcpy+0x40/0x70
sev_dbg_crypt+0x993/0xd10 [kvm_amd]
sev_mem_enc_ioctl+0x33c/0x450 [kvm_amd]
kvm_vm_ioctl+0x65d/0x6d0 [kvm]
__se_sys_ioctl+0xb2/0x100
do_syscall_64+0xe8/0x870
entry_SYSCALL_64_after_hwframe+0x4b/0x53
</TASK>
The buggy address belongs to the physical page:
page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x7fe72b6a0 pfn:0x62293bb
memcg:ff11000112827d82
flags: 0x1400000000000000(node=1|zone=1)
raw: 1400000000000000 0000000000000000 dead000000000122 0000000000000000
raw: 00000007fe72b6a0 0000000000000000 00000001ffffffff ff11000112827d82
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ff110062293bbf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ff110062293bbf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ff110062293bc000: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
^
ff110062293bc080: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
ff110062293bc100: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================
Disabling lock debugging due to kernel taint--- arch/x86/kvm/svm/sev.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kvm/svm/sev.c +1 -0
@@ -954,6 +954,7 @@ static int sev_dbg_crypt(struct kvm *kvm s_off = vaddr & ~PAGE_MASK ; d_off = dst_vaddr & ~PAGE_MASK ; len =min_t (size_t, (PAGE_SIZE - s_off), size); + len =min_t (size_t, len,PAGE_SIZE - d_off);if (dec) ret = __sev_dbg_decrypt_user(kvm,
Greg Kroah-Hartman
maintainerPATCH 74/95 power: reset: linkstation-poweroff: fix use-after-free in the linkstation_poweroff_init()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
commit 8eec545cde69e46e9a1d2b7d915ce4f5df85b3bd upstream.
Move of_node_put(dn) after the of_match_node() call, which still needs the node pointer. The node reference is correctly released after use.
--- drivers/power/reset/linkstation-poweroff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/power/reset/linkstation-poweroff.c +1 -1
@@ -163,10 +163,10 @@ static int __init linkstation_poweroff_i dn =of_find_matching_node (NULL , ls_poweroff_of_match);if (!dn)return -ENODEV ; -of_node_put (dn); match =of_match_node (ls_poweroff_of_match, dn); cfg = match->data; +of_node_put (dn); dn =of_find_node_by_name (NULL , cfg->mdio_node_name);if (!dn)
Greg Kroah-Hartman
maintainerPATCH 75/95 fbdev: Fix fb_new_modelist to prevent null-ptr-deref in fb_videomode_to_var
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <[email protected]>
commit 7f08fc10fa3d3366dc3af723970bd03d7d6d10e3 upstream.
info->var, a framebuffer's current mode, is expected to have a matching entry in info->modelist. var_to_display() relies on this and treats a failed fb_match_mode() as "This should not happen". fb_set_var() keeps it true by adding the mode to the list on every change, and do_register_framebuffer() does the same at registration.
store_modes() replaces the modelist from userspace. fb_new_modelist() validates the new modes but does not check that info->var still has a match. It relies on fbcon_new_modelist() to re-point consoles, but that only handles consoles mapped to the framebuffer. With fbcon unbound there are none, so info->var is left describing a mode that is no longer in the list.
A later console takeover runs var_to_display(), where fb_match_mode() returns NULL and leaves fb_display[i].mode NULL. fbcon_switch() passes it to display_to_var(), and fb_videomode_to_var() dereferences the NULL mode.
Keep the current mode in the list in fb_new_modelist(), the same way fb_set_var() does.
--- drivers/video/fbdev/core/fbmem.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/video/fbdev/core/fbmem.c +12 -0
@@ -2061,6 +2061,18 @@ int fb_new_modelist(struct fb_info *infoif (list_empty (&info->modelist))return 1 ; +/* +* The new modelist may not contain the current mode (info->var), and +* fbcon_new_modelist() below only re-points consoles mapped to this +* framebuffer. Add the current mode here so info->var keeps a match +* even when fbcon is unbound. +*/ +if (!fb_match_mode (&info->var, &info->modelist)) { +fb_var_to_videomode (&mode, &info->var); +if (fb_add_videomode (&mode, &info->modelist)) +return 1 ; + } +fbcon_new_modelist (info);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 76/95 fbdev: modedb: Fix misaligned fields in the 1920x1080-60 mode
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steffen Persvold <[email protected]>
commit d894c48a57d78206e4df9c90d4acfaf39394806a upstream.
The 1920x1080@60 modedb entry has one too many initializers before its sync field: a stray "0" occupies the sync slot, which shifts the remaining values by one field. The entry therefore decodes as sync = 0, vmode = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT (0x3, i.e. FB_VMODE_INTERLACED | FB_VMODE_DOUBLE), and flag = FB_VMODE_NONINTERLACED, instead of the intended sync = positive H/V, vmode = non-interlaced.
fb_find_mode() then returns a 1920x1080 mode flagged as interlaced + doublescan with active-low syncs. Drivers that honour var->vmode and var->sync when programming display timing enable doublescan and the wrong sync polarity, corrupting the output.
Drop the stray initializer so sync and vmode hold their intended values (positive H/V sync, non-interlaced), matching the adjacent 1920x1200 entry.
--- drivers/video/fbdev/core/modedb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/core/modedb.c +1 -1
@@ -258,7 +258,7 @@ static const struct fb_videomode modedb[ FB_VMODE_DOUBLE },/* 1920x1080 @ 60 Hz, 67.3 kHz hsync */ - {NULL ,60 ,1920 ,1080 ,6734 ,148 ,88 ,36 ,4 ,44 ,5 ,0 , + {NULL ,60 ,1920 ,1080 ,6734 ,148 ,88 ,36 ,4 ,44 ,5 ,FB_SYNC_HOR_HIGH_ACT |FB_SYNC_VERT_HIGH_ACT , FB_VMODE_NONINTERLACED },
Greg Kroah-Hartman
maintainerPATCH 77/95 NFSD: Fix SECINFO_NO_NAME decode error cleanup
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guannan Wang <[email protected]>
commit 9e18e83b8846a5c3fe13fc8a464b4865d33996c6 upstream.
nfsd4_decode_secinfo_no_name() currently initializes sin_exp after decoding sin_style. If the XDR stream is truncated, the decoder returns nfserr_bad_xdr before sin_exp is initialized.
Since commit 3fdc54646234 ("NFSD: Reduce amount of struct nfsd4_compoundargs that needs clearing"), the inline iops array is not cleared between RPC calls. A failed SECINFO_NO_NAME decode can therefore leave sin_exp holding stale union contents from a previous operation.
The error response path still invokes nfsd4_secinfo_no_name_release(), which calls exp_put() on a non-NULL sin_exp.
Initialize sin_exp before the first failable decode step, matching nfsd4_decode_secinfo().
--- fs/nfsd/nfs4xdr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/nfs4xdr.c +2 -1
@@ -1821,10 +1821,11 @@ static __be32 nfsd4_decode_secinfo_no_na union nfsd4_op_u *u) {struct nfsd4_secinfo_no_name *sin = &u->secinfo_no_name; + + sin->sin_exp =NULL ;if (xdr_stream_decode_u32 (argp->xdr, &sin->sin_style) <0 )return nfserr_bad_xdr; - sin->sin_exp =NULL ;return nfs_ok; }
Greg Kroah-Hartman
maintainerPATCH 78/95 nfsd: fix posix_acl leak on SETACL decode failure
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit 0853ac544c590880d797b04daa33fcb72b6be0e1 upstream.
nfsaclsvc_decode_setaclargs() and nfs3svc_decode_setaclargs() each call nfs_stream_decode_acl() twice, first for NFS_ACL and then for NFS_DFACL. Each successful call transfers ownership of a freshly allocated posix_acl into argp->acl_access or argp->acl_default. If the first call succeeds but the second fails, the decoder returns false and argp->acl_access is left dangling.
ACLPROC2_SETACL.pc_release was wired to nfssvc_release_attrstat and ACLPROC3_SETACL.pc_release was wired to nfs3svc_release_fhandle. Both only call fh_put() and have no knowledge of the ACL fields on argp. The posix_acl_release() pairs sat at the out: labels inside nfsacld_proc_setacl() and nfsd3_proc_setacl(), but svc_process() skips pc_func when pc_decode returns false, so that cleanup is unreachable on decode failure:
svc_process_common()
pc_decode() /* decode_setaclargs: false */
/* pc_func skipped */
pc_release() /* fh_put only -- ACLs leaked */
The orphaned posix_acl is leaked for the lifetime of the server.
Fix by adding nfsaclsvc_release_setacl() and nfs3svc_release_setacl(), which release both argp->acl_access and argp->acl_default in addition to fh_put(), and wiring them as pc_release for their respective SETACL procedures. pc_release runs on every path svc_process() takes after decode, including decode failure, so the posix_acl_release() pairs are removed from the proc functions' out: labels to keep ownership in one place. This matches the existing release_getacl() pattern used by the sibling GETACL procedures.
--- fs/nfsd/nfs2acl.c | 17 ++++++++++++----- fs/nfsd/nfs3acl.c | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-)
fs/nfsd/nfs2acl.c +12 -5
@@ -131,10 +131,7 @@ static __be32 nfsacld_proc_setacl(struct resp->status =fh_getattr (fh, &resp->stat); out: -/* argp->acl_{access,default} may have been allocated in -nfssvc_decode_setaclargs. */ -posix_acl_release (argp->acl_access); -posix_acl_release (argp->acl_default); +/* argp->acl_{access,default} are released in nfsaclsvc_release_setacl. */ return rpc_success; out_drop_lock:
@@ -312,6 +309,16 @@ static void nfsaclsvc_release_access(strstruct nfsd3_voidargs {int dummy; }; +static void nfsaclsvc_release_setacl (struct svc_rqst *rqstp) +{ +struct nfsd3_setaclargs *argp = rqstp->rq_argp; +struct nfsd_attrstat *resp = rqstp->rq_resp; + +fh_put (&resp->fh); +posix_acl_release (argp->acl_access); +posix_acl_release (argp->acl_default); +} +#define ST 1/* status*/ #define AT 21/* attributes */ #define pAT (1+AT)/* post attributes - conditional */
@@ -345,7 +352,7 @@ static const struct svc_procedure nfsd_a .pc_func = nfsacld_proc_setacl, .pc_decode = nfsaclsvc_decode_setaclargs, .pc_encode = nfssvc_encode_attrstatres, - .pc_release = nfssvc_release_attrstat, + .pc_release = nfsaclsvc_release_setacl, .pc_argsize = sizeof(struct nfsd3_setaclargs), .pc_argzero = sizeof(struct nfsd3_setaclargs), .pc_ressize = sizeof(struct nfsd_attrstat),
fs/nfsd/nfs3acl.c +12 -5
@@ -118,10 +118,7 @@ out_drop_lock: out_errno: resp->status =nfserrno (error); out: -/* argp->acl_{access,default} may have been allocated in -nfs3svc_decode_setaclargs. */ -posix_acl_release (argp->acl_access); -posix_acl_release (argp->acl_default); +/* argp->acl_{access,default} are released in nfs3svc_release_setacl. */ return rpc_success; }
@@ -225,6 +222,16 @@ static void nfs3svc_release_getacl(strucstruct nfsd3_voidargs {int dummy; }; +static void nfs3svc_release_setacl (struct svc_rqst *rqstp) +{ +struct nfsd3_setaclargs *argp = rqstp->rq_argp; +struct nfsd3_attrstat *resp = rqstp->rq_resp; + +fh_put (&resp->fh); +posix_acl_release (argp->acl_access); +posix_acl_release (argp->acl_default); +} +#define ST 1/* status*/ #define AT 21/* attributes */ #define pAT (1+AT)/* post attributes - conditional */
@@ -258,7 +265,7 @@ static const struct svc_procedure nfsd_a .pc_func = nfsd3_proc_setacl, .pc_decode = nfs3svc_decode_setaclargs, .pc_encode = nfs3svc_encode_setaclres, - .pc_release = nfs3svc_release_fhandle, + .pc_release = nfs3svc_release_setacl, .pc_argsize = sizeof(struct nfsd3_setaclargs), .pc_argzero = sizeof(struct nfsd3_setaclargs), .pc_ressize = sizeof(struct nfsd3_attrstat),
Greg Kroah-Hartman
maintainerPATCH 79/95 nfsd: check get_user() return when reading princhashlen
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominik Woźniak <[email protected]>
commit e186fa1c057f5eccb22afb1e83e34c0627085868 upstream.
In __cld_pipe_inprogress_downcall(), the get_user() that reads princhashlen from the userspace cld_msg_v2 buffer does not check its return value. A failing copy leaves princhashlen with uninitialised stack contents, which are then used to drive memdup_user() and stored as princhash.len on the resulting reclaim record. The other get_user() calls in this function all check the return; only this one is missed, which is most likely a copy-paste oversight from when v2 upcalls were introduced.
Mirror the existing pattern used a few lines above for namelen. namecopy is declared with __free(kfree) so the early return cleans up the already-allocated buffer automatically.
--- fs/nfsd/nfs4recover.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nfsd/nfs4recover.c +2 -1
@@ -815,7 +815,8 @@ __cld_pipe_inprogress_downcall(const strif (IS_ERR (name.data))return PTR_ERR (name.data); name.len = namelen; -get_user (princhashlen, &ci->cc_princhash.cp_len); +if (get_user (princhashlen, &ci->cc_princhash.cp_len)) +return -EFAULT ;if (princhashlen >0 ) { princhash.data = memdup_user( &ci->cc_princhash.cp_data,
Greg Kroah-Hartman
maintainerPATCH 80/95 NFSv4/pNFS: reject zero-length r_addr in nfs4_decode_mp_ds_addr
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <[email protected]>
commit 41fe0f7b84f0cb822ae10ab08592996a592b2a25 upstream.
nfs4_decode_mp_ds_addr() decodes the r_netid and r_addr opaques of a netaddr4 from a GETDEVICEINFO multipath-DS body, then immediately calls strrchr(buf, '.') to locate the port separator. Both decodes use xdr_stream_decode_string_dup(), and the current code checks only "nlen < 0" / "rlen < 0" before dereferencing the returned string.
When the on-wire opaque has length zero, xdr_stream_decode_opaque_inline() returns 0 and xdr_stream_decode_string_dup() falls through to its "*str = NULL; return ret" tail, leaving buf NULL with a return value of 0. The "< 0" check does not catch this, and the next line is strrchr(NULL, '.'), a kernel NULL pointer dereference reachable from any pNFS-flexfile client mounted against a malicious or compromised metadata server.
Reject the zero-length cases explicitly so the decoder fails with -EBADMSG (treated as a malformed GETDEVICEINFO body) instead of panicking the client.
--- fs/nfs/pnfs_nfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
fs/nfs/pnfs_nfs.c +2 -2
@@ -1057,14 +1057,14 @@ nfs4_decode_mp_ds_addr(struct net *net,/* r_netid */ nlen =xdr_stream_decode_string_dup (xdr, &netid,XDR_MAX_NETOBJ , gfp_flags); -if (unlikely (nlen <0 )) +if (unlikely (nlen <=0 )) goto out_err;/* r_addr: ip/ip6addr with port in dec octets - see RFC 5665 */ /* port is ".ABC.DEF", 8 chars max */ rlen =xdr_stream_decode_string_dup (xdr, &buf,INET6_ADDRSTRLEN +IPV6_SCOPE_ID_LEN +8 , gfp_flags); -if (unlikely (rlen <0 )) +if (unlikely (rlen <=0 )) goto out_free_netid;/* replace port '.' with '-' */
Greg Kroah-Hartman
maintainerPATCH 81/95 mptcp: fix missing wakeups in edge scenarios
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit 9d8d28738f24b75616d6ca7a27cb4aed88520343 ]
The mptcp_recvmsg() can fill MPTCP socket receive queue via mptcp_move_skbs(), but currently does not try to wakeup any listener, because the same process is going to check the receive queue soon.
When multiple threads are reading from the same fd, the above can cause stall. Add the missing wakeup.
--- net/mptcp/protocol.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/mptcp/protocol.c +3 -1
@@ -2119,8 +2119,10 @@ static bool __mptcp_move_skbs(struct mpt__mptcp_splice_receive_queue (sk);mptcp_data_unlock (sk); } -if (ret) +if (ret) {mptcp_check_data_fin ((struct sock *)msk); + sk->sk_data_ready (sk); + }return !skb_queue_empty (&msk->receive_queue); }
Greg Kroah-Hartman
maintainerPATCH 82/95 hv: utils: handle and propagate errors in kvp_register
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
[ Upstream commit 3fcf923302a8f5c0dc3af3d2ca2657cb5fae4297 ]
Make kvp_register() return an error code instead of silently ignoring failures, and propagate the error from kvp_handle_handshake() instead of returning success.
This propagates both kzalloc_obj() and hvutil_transport_send() failures to kvp_handle_handshake() and thus to kvp_on_msg().
--- drivers/hv/hv_kvp.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-)
drivers/hv/hv_kvp.c +14 -13
@@ -93,7 +93,7 @@ static void kvp_send_key(struct work_strstatic void kvp_respond_to_host (struct hv_kvp_msg *msg,int error);static void kvp_timeout_func (struct work_struct *dummy);static void kvp_host_handshake_func (struct work_struct *dummy); -static void kvp_register (int ); +static int kvp_register (int ); static DECLARE_DELAYED_WORK(kvp_timeout_work, kvp_timeout_func); static DECLARE_DELAYED_WORK(kvp_host_handshake_work, kvp_host_handshake_func);
@@ -127,24 +127,26 @@ static void kvp_register_done(void)hv_poll_channel (kvp_transaction.recv_channel, kvp_poll_wrapper); } -static void +static int kvp_register (int reg_value) {struct hv_kvp_msg *kvp_msg;char *version; +int ret; kvp_msg =kzalloc (sizeof (*kvp_msg),GFP_KERNEL ); +if (!kvp_msg) +return -ENOMEM ; -if (kvp_msg) { - version = kvp_msg->body.kvp_register.version; - kvp_msg->kvp_hdr.operation = reg_value; -strcpy (version,HV_DRV_VERSION ); - -hvutil_transport_send (hvt, kvp_msg,sizeof (*kvp_msg), - kvp_register_done); -kfree (kvp_msg); - } + version = kvp_msg->body.kvp_register.version; + kvp_msg->kvp_hdr.operation = reg_value; +strcpy (version,HV_DRV_VERSION ); + + ret =hvutil_transport_send (hvt, kvp_msg,sizeof (*kvp_msg), + kvp_register_done); +kfree (kvp_msg); +return ret; }static void kvp_timeout_func (struct work_struct *dummy)
@@ -186,9 +188,8 @@ static int kvp_handle_handshake(struct h*/ pr_debug ("KVP: userspace daemon ver. %d connected\n" , msg->kvp_hdr.operation); -kvp_register (dm_reg_value); -return 0 ; +return kvp_register (dm_reg_value); }
Greg Kroah-Hartman
maintainerPATCH 83/95 misc: fastrpc: Add dma_mask to fastrpc_channel_ctx
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <[email protected]>
[ Upstream commit 9bde43a0e2f469961e18d0a3496a9a74379c22bf ]
dma_set_mask_and_coherent only updates the mask to which the device dma_mask pointer points to. Add a dma_mask to the channel ctx and set the device dma_mask to point to that, otherwise the dma_set_mask will return an error and the dma_set_coherent_mask will be skipped too.
Stable-dep-of: 5401fb4fe10f ("misc: fastrpc: Fix NULL pointer dereference in rpmsg callback")
--- drivers/misc/fastrpc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/misc/fastrpc.c +2 -0
@@ -214,6 +214,7 @@ struct fastrpc_channel_ctx {struct list_head users;struct miscdevice miscdev;struct kref refcount; +u64 dma_mask; };struct fastrpc_user {
@@ -1691,6 +1692,7 @@ static int fastrpc_rpmsg_probe(struct rpkref_init (&data->refcount);dev_set_drvdata (&rpdev->dev, data); + rdev->dma_mask = &data->dma_mask;dma_set_mask_and_coherent (rdev,DMA_BIT_MASK (32 ));INIT_LIST_HEAD (&data->users);spin_lock_init (&data->lock);
Greg Kroah-Hartman
maintainerPATCH 84/95 misc: fastrpc: Fix NULL pointer dereference in rpmsg callback
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Ojha <[email protected]>
[ Upstream commit 5401fb4fe10fac6134c308495df18ed74aebb9c4 ]
A NULL pointer dereference was observed on Hawi at boot when the DSP sends a glink message before fastrpc_rpmsg_probe() has completed initialization:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000178 pc : _raw_spin_lock_irqsave+0x34/0x8c lr : fastrpc_rpmsg_callback+0x3c/0xcc [fastrpc] ... Call trace: _raw_spin_lock_irqsave+0x34/0x8c (P) fastrpc_rpmsg_callback+0x3c/0xcc [fastrpc] qcom_glink_native_rx+0x538/0x6a4 qcom_glink_smem_intr+0x14/0x24 [qcom_glink_smem]
The faulting address 0x178 corresponds to the lock variable inside struct fastrpc_channel_ctx, confirming that cctx is NULL when fastrpc_rpmsg_callback() attempts to take the spinlock.
There are two issues here. First, dev_set_drvdata() is called before spin_lock_init() and idr_init(), leaving a window where the callback can retrieve a valid cctx pointer but operate on an uninitialized spinlock. Second, the rpmsg channel becomes live as soon as the driver is bound, so fastrpc_rpmsg_callback() can fire before dev_set_drvdata() is called at all, resulting in dev_get_drvdata() returning NULL.
Fix both issues by moving all cctx initialization ahead of dev_set_drvdata() so the structure is fully initialized before it becomes visible to the callback, and add a NULL check in fastrpc_rpmsg_callback() as a guard against any remaining window.
--- drivers/misc/fastrpc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/misc/fastrpc.c +4 -1
@@ -1691,7 +1691,6 @@ static int fastrpc_rpmsg_probe(struct rpkref_init (&data->refcount); -dev_set_drvdata (&rpdev->dev, data); rdev->dma_mask = &data->dma_mask;dma_set_mask_and_coherent (rdev,DMA_BIT_MASK (32 ));INIT_LIST_HEAD (&data->users);
@@ -1699,6 +1698,7 @@ static int fastrpc_rpmsg_probe(struct rpidr_init (&data->ctx_idr); data->domain_id = domain_id; data->rpdev = rpdev; +dev_set_drvdata (&rpdev->dev, data);return of_platform_populate (rdev->of_node,NULL ,NULL , rdev); }
@@ -1746,6 +1746,9 @@ static int fastrpc_rpmsg_callback(structif (len <sizeof (*rsp))return -EINVAL ; +if (!cctx) +return -ENODEV ; + ctxid = ((rsp->ctx &FASTRPC_CTXID_MASK ) >>4 );spin_lock_irqsave (&cctx->lock, flags);
Greg Kroah-Hartman
maintainerPATCH 85/95 Drivers: hv: vmbus: Improve the logic of reserving fb_mmio on Gen2 VMs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dexuan Cui <[email protected]>
[ Upstream commit 016a25e4b0df4d77e7c258edee4aaf982e4ee809 ]
If vmbus_reserve_fb() in the kdump/kexec kernel fails to properly reserve the framebuffer MMIO range (which is below 4GB) due to a Gen2 VM's screen.lfb_base being zero [1], there is an MMIO conflict between the drivers hyperv-drm and pci-hyperv: when the driver pci-hyperv's hv_allocate_config_window() calls vmbus_allocate_mmio() to get an MMIO range, typically it gets a 32-bit MMIO range that overlaps with the framebuffer MMIO range, and later hv_pci_enter_d0() fails with an error message "PCI Pass-through VSP failed D0 Entry with status" since the host thinks that PCI devices must not use MMIO space that the host has assigned to the framebuffer.
This is especially an issue if pci-hyperv is built-in and hyperv-drm is built as a module. Consequently, the kdump/kexec kernel fails to detect PCI devices via pci-hyperv, and may fail to mount the root file system, which may reside in a NVMe disk. The issue described here has existed for SR-IOV VF NICs since day one of the pci-hyperv driver, and has been worked around on x64 when possible. With the recent introduction of ARM64 VMs that boot from NVMe, there is no workaround, so we need a formal fix.
On Gen2 VMs, if the screen.lfb_base is 0 in the kdump/kexec kernel [1], fall back to the low MMIO base, which should be equal to the framebuffer MMIO base [2] (the statement is true according to my testing on x64 Windows Server 2016, and on x64 and ARM64 Windows Server 2025 and on Azure. I checked with the Hyper-V team and they said the statement should continue to be true for Gen2 VMs). In the first kernel, screen.lfb_base is not 0; if the user specifies a very high resolution, it's not enough to only reserve 8MB: let's always reserve half of the space below 4GB, but cap the reservation to 128MB, which is the required framebuffer size of the highest resolution 7680*4320 supported by Hyper-V.
While at it, fix the comparison "end > VTPM_BASE_ADDRESS" by changing the > to >=. Here the 'end' is an inclusive end (typically, it's 0xFFFF_FFFF for the low MMIO range).
Note: vmbus_reserve_fb() now also reserves an MMIO range at the beginning of the low MMIO range on CVMs, which have no framebuffers (the 'screen.lfb_base' in vmbus_reserve_fb() is 0 for CVMs), just in case the host might treat the beginning of the low MMIO range specially [3]. BTW, the OpenHCL kernel is not affected by the change, because that kernel boots with DeviceTree rather than ACPI (so vmbus_reserve_fb() won't run there), and there is no framebuffer device for that kernel.
Note: normally Gen1 VMs don't have the MMIO conflict issue because the framebuffer MMIO range (which is hardcoded to base=4GB-128MB and size=64MB for Gen1 VMs by the host) is always reported via the legacy PCI graphics device's BAR, so the kdump/kexec kernel can reserve the 64MB MMIO range; however, if the VM is configured to use a very high resolution and the required framebuffer size exceeds 64MB (AFAIK, in practice, this isn't a typical configuration by users), the hyperv-drm driver may need to allocate an MMIO range above 4GB and change the framebuffer MMIO location to the allocated MMIO range -- in this case, there can still be issues [4] which can't be easily fixed: any possible affected Gen1 users would have to use a resolution whose framebuffer size is <= 64MB, or switch to Gen2 VMs.
[1] https://lore.kernel.org/all/SA1PR21MB692176C1BC53BFC9EAE5CF8EBF51A@SA1PR21MB6921.namprd21.prod.outlook.com/
[2] https://lore.kernel.org/all/SA1PR21MB69218F955B62DFF62E3E88D2BF222@SA1PR21MB6921.namprd21.prod.outlook.com/
[3] https://lore.kernel.org/all/SN6PR02MB415726B17D5A6027CD1717E8D4342@SN6PR02MB4157.namprd02.prod.outlook.com/
[4] https://lore.kernel.org/all/SA1PR21MB69213486F821CA5A2C793C81BF342@SA1PR21MB6921.namprd21.prod.outlook.com/
--- drivers/hv/vmbus_drv.c | 56 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 15 deletions(-)
drivers/hv/vmbus_drv.c +41 -15
@@ -2222,8 +2222,8 @@ static acpi_status vmbus_walk_resources(return AE_NO_MEMORY ;/* If this range overlaps the virtual TPM, truncate it. */ -if (end >VTPM_BASE_ADDRESS && start <VTPM_BASE_ADDRESS ) - end =VTPM_BASE_ADDRESS ; +if (end >=VTPM_BASE_ADDRESS && start <VTPM_BASE_ADDRESS ) + end =VTPM_BASE_ADDRESS -1 ; new_res->name ="hyperv mmio" ; new_res->flags =IORESOURCE_MEM ;
@@ -2290,26 +2290,52 @@ static int vmbus_acpi_remove(struct acpistatic void vmbus_reserve_fb (void ) { -int size; +resource_size_t start =0 , size; +resource_size_t low_mmio_base; + +if (efi_enabled (EFI_BOOT )) { +/* Gen2 VM: get FB base from EFI framebuffer */ + start = screen_info.lfb_base; + size =max_t (__u32, screen_info.lfb_size,0x800000 ); + + low_mmio_base = hyperv_mmio->start; +if (!low_mmio_base ||upper_32_bits (low_mmio_base) || + (start && start < low_mmio_base)) { +pr_warn ("Unexpected low mmio base %pa\n" , &low_mmio_base); + }else { +/* +* If the kdump/kexec or CVM kernel's lfb_base +* is 0, fall back to the low mmio base. +*/ +if (!start) + start = low_mmio_base; +/* +* Reserve half of the space below 4GB for high +* resolutions, but cap the reservation to 128MB. +*/ + size =min ((SZ_4G - start) /2 ,SZ_128M ); + } + }else { +/* Gen1 VM: get FB base from screen_info */ + start = screen_info.lfb_base; + size =max_t (__u32, screen_info.lfb_size,0x4000000 ); + } + +if (!start) { +pr_warn ("Unexpected framebuffer mmio base of zero\n" ); +return ; + } +/* * Make a claim for the frame buffer in the resource tree under the * first node, which will be the one below 4GB. The length seems to * be underreported, particularly in a Generation 1 VM. So start out * reserving a larger area and make it smaller until it succeeds. */ +for (; !fb_mmio && (size >=0x100000 ); size >>=1 ) + fb_mmio =__request_region (hyperv_mmio, start, size, fb_mmio_name,0 ); -if (screen_info.lfb_base) { -if (efi_enabled (EFI_BOOT )) - size =max_t (__u32, screen_info.lfb_size,0x800000 ); -else - size =max_t (__u32, screen_info.lfb_size,0x4000000 ); - -for (; !fb_mmio && (size >=0x100000 ); size >>=1 ) { - fb_mmio =__request_region (hyperv_mmio, - screen_info.lfb_base, size, - fb_mmio_name,0 ); - } - } +pr_info ("hv_mmio=%pR,%pR fb=%pR\n" , hyperv_mmio, hyperv_mmio->sibling, fb_mmio); }/**
Greg Kroah-Hartman
maintainerPATCH 86/95 phonet: Pass ifindex to fill_addr().
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 08a9572be36819b5d9011604edfa5db6c5062a7a ]
We will convert addr_doit() and getaddr_dumpit() to RCU, both of which call fill_addr().
The former will call phonet_address_notify() outside of RCU due to GFP_KERNEL, so dev will not be available in fill_addr().
Let's pass ifindex directly to fill_addr().
Stable-dep-of: 71de0177b28d ("net: phonet: free phonet_device after RCU grace period")
--- net/phonet/pn_netlink.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
net/phonet/pn_netlink.c +7 -6
@@ -19,7 +19,7 @@/* Device address handling */ -static int fill_addr (struct sk_buff *skb,struct net_device *dev,u8 addr, +static int fill_addr (struct sk_buff *skb,u32 ifindex,u8 addr,u32 portid,u32 seq,int event);void phonet_address_notify (int event,struct net_device *dev,u8 addr)
@@ -31,7 +31,8 @@ void phonet_address_notify(int event, st nla_total_size(1), GFP_KERNEL);if (skb ==NULL ) goto errout; - err =fill_addr (skb, dev, addr,0 ,0 , event); + + err =fill_addr (skb, dev->ifindex, addr,0 ,0 , event);if (err <0 ) {WARN_ON (err == -EMSGSIZE );kfree_skb (skb);
@@ -92,8 +93,8 @@ static int addr_doit(struct sk_buff *skbreturn err; } -static int fill_addr (struct sk_buff *skb,struct net_device *dev,u8 addr, -u32 portid,u32 seq,int event) +static int fill_addr (struct sk_buff *skb,u32 ifindex,u8 addr, +u32 portid,u32 seq,int event) {struct ifaddrmsg *ifm;struct nlmsghdr *nlh;
@@ -107,7 +108,7 @@ static int fill_addr(struct sk_buff *skb ifm->ifa_prefixlen =0 ; ifm->ifa_flags =IFA_F_PERMANENT ; ifm->ifa_scope =RT_SCOPE_LINK ; - ifm->ifa_index = dev->ifindex; + ifm->ifa_index = ifindex;if (nla_put_u8 (skb,IFA_LOCAL , addr)) goto nla_put_failure;nlmsg_end (skb, nlh);
@@ -140,7 +141,7 @@ static int getaddr_dumpit(struct sk_buffif (addr_idx++ < addr_start_idx)continue ; -if (fill_addr (skb, pnd->netdev, addr <<2 , +if (fill_addr (skb, pnd->netdev->ifindex, addr <<2 ,NETLINK_CB (cb->skb).portid, cb->nlh->nlmsg_seq,RTM_NEWADDR ) <0 ) goto out;
Greg Kroah-Hartman
maintainerPATCH 87/95 phonet: Pass net and ifindex to phonet_address_notify().
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 68ed5c38b512b734caf3da1f87db4a99fcfe3002 ]
Currently, phonet_address_notify() fetches netns and ifindex from dev.
Once addr_doit() is converted to RCU, phonet_address_notify() will be called outside of RCU due to GFP_KERNEL, and dev will be unavailable there.
Let's pass net and ifindex to phonet_address_notify().
Stable-dep-of: 71de0177b28d ("net: phonet: free phonet_device after RCU grace period")
--- include/net/phonet/pn_dev.h | 2 +- net/phonet/pn_dev.c | 10 +++++++--- net/phonet/pn_netlink.c | 12 ++++++------ 3 files changed, 14 insertions(+), 10 deletions(-)
include/net/phonet/pn_dev.h +1 -1
@@ -33,7 +33,7 @@ int phonet_address_add(struct net_deviceint phonet_address_del (struct net_device *dev,u8 addr);u8 phonet_address_get (struct net_device *dev,u8 addr);int phonet_address_lookup (struct net *net,u8 addr); -void phonet_address_notify (int event,struct net_device *dev,u8 addr); +void phonet_address_notify (struct net *net,int event,u32 ifindex,u8 addr);int phonet_route_add (struct net_device *dev,u8 daddr);int phonet_route_del (struct net_device *dev,u8 daddr);
net/phonet/pn_dev.c +7 -3
@@ -98,10 +98,13 @@ static void phonet_device_destroy(structmutex_unlock (&pndevs->lock);if (pnd) { +struct net *net =dev_net (dev); +u32 ifindex = dev->ifindex;u8 addr;for_each_set_bit (addr, pnd->addrs,64 ) -phonet_address_notify (RTM_DELADDR , dev, addr); +phonet_address_notify (net,RTM_DELADDR , ifindex, addr); +kfree (pnd); } }
@@ -244,8 +247,9 @@ static int phonet_device_autoconf(struct ret =phonet_address_add (dev, req.ifr_phonet_autoconf.device);if (ret)return ret; -phonet_address_notify (RTM_NEWADDR , dev, - req.ifr_phonet_autoconf.device); + +phonet_address_notify (dev_net (dev),RTM_NEWADDR , dev->ifindex, + req.ifr_phonet_autoconf.device);return 0 ; }
net/phonet/pn_netlink.c +6 -6
@@ -22,7 +22,7 @@static int fill_addr (struct sk_buff *skb,u32 ifindex,u8 addr,u32 portid,u32 seq,int event); -void phonet_address_notify (int event,struct net_device *dev,u8 addr) +void phonet_address_notify (struct net *net,int event,u32 ifindex,u8 addr) {struct sk_buff *skb;int err = -ENOBUFS ;
@@ -32,17 +32,17 @@ void phonet_address_notify(int event, stif (skb ==NULL ) goto errout; - err =fill_addr (skb, dev->ifindex, addr,0 ,0 , event); + err =fill_addr (skb, ifindex, addr,0 ,0 , event);if (err <0 ) {WARN_ON (err == -EMSGSIZE );kfree_skb (skb); goto errout; } -rtnl_notify (skb,dev_net (dev),0 , -RTNLGRP_PHONET_IFADDR ,NULL ,GFP_KERNEL ); + +rtnl_notify (skb, net,0 ,RTNLGRP_PHONET_IFADDR ,NULL ,GFP_KERNEL );return ; errout: -rtnl_set_sk_err (dev_net (dev),RTNLGRP_PHONET_IFADDR , err); +rtnl_set_sk_err (net,RTNLGRP_PHONET_IFADDR , err); }static const struct nla_policy ifa_phonet_policy[IFA_MAX +1 ] = {
@@ -89,7 +89,7 @@ static int addr_doit(struct sk_buff *skbelse err =phonet_address_del (dev, pnaddr);if (!err) -phonet_address_notify (nlh->nlmsg_type, dev, pnaddr); +phonet_address_notify (net, nlh->nlmsg_type, ifm->ifa_index, pnaddr);return err; }
Greg Kroah-Hartman
maintainerPATCH 88/95 net: phonet: free phonet_device after RCU grace period
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Santosh Kalluri <[email protected]>
[ Upstream commit 71de0177b28da751f407581a4515cf4d762f6296 ]
phonet_device_destroy() removes a phonet_device from the per-net device list with list_del_rcu(), but frees it immediately. RCU readers walking the same list can still hold a pointer to the object after it has been removed, leading to a slab-use-after-free.
Use kfree_rcu(), matching the lifetime rule already used by phonet_address_del() for the same object type.
--- net/phonet/pn_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/phonet/pn_dev.c +1 -1
@@ -105,7 +105,7 @@ static void phonet_device_destroy(structfor_each_set_bit (addr, pnd->addrs,64 )phonet_address_notify (net,RTM_DELADDR , ifindex, addr); -kfree (pnd); +kfree_rcu (pnd, rcu); } }
Greg Kroah-Hartman
maintainerPATCH 89/95 fuse: re-lock request before replacing page cache folio
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joanne Koong <[email protected]>
[ Upstream commit a078484921052d0badd827fcc2770b5cfc1d4120 ]
fuse_try_move_folio() unlocks the request on entry but does not re-lock it on the success path. This means fuse_chan_abort() can end the request and free the fuse_io_args (eg fuse_readpages_end()) while the subsequent copy chain logic after fuse_try_move_folio() accesses the fuse_io_args, leading to use-after-free issues.
Fix this by calling lock_request() before replace_page_cache_folio(). This ensures the request is locked on the success path which will prevent the fuse_io_args from being freed while the later copying logic runs, and also ensures that the ap->folios[i]->mapping is never null since ap->folios[i] will always point to the newfolio after replace_page_cache_folio().
--- fs/fuse/dev.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-)
fs/fuse/dev.c +5 -14
@@ -845,6 +845,10 @@ static int fuse_try_move_page(struct fusif (WARN_ON (PageMlocked (oldpage))) goto out_fallback_unlock; + err =lock_request (cs->req); +if (err) + goto out_fallback_unlock; +replace_page_cache_page (oldpage, newpage);get_page (newpage);
@@ -858,20 +862,7 @@ static int fuse_try_move_page(struct fus*/ pipe_buf_release (cs->pipe, buf); - err =0 ; -spin_lock (&cs->req->waitq.lock); -if (test_bit (FR_ABORTED , &cs->req->flags)) - err = -ENOENT ; -else - *pagep = newpage; -spin_unlock (&cs->req->waitq.lock); - -if (err) { -unlock_page (newpage); -put_page (newpage); - goto out_put_old; - } - + *pagep = newpage;unlock_page (oldpage);/* Drop ref for ap->pages[] array */ put_page (oldpage);
Greg Kroah-Hartman
maintainerPATCH 90/95 ksmbd: reject non-VALID session in compound request branch
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gil Portnoy <[email protected]>
[ Upstream commit 609ca17d869d04ba249e32cdcbf13c0b1c66f43c ]
smb2_check_user_session() takes a shortcut for any operation that is not the first in a COMPOUND request: it reuses work->sess (the session bound by the first operation) and validates only the SessionId, then returns "valid". It never re-checks work->sess->state == SMB2_SESSION_VALID, and a SessionId of 0xFFFFFFFFFFFFFFFF (ULLONG_MAX, the MS-SMB2 related-operation value) skips even the id comparison. The standalone path (ksmbd_session_lookup_all() plus the SESSION_SETUP state machine) does enforce the VALID state; the compound branch bypasses all of it.
A SESSION_SETUP carrying only an NTLM Type-1 (NtLmNegotiate) blob publishes a fresh SMB2_SESSION_IN_PROGRESS session whose sess->user is still NULL (->user is assigned later, by ntlm_authenticate()). Used as operation 1 of a COMPOUND with operation 2 = TREE_CONNECT (related, SessionId=ULLONG_MAX, \\host\IPC$), the tree-connect then runs on that IN_PROGRESS session and reaches ksmbd_ipc_tree_connect_request(), which dereferences user_name(sess->user) with sess->user == NULL (transport_ipc.c:687/701/704) -> remote NULL-pointer dereference and a kernel Oops that wedges the ksmbd worker for all clients.
Reject any non-first compound operation that lands on a session which is not SMB2_SESSION_VALID, mirroring the validity the standalone lookup path enforces. SESSION_SETUP itself legitimately runs on an IN_PROGRESS session, but it is never carried as a non-first compound operation, so multi-leg authentication is unaffected by this check.
--- fs/ksmbd/smb2pdu.c | 5 +++++ 1 file changed, 5 insertions(+)
fs/ksmbd/smb2pdu.c +5 -0
@@ -606,6 +606,11 @@ int smb2_check_user_session(struct ksmbd sess_id, work->sess->id);return -EINVAL ; } +if (work->sess->state !=SMB2_SESSION_VALID ) { +pr_err ("compound request on a non-valid session (state %d)\n" , + work->sess->state); +return -EINVAL ; + }return 1 ; }
Greg Kroah-Hartman
maintainerPATCH 91/95 Documentation: ioctl-number: Extend "Include File" column width
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bagas Sanjaya <[email protected]>
[ Upstream commit 15afd5def819e4df2a29cef6fcfa6ae7ba167c0f ]
Extend width of "Include File" column to fit full path to papr-physical-attestation.h in later commit.
Stable-dep-of: d237230728c5 ("crypto: qat - remove unused character device and IOCTLs")
--- Documentation/userspace-api/ioctl/ioctl-number.rst | 448 ++++++++++----------- 1 file changed, 224 insertions(+), 224 deletions(-)
Documentation/userspace-api/ioctl/ioctl-number.rst +224 -224
@@ -66,17 +66,17 @@ This table lists ioctls visible from use most drivers up to 2.6.31, but I know I am missing some. There has been no attempt to list non-X86 architectures or ioctls from drivers/staging/. -==== ===== ======================================================= ================================================================ -Code Seq# Include File Comments +==== ===== ========================================================= ================================================================ +Code Seq# Include File Comments (hex) -==== ===== ======================================================= ================================================================ -0x00 00-1F linux/fs.h conflict! -0x00 00-1F scsi/scsi_ioctl.h conflict! -0x00 00-1F linux/fb.h conflict! -0x00 00-1F linux/wavefront.h conflict! +==== ===== ========================================================= ================================================================ +0x00 00-1F linux/fs.h conflict! +0x00 00-1F scsi/scsi_ioctl.h conflict! +0x00 00-1F linux/fb.h conflict! +0x00 00-1F linux/wavefront.h conflict! 0x02 all linux/fd.h 0x03 all linux/hdreg.h -0x04 D2-DC linux/umsdos_fs.h Dead since 2.6.11, but don't reuse these. +0x04 D2-DC linux/umsdos_fs.h Dead since 2.6.11, but don't reuse these. 0x06 all linux/lp.h 0x09 all linux/raid/md_u.h 0x10 00-0F drivers/char/s390/vmcp.h
@@ -84,291 +84,291 @@ Code Seq# Include File 0x10 20-2F arch/s390/include/uapi/asm/hypfs.h 0x12 all linux/fs.h linux/blkpg.h -0x1b all InfiniBand Subsystem - <http://infiniband.sourceforge.net/> +0x1b all InfiniBand Subsystem + <http://infiniband.sourceforge.net/> 0x20 all drivers/cdrom/cm206.h 0x22 all scsi/sg.h '!' 00-1F uapi/linux/seccomp.h -'#' 00-3F IEEE 1394 Subsystem - Block for the entire subsystem +'#' 00-3F IEEE 1394 Subsystem + Block for the entire subsystem '$' 00-0F linux/perf_counter.h, linux/perf_event.h -'%' 00-0F include/uapi/linux/stm.h System Trace Module subsystem - <mailto:[email protected]> +'%' 00-0F include/uapi/linux/stm.h System Trace Module subsystem + <mailto:[email protected]> '&' 00-07 drivers/firewire/nosy-user.h -'1' 00-1F linux/timepps.h PPS kit from Ulrich Windl - <ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/> +'1' 00-1F linux/timepps.h PPS kit from Ulrich Windl + <ftp://ftp.de.kernel.org/pub/linux/daemons/ntp/PPS/> '2' 01-04 linux/i2o.h -'3' 00-0F drivers/s390/char/raw3270.h conflict! -'3' 00-1F linux/suspend_ioctls.h, conflict! +'3' 00-0F drivers/s390/char/raw3270.h conflict! +'3' 00-1F linux/suspend_ioctls.h, conflict! kernel/power/user.c -'8' all SNP8023 advanced NIC card - <mailto:[email protected]> +'8' all SNP8023 advanced NIC card + <mailto:[email protected]> ';' 64-7F linux/vfio.h -'=' 00-3f uapi/linux/ptp_clock.h <mailto:[email protected]> -'@' 00-0F linux/radeonfb.h conflict! -'@' 00-0F drivers/video/aty/aty128fb.c conflict! -'A' 00-1F linux/apm_bios.h conflict! -'A' 00-0F linux/agpgart.h, conflict! +'=' 00-3f uapi/linux/ptp_clock.h <mailto:[email protected]> +'@' 00-0F linux/radeonfb.h conflict! +'@' 00-0F drivers/video/aty/aty128fb.c conflict! +'A' 00-1F linux/apm_bios.h conflict! +'A' 00-0F linux/agpgart.h, conflict! drivers/char/agp/compat_ioctl.h -'A' 00-7F sound/asound.h conflict! -'B' 00-1F linux/cciss_ioctl.h conflict! -'B' 00-0F include/linux/pmu.h conflict! -'B' C0-FF advanced bbus <mailto:[email protected]> -'C' all linux/soundcard.h conflict! -'C' 01-2F linux/capi.h conflict! -'C' F0-FF drivers/net/wan/cosa.h conflict! +'A' 00-7F sound/asound.h conflict! +'B' 00-1F linux/cciss_ioctl.h conflict! +'B' 00-0F include/linux/pmu.h conflict! +'B' C0-FF advanced bbus <mailto:[email protected]> +'C' all linux/soundcard.h conflict! +'C' 01-2F linux/capi.h conflict! +'C' F0-FF drivers/net/wan/cosa.h conflict! 'D' all arch/s390/include/asm/dasd.h 'D' 40-5F drivers/scsi/dpt/dtpi_ioctl.h 'D' 05 drivers/scsi/pmcraid.h -'E' all linux/input.h conflict! -'E' 00-0F xen/evtchn.h conflict! -'F' all linux/fb.h conflict! -'F' 01-02 drivers/scsi/pmcraid.h conflict! -'F' 20 drivers/video/fsl-diu-fb.h conflict! -'F' 20 drivers/video/intelfb/intelfb.h conflict! -'F' 20 linux/ivtvfb.h conflict! -'F' 20 linux/matroxfb.h conflict! -'F' 20 drivers/video/aty/atyfb_base.c conflict! -'F' 00-0F video/da8xx-fb.h conflict! -'F' 80-8F linux/arcfb.h conflict! -'F' DD video/sstfb.h conflict! -'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict! -'H' 00-7F linux/hiddev.h conflict! -'H' 00-0F linux/hidraw.h conflict! -'H' 01 linux/mei.h conflict! -'H' 02 linux/mei.h conflict! -'H' 03 linux/mei.h conflict! -'H' 00-0F sound/asound.h conflict! -'H' 20-40 sound/asound_fm.h conflict! -'H' 80-8F sound/sfnt_info.h conflict! -'H' 10-8F sound/emu10k1.h conflict! -'H' 10-1F sound/sb16_csp.h conflict! -'H' 10-1F sound/hda_hwdep.h conflict! -'H' 40-4F sound/hdspm.h conflict! -'H' 40-4F sound/hdsp.h conflict! +'E' all linux/input.h conflict! +'E' 00-0F xen/evtchn.h conflict! +'F' all linux/fb.h conflict! +'F' 01-02 drivers/scsi/pmcraid.h conflict! +'F' 20 drivers/video/fsl-diu-fb.h conflict! +'F' 20 drivers/video/intelfb/intelfb.h conflict! +'F' 20 linux/ivtvfb.h conflict! +'F' 20 linux/matroxfb.h conflict! +'F' 20 drivers/video/aty/atyfb_base.c conflict! +'F' 00-0F video/da8xx-fb.h conflict! +'F' 80-8F linux/arcfb.h conflict! +'F' DD video/sstfb.h conflict! +'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict! +'H' 00-7F linux/hiddev.h conflict! +'H' 00-0F linux/hidraw.h conflict! +'H' 01 linux/mei.h conflict! +'H' 02 linux/mei.h conflict! +'H' 03 linux/mei.h conflict! +'H' 00-0F sound/asound.h conflict! +'H' 20-40 sound/asound_fm.h conflict! +'H' 80-8F sound/sfnt_info.h conflict! +'H' 10-8F sound/emu10k1.h conflict! +'H' 10-1F sound/sb16_csp.h conflict! +'H' 10-1F sound/hda_hwdep.h conflict! +'H' 40-4F sound/hdspm.h conflict! +'H' 40-4F sound/hdsp.h conflict! 'H' 90 sound/usb/usx2y/usb_stream.h -'H' 00-0F uapi/misc/habanalabs.h conflict! +'H' 00-0F uapi/misc/habanalabs.h conflict! 'H' A0 uapi/linux/usb/cdc-wdm.h -'H' C0-F0 net/bluetooth/hci.h conflict! -'H' C0-DF net/bluetooth/hidp/hidp.h conflict! -'H' C0-DF net/bluetooth/cmtp/cmtp.h conflict! -'H' C0-DF net/bluetooth/bnep/bnep.h conflict! -'H' F1 linux/hid-roccat.h <mailto:[email protected]> +'H' C0-F0 net/bluetooth/hci.h conflict! +'H' C0-DF net/bluetooth/hidp/hidp.h conflict! +'H' C0-DF net/bluetooth/cmtp/cmtp.h conflict! +'H' C0-DF net/bluetooth/bnep/bnep.h conflict! +'H' F1 linux/hid-roccat.h <mailto:[email protected]> 'H' F8-FA sound/firewire.h -'I' all linux/isdn.h conflict! -'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict! -'I' 40-4F linux/mISDNif.h conflict! +'I' all linux/isdn.h conflict! +'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict! +'I' 40-4F linux/mISDNif.h conflict! 'K' all linux/kd.h -'L' 00-1F linux/loop.h conflict! -'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict! -'L' E0-FF linux/ppdd.h encrypted disk device driver - <http://linux01.gwdg.de/~alatham/ppdd.html> -'M' all linux/soundcard.h conflict! -'M' 01-16 mtd/mtd-abi.h conflict! +'L' 00-1F linux/loop.h conflict! +'L' 10-1F drivers/scsi/mpt3sas/mpt3sas_ctl.h conflict! +'L' E0-FF linux/ppdd.h encrypted disk device driver + <http://linux01.gwdg.de/~alatham/ppdd.html> +'M' all linux/soundcard.h conflict! +'M' 01-16 mtd/mtd-abi.h conflict! and drivers/mtd/mtdchar.c 'M' 01-03 drivers/scsi/megaraid/megaraid_sas.h -'M' 00-0F drivers/video/fsl-diu-fb.h conflict! +'M' 00-0F drivers/video/fsl-diu-fb.h conflict! 'N' 00-1F drivers/usb/scanner.h 'N' 40-7F drivers/block/nvme.c -'O' 00-06 mtd/ubi-user.h UBI -'P' all linux/soundcard.h conflict! -'P' 60-6F sound/sscape_ioctl.h conflict! -'P' 00-0F drivers/usb/class/usblp.c conflict! -'P' 01-09 drivers/misc/pci_endpoint_test.c conflict! +'O' 00-06 mtd/ubi-user.h UBI +'P' all linux/soundcard.h conflict! +'P' 60-6F sound/sscape_ioctl.h conflict! +'P' 00-0F drivers/usb/class/usblp.c conflict! +'P' 01-09 drivers/misc/pci_endpoint_test.c conflict! 'Q' all linux/soundcard.h -'R' 00-1F linux/random.h conflict! -'R' 01 linux/rfkill.h conflict! +'R' 00-1F linux/random.h conflict! +'R' 01 linux/rfkill.h conflict! 'R' C0-DF net/bluetooth/rfcomm.h 'R' E0 uapi/linux/fsl_mc.h -'S' all linux/cdrom.h conflict! -'S' 80-81 scsi/scsi_ioctl.h conflict! -'S' 82-FF scsi/scsi.h conflict! -'S' 00-7F sound/asequencer.h conflict! -'T' all linux/soundcard.h conflict! -'T' 00-AF sound/asound.h conflict! -'T' all arch/x86/include/asm/ioctls.h conflict! -'T' C0-DF linux/if_tun.h conflict! -'U' all sound/asound.h conflict! -'U' 00-CF linux/uinput.h conflict! +'S' all linux/cdrom.h conflict! +'S' 80-81 scsi/scsi_ioctl.h conflict! +'S' 82-FF scsi/scsi.h conflict! +'S' 00-7F sound/asequencer.h conflict! +'T' all linux/soundcard.h conflict! +'T' 00-AF sound/asound.h conflict! +'T' all arch/x86/include/asm/ioctls.h conflict! +'T' C0-DF linux/if_tun.h conflict! +'U' all sound/asound.h conflict! +'U' 00-CF linux/uinput.h conflict! 'U' 00-EF linux/usbdevice_fs.h 'U' C0-CF drivers/bluetooth/hci_uart.h -'V' all linux/vt.h conflict! -'V' all linux/videodev2.h conflict! -'V' C0 linux/ivtvfb.h conflict! -'V' C0 linux/ivtv.h conflict! -'V' C0 media/davinci/vpfe_capture.h conflict! -'V' C0 media/si4713.h conflict! -'W' 00-1F linux/watchdog.h conflict! -'W' 00-1F linux/wanrouter.h conflict! (pre 3.9) -'W' 00-3F sound/asound.h conflict! +'V' all linux/vt.h conflict! +'V' all linux/videodev2.h conflict! +'V' C0 linux/ivtvfb.h conflict! +'V' C0 linux/ivtv.h conflict! +'V' C0 media/davinci/vpfe_capture.h conflict! +'V' C0 media/si4713.h conflict! +'W' 00-1F linux/watchdog.h conflict! +'W' 00-1F linux/wanrouter.h conflict! (pre 3.9) +'W' 00-3F sound/asound.h conflict! 'W' 40-5F drivers/pci/switch/switchtec.c 'W' 60-61 linux/watch_queue.h -'X' all fs/xfs/xfs_fs.h, conflict! +'X' all fs/xfs/xfs_fs.h, conflict! fs/xfs/linux-2.6/xfs_ioctl32.h, include/linux/falloc.h, linux/fs.h, -'X' all fs/ocfs2/ocfs_fs.h conflict! -'X' 01 linux/pktcdvd.h conflict! +'X' all fs/ocfs2/ocfs_fs.h conflict! +'X' 01 linux/pktcdvd.h conflict! 'Z' 14-15 drivers/message/fusion/mptctl.h -'[' 00-3F linux/usb/tmc.h USB Test and Measurement Devices - <mailto:[email protected]> -'a' all linux/atm*.h, linux/sonet.h ATM on linux - <http://lrcwww.epfl.ch/> -'a' 00-0F drivers/crypto/qat/qat_common/adf_cfg_common.h conflict! qat driver -'b' 00-FF conflict! bit3 vme host bridge - <mailto:[email protected]> -'c' all linux/cm4000_cs.h conflict! -'c' 00-7F linux/comstats.h conflict! -'c' 00-7F linux/coda.h conflict! -'c' 00-1F linux/chio.h conflict! -'c' 80-9F arch/s390/include/asm/chsc.h conflict! +'[' 00-3F linux/usb/tmc.h USB Test and Measurement Devices + <mailto:[email protected]> +'a' all linux/atm*.h, linux/sonet.h ATM on linux + <http://lrcwww.epfl.ch/> +'a' 00-0F drivers/crypto/qat/qat_common/adf_cfg_common.h conflict! qat driver +'b' 00-FF conflict! bit3 vme host bridge + <mailto:[email protected]> +'c' all linux/cm4000_cs.h conflict! +'c' 00-7F linux/comstats.h conflict! +'c' 00-7F linux/coda.h conflict! +'c' 00-1F linux/chio.h conflict! +'c' 80-9F arch/s390/include/asm/chsc.h conflict! 'c' A0-AF arch/x86/include/asm/msr.h conflict! -'d' 00-FF linux/char/drm/drm.h conflict! -'d' 02-40 pcmcia/ds.h conflict! +'d' 00-FF linux/char/drm/drm.h conflict! +'d' 02-40 pcmcia/ds.h conflict! 'd' F0-FF linux/digi1.h -'e' all linux/digi1.h conflict! -'f' 00-1F linux/ext2_fs.h conflict! -'f' 00-1F linux/ext3_fs.h conflict! -'f' 00-0F fs/jfs/jfs_dinode.h conflict! -'f' 00-0F fs/ext4/ext4.h conflict! -'f' 00-0F linux/fs.h conflict! -'f' 00-0F fs/ocfs2/ocfs2_fs.h conflict! +'e' all linux/digi1.h conflict! +'f' 00-1F linux/ext2_fs.h conflict! +'f' 00-1F linux/ext3_fs.h conflict! +'f' 00-0F fs/jfs/jfs_dinode.h conflict! +'f' 00-0F fs/ext4/ext4.h conflict! +'f' 00-0F linux/fs.h conflict! +'f' 00-0F fs/ocfs2/ocfs2_fs.h conflict! 'f' 13-27 linux/fscrypt.h 'f' 81-8F linux/fsverity.h 'g' 00-0F linux/usb/gadgetfs.h 'g' 20-2F linux/usb/g_printer.h -'h' 00-7F conflict! Charon filesystem - <mailto:[email protected]> -'h' 00-1F linux/hpet.h conflict! +'h' 00-7F conflict! Charon filesystem + <mailto:[email protected]> +'h' 00-1F linux/hpet.h conflict! 'h' 80-8F fs/hfsplus/ioctl.c -'i' 00-3F linux/i2o-dev.h conflict! -'i' 0B-1F linux/ipmi.h conflict! +'i' 00-3F linux/i2o-dev.h conflict! +'i' 0B-1F linux/ipmi.h conflict! 'i' 80-8F linux/i8k.h -'i' 90-9F `linux/iio/*.h` IIO +'i' 90-9F `linux/iio/*.h` IIO 'j' 00-3F linux/joystick.h -'k' 00-0F linux/spi/spidev.h conflict! -'k' 00-05 video/kyro.h conflict! -'k' 10-17 linux/hsi/hsi_char.h HSI character device -'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system - <http://web.archive.org/web/%2A/http://mikonos.dia.unisa.it/tcfs> -'l' 40-7F linux/udf_fs_i.h in development: - <http://sourceforge.net/projects/linux-udf/> -'m' 00-09 linux/mmtimer.h conflict! -'m' all linux/mtio.h conflict! -'m' all linux/soundcard.h conflict! -'m' all linux/synclink.h conflict! -'m' 00-19 drivers/message/fusion/mptctl.h conflict! -'m' 00 drivers/scsi/megaraid/megaraid_ioctl.h conflict! +'k' 00-0F linux/spi/spidev.h conflict! +'k' 00-05 video/kyro.h conflict! +'k' 10-17 linux/hsi/hsi_char.h HSI character device +'l' 00-3F linux/tcfs_fs.h transparent cryptographic file system + <http://web.archive.org/web/%2A/http://mikonos.dia.unisa.it/tcfs> +'l' 40-7F linux/udf_fs_i.h in development: + <http://sourceforge.net/projects/linux-udf/> +'m' 00-09 linux/mmtimer.h conflict! +'m' all linux/mtio.h conflict! +'m' all linux/soundcard.h conflict! +'m' all linux/synclink.h conflict! +'m' 00-19 drivers/message/fusion/mptctl.h conflict! +'m' 00 drivers/scsi/megaraid/megaraid_ioctl.h conflict! 'n' 00-7F linux/ncp_fs.h and fs/ncpfs/ioctl.c -'n' 80-8F uapi/linux/nilfs2_api.h NILFS2 -'n' E0-FF linux/matroxfb.h matroxfb -'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 -'o' 00-03 mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps) -'o' 40-41 mtd/ubi-user.h UBI -'o' 01-A1 `linux/dvb/*.h` DVB -'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) -'p' 00-1F linux/rtc.h conflict! +'n' 80-8F uapi/linux/nilfs2_api.h NILFS2 +'n' E0-FF linux/matroxfb.h matroxfb +'o' 00-1F fs/ocfs2/ocfs2_fs.h OCFS2 +'o' 00-03 mtd/ubi-user.h conflict! (OCFS2 and UBI overlaps) +'o' 40-41 mtd/ubi-user.h UBI +'o' 01-A1 `linux/dvb/*.h` DVB +'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) +'p' 00-1F linux/rtc.h conflict! 'p' 40-7F linux/nvram.h -'p' 80-9F linux/ppdev.h user-space parport - <mailto:[email protected]> -'p' A1-A5 linux/pps.h LinuxPPS - <mailto:[email protected]> +'p' 80-9F linux/ppdev.h user-space parport + <mailto:[email protected]> +'p' A1-A5 linux/pps.h LinuxPPS + <mailto:[email protected]> 'q' 00-1F linux/serio.h -'q' 80-FF linux/telephony.h Internet PhoneJACK, Internet LineJACK - linux/ixjuser.h <http://web.archive.org/web/%2A/http://www.quicknet.net> +'q' 80-FF linux/telephony.h Internet PhoneJACK, Internet LineJACK + linux/ixjuser.h <http://web.archive.org/web/%2A/http://www.quicknet.net> 'r' 00-1F linux/msdos_fs.h and fs/fat/dir.c 's' all linux/cdk.h 't' 00-7F linux/ppp-ioctl.h 't' 80-8F linux/isdn_ppp.h -'t' 90-91 linux/toshiba.h toshiba and toshiba_acpi SMM -'u' 00-1F linux/smb_fs.h gone -'u' 20-3F linux/uvcvideo.h USB video class host driver -'u' 40-4f linux/udmabuf.h userspace dma-buf misc device -'v' 00-1F linux/ext2_fs.h conflict! -'v' 00-1F linux/fs.h conflict! -'v' 00-0F linux/sonypi.h conflict! -'v' 00-0F media/v4l2-subdev.h conflict! -'v' 20-27 arch/powerpc/include/uapi/asm/vas-api.h VAS API -'v' C0-FF linux/meye.h conflict! -'w' all CERN SCI driver -'y' 00-1F packet based user level communications - <mailto:[email protected]> -'z' 00-3F CAN bus card conflict! - <mailto:[email protected]> -'z' 40-7F CAN bus card conflict! - <mailto:[email protected]> -'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! +'t' 90-91 linux/toshiba.h toshiba and toshiba_acpi SMM +'u' 00-1F linux/smb_fs.h gone +'u' 20-3F linux/uvcvideo.h USB video class host driver +'u' 40-4f linux/udmabuf.h userspace dma-buf misc device +'v' 00-1F linux/ext2_fs.h conflict! +'v' 00-1F linux/fs.h conflict! +'v' 00-0F linux/sonypi.h conflict! +'v' 00-0F media/v4l2-subdev.h conflict! +'v' 20-27 arch/powerpc/include/uapi/asm/vas-api.h VAS API +'v' C0-FF linux/meye.h conflict! +'w' all CERN SCI driver +'y' 00-1F packet based user level communications + <mailto:[email protected]> +'z' 00-3F CAN bus card conflict! + <mailto:[email protected]> +'z' 40-7F CAN bus card conflict! + <mailto:[email protected]> +'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! '|' 00-7F linux/media.h 0x80 00-1F linux/fb.h 0x81 00-1F linux/vduse.h 0x89 00-06 arch/x86/include/asm/sockios.h 0x89 0B-DF linux/sockios.h -0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range -0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range +0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range +0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range 0x8B all linux/wireless.h -0x8C 00-3F WiNRADiO driver - <http://www.winradio.com.au/> +0x8C 00-3F WiNRADiO driver + <http://www.winradio.com.au/> 0x90 00 drivers/cdrom/sbpcd.h 0x92 00-0F drivers/usb/mon/mon_bin.c 0x93 60-7F linux/auto_fs.h -0x94 all fs/btrfs/ioctl.h Btrfs filesystem - and linux/fs.h some lifted to vfs/generic -0x97 00-7F fs/ceph/ioctl.h Ceph file system -0x99 00-0F 537-Addinboard driver - <mailto:[email protected]> -0xA0 all linux/sdp/sdp.h Industrial Device Project - <mailto:[email protected]> -0xA1 0 linux/vtpm_proxy.h TPM Emulator Proxy Driver -0xA2 all uapi/linux/acrn.h ACRN hypervisor -0xA3 80-8F Port ACL in development: - <mailto:[email protected]> +0x94 all fs/btrfs/ioctl.h Btrfs filesystem + and linux/fs.h some lifted to vfs/generic +0x97 00-7F fs/ceph/ioctl.h Ceph file system +0x99 00-0F 537-Addinboard driver + <mailto:[email protected]> +0xA0 all linux/sdp/sdp.h Industrial Device Project + <mailto:[email protected]> +0xA1 0 linux/vtpm_proxy.h TPM Emulator Proxy Driver +0xA2 all uapi/linux/acrn.h ACRN hypervisor +0xA3 80-8F Port ACL in development: + <mailto:[email protected]> 0xA3 90-9F linux/dtlk.h -0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem -0xA4 00-1F uapi/asm/sgx.h <mailto:[email protected]> -0xA5 01-05 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator - <mailto:[email protected]> -0xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver - <mailto:[email protected]> +0xA4 00-1F uapi/linux/tee.h Generic TEE subsystem +0xA4 00-1F uapi/asm/sgx.h <mailto:[email protected]> +0xA5 01-05 linux/surface_aggregator/cdev.h Microsoft Surface Platform System Aggregator + <mailto:[email protected]> +0xA5 20-2F linux/surface_aggregator/dtx.h Microsoft Surface DTX driver + <mailto:[email protected]> 0xAA 00-3F linux/uapi/linux/userfaultfd.h 0xAB 00-1F linux/nbd.h 0xAC 00-1F linux/raw.h -0xAD 00 Netfilter device in development: - <mailto:[email protected]> -0xAE 00-1F linux/kvm.h Kernel-based Virtual Machine - <mailto:[email protected]> -0xAE 40-FF linux/kvm.h Kernel-based Virtual Machine - <mailto:[email protected]> -0xAE 20-3F linux/nitro_enclaves.h Nitro Enclaves -0xAF 00-1F linux/fsl_hypervisor.h Freescale hypervisor -0xB0 all RATIO devices in development: - <mailto:[email protected]> -0xB1 00-1F PPPoX - <mailto:[email protected]> +0xAD 00 Netfilter device in development: + <mailto:[email protected]> +0xAE 00-1F linux/kvm.h Kernel-based Virtual Machine + <mailto:[email protected]> +0xAE 40-FF linux/kvm.h Kernel-based Virtual Machine + <mailto:[email protected]> +0xAE 20-3F linux/nitro_enclaves.h Nitro Enclaves +0xAF 00-1F linux/fsl_hypervisor.h Freescale hypervisor +0xB0 all RATIO devices in development: + <mailto:[email protected]> +0xB1 00-1F PPPoX + <mailto:[email protected]> 0xB3 00 linux/mmc/ioctl.h -0xB4 00-0F linux/gpio.h <mailto:[email protected]> -0xB5 00-0F uapi/linux/rpmsg.h <mailto:[email protected]> +0xB4 00-0F linux/gpio.h <mailto:[email protected]> +0xB5 00-0F uapi/linux/rpmsg.h <mailto:[email protected]> 0xB6 all linux/fpga-dfl.h -0xB7 all uapi/linux/remoteproc_cdev.h <mailto:[email protected]> -0xB7 all uapi/linux/nsfs.h <mailto:Andrei Vagin <[email protected]>> +0xB7 all uapi/linux/remoteproc_cdev.h <mailto:[email protected]> +0xB7 all uapi/linux/nsfs.h <mailto:Andrei Vagin <[email protected]>> 0xC0 00-0F linux/usb/iowarrior.h 0xCA 00-0F uapi/misc/cxl.h 0xCA 10-2F uapi/misc/ocxl.h 0xCA 80-BF uapi/scsi/cxlflash_ioctl.h -0xCB 00-1F CBM serial IEC bus in development: - <mailto:[email protected]> -0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver +0xCB 00-1F CBM serial IEC bus in development: + <mailto:[email protected]> +0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver 0xCD 01 linux/reiserfs_fs.h -0xCE 01-02 uapi/linux/cxl_mem.h Compute Express Link Memory Devices +0xCE 01-02 uapi/linux/cxl_mem.h Compute Express Link Memory Devices 0xCF 02 fs/cifs/ioctl.c 0xDB 00-0F drivers/char/mwave/mwavepub.h -0xDD 00-3F ZFCP device driver see drivers/s390/scsi/ - <mailto:[email protected]> +0xDD 00-3F ZFCP device driver see drivers/s390/scsi/ + <mailto:[email protected]> 0xE5 00-3F linux/fuse.h -0xEC 00-01 drivers/platform/chrome/cros_ec_dev.h ChromeOS EC driver -0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development) - <mailto:[email protected]> -0xF6 all LTTng Linux Trace Toolkit Next Generation - <mailto:[email protected]> +0xEC 00-01 drivers/platform/chrome/cros_ec_dev.h ChromeOS EC driver +0xF3 00-3F drivers/usb/misc/sisusbvga/sisusb.h sisfb (in development) + <mailto:[email protected]> +0xF6 all LTTng Linux Trace Toolkit Next Generation + <mailto:[email protected]> 0xFD all linux/dm-ioctl.h 0xFE all linux/isst_if.h -==== ===== ======================================================= ================================================================ +==== ===== ========================================================= ================================================================
Greg Kroah-Hartman
maintainerPATCH 92/95 crypto: qat - Replace kzalloc() + copy_from_user() with memdup_user()
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
[ Upstream commit 1e26339703e2afd397037defa798682b2b93dcc0 ]
Replace kzalloc() followed by copy_from_user() with memdup_user() to improve and simplify adf_ctl_alloc_resources(). memdup_user() returns either -ENOMEM or -EFAULT (instead of -EIO) if an error occurs.
Remove the unnecessary device id initialization, since memdup_user() (like copy_from_user()) immediately overwrites it.
No functional changes intended other than returning the more idiomatic error code -EFAULT.
Stable-dep-of: d237230728c5 ("crypto: qat - remove unused character device and IOCTLs")
--- drivers/crypto/qat/qat_common/adf_ctl_drv.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/crypto/qat/qat_common/adf_ctl_drv.c +3 -10
@@ -87,17 +87,10 @@ static int adf_ctl_alloc_resources(struc {struct adf_user_cfg_ctl_data *cfg_data; - cfg_data =kzalloc (sizeof (*cfg_data),GFP_KERNEL ); -if (!cfg_data) -return -ENOMEM ; - -/* Initialize device id to NO DEVICE as 0 is a valid device id */ - cfg_data->device_id =ADF_CFG_NO_DEVICE ; - -if (copy_from_user (cfg_data, (void __user *)arg,sizeof (*cfg_data))) { + cfg_data =memdup_user ((void __user *)arg,sizeof (*cfg_data)); +if (IS_ERR (cfg_data)) {pr_err ("QAT: failed to copy from user cfg_data.\n" ); -kfree (cfg_data); -return -EIO ; +return PTR_ERR (cfg_data); } *ctl_data = cfg_data;
Greg Kroah-Hartman
maintainerPATCH 93/95 crypto: qat - Return pointer directly in adf_ctl_alloc_resources
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 5ce9891ea928208a915411ce8227f8c3e37e5ad9 ]
Returning values through arguments is confusing and that has upset the compiler with the recent change to memdup_user:
../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c: In function ‘adf_ctl_ioctl’:../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:308:26: warning: ‘ctl_data’ may be used uninitialized [-Wmaybe-uninitialized]
308 | ctl_data->device_id);
| ^~../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:294:39: note: ‘ctl_data’ was declared here
294 | struct adf_user_cfg_ctl_data *ctl_data;
| ^~~~~~~~
In function ‘adf_ctl_ioctl_dev_stop’,
inlined from ‘adf_ctl_ioctl’ at ../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:386:9:../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:273:48: warning: ‘ctl_data’ may be used uninitialized [-Wmaybe-uninitialized]
273 | ret = adf_ctl_is_device_in_use(ctl_data->device_id);
| ~~~~~~~~^~~~~~~~~~~../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c: In function ‘adf_ctl_ioctl’:../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:261:39: note: ‘ctl_data’ was declared here
261 | struct adf_user_cfg_ctl_data *ctl_data;
| ^~~~~~~~
In function ‘adf_ctl_ioctl_dev_config’,
inlined from ‘adf_ctl_ioctl’ at ../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:382:9:../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:192:54: warning: ‘ctl_data’ may be used uninitialized [-Wmaybe-uninitialized]
192 | accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
| ~~~~~~~~^~~~~~~~~~~../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c: In function ‘adf_ctl_ioctl’:../drivers/crypto/intel/qat/qat_common/adf_ctl_drv.c:185:39: note: ‘ctl_data’ was declared here
185 | struct adf_user_cfg_ctl_data *ctl_data;
| ^~~~~~~~
Fix this by returning the pointer directly.
Stable-dep-of: d237230728c5 ("crypto: qat - remove unused character device and IOCTLs")
--- drivers/crypto/qat/qat_common/adf_ctl_drv.c | 31 +++++++++++----------------- 1 file changed, 13 insertions(+), 18 deletions(-)
drivers/crypto/qat/qat_common/adf_ctl_drv.c +13 -18
@@ -82,19 +82,14 @@ err_chrdev_unreg:return -EFAULT ; } -static int adf_ctl_alloc_resources (struct adf_user_cfg_ctl_data **ctl_data, -unsigned long arg) +static struct adf_user_cfg_ctl_data *adf_ctl_alloc_resources (unsigned long arg) {struct adf_user_cfg_ctl_data *cfg_data; cfg_data =memdup_user ((void __user *)arg,sizeof (*cfg_data)); -if (IS_ERR (cfg_data)) { +if (IS_ERR (cfg_data))pr_err ("QAT: failed to copy from user cfg_data.\n" ); -return PTR_ERR (cfg_data); - } - - *ctl_data = cfg_data; -return 0 ; +return cfg_data; } static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
@@ -173,13 +168,13 @@ out_err:static int adf_ctl_ioctl_dev_config (struct file *fp,unsigned int cmd,unsigned long arg) { -int ret;struct adf_user_cfg_ctl_data *ctl_data;struct adf_accel_dev *accel_dev; +int ret =0 ; - ret =adf_ctl_alloc_resources (&ctl_data, arg); -if (ret) -return ret; + ctl_data =adf_ctl_alloc_resources (arg); +if (IS_ERR (ctl_data)) +return PTR_ERR (ctl_data); accel_dev =adf_devmgr_get_dev_by_id (ctl_data->device_id);if (!accel_dev) {
@@ -254,9 +249,9 @@ static int adf_ctl_ioctl_dev_stop(structint ret;struct adf_user_cfg_ctl_data *ctl_data; - ret =adf_ctl_alloc_resources (&ctl_data, arg); -if (ret) -return ret; + ctl_data =adf_ctl_alloc_resources (arg); +if (IS_ERR (ctl_data)) +return PTR_ERR (ctl_data);if (adf_devmgr_verify_id (ctl_data->device_id)) {pr_err ("QAT: Device %d not found\n" , ctl_data->device_id);
@@ -288,9 +283,9 @@ static int adf_ctl_ioctl_dev_start(strucstruct adf_user_cfg_ctl_data *ctl_data;struct adf_accel_dev *accel_dev; - ret =adf_ctl_alloc_resources (&ctl_data, arg); -if (ret) -return ret; + ctl_data =adf_ctl_alloc_resources (arg); +if (IS_ERR (ctl_data)) +return PTR_ERR (ctl_data); ret = -ENODEV ; accel_dev =adf_devmgr_get_dev_by_id (ctl_data->device_id);
Greg Kroah-Hartman
maintainerPATCH 94/95 crypto: qat - remove unused character device and IOCTLs
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giovanni Cabiddu <[email protected]>
[ Upstream commit d237230728c567297f2f98b425d63156ab2ed17f ]
The QAT driver exposes a character device (qat_adf_ctl) with IOCTLs for device configuration, start, stop, status query and enumeration. These IOCTLs are not part of any public uAPI header and have no known in-tree or out-of-tree users. Device lifecycle is already managed via sysfs.
The ioctl interface also increases the attack surface and is the subject of a number of bug reports.
Remove the character device, the IOCTL definitions, and the related data structures (adf_dev_status_info, adf_user_cfg_key_val, adf_user_cfg_section, adf_user_cfg_ctl_data). Drop the now-unused adf_cfg_user.h header and strip adf_ctl_drv.c down to the minimal module_init/module_exit hooks for workqueue, AER, and crypto/compression algorithm registration.
Clean up leftover dead code that was only reachable from the removed IOCTL paths: adf_cfg_del_all(), adf_devmgr_verify_id(), adf_devmgr_get_num_dev(), adf_devmgr_get_dev_by_id(), adf_get_vf_real_id() and the unused ADF_CFG macros.
Additionally, drop the entry associated to QAT IOCTLs in ioctl-number.rst.
--- Documentation/userspace-api/ioctl/ioctl-number.rst | 1 drivers/crypto/qat/qat_common/adf_cfg_common.h | 32 - drivers/crypto/qat/qat_common/adf_cfg_user.h | 38 - drivers/crypto/qat/qat_common/adf_common_drv.h | 3 drivers/crypto/qat/qat_common/adf_ctl_drv.c | 409 --------------------- drivers/crypto/qat/qat_common/adf_dev_mgr.c | 70 --- 6 files changed, 3 insertions(+), 550 deletions(-) delete mode 100644 drivers/crypto/qat/qat_common/adf_cfg_user.h
Documentation/userspace-api/ioctl/ioctl-number.rst +0 -1
@@ -214,7 +214,6 @@ Code Seq# Include File <mailto:[email protected]> 'a' all linux/atm*.h, linux/sonet.h ATM on linux <http://lrcwww.epfl.ch/> -'a' 00-0F drivers/crypto/qat/qat_common/adf_cfg_common.h conflict! qat driver 'b' 00-FF conflict! bit3 vme host bridge <mailto:[email protected]> 'c' all linux/cm4000_cs.h conflict!
drivers/crypto/qat/qat_common/adf_cfg_common.h +0 -32
@@ -4,18 +4,11 @@#define ADF_CFG_COMMON_H_ #include <linux/types.h> -#include <linux/ioctl.h> #define ADF_CFG_MAX_STR_LEN 64#define ADF_CFG_MAX_KEY_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN#define ADF_CFG_MAX_VAL_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN#define ADF_CFG_MAX_SECTION_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN -#define ADF_CFG_BASE_DEC 10 -#define ADF_CFG_BASE_HEX 16 -#define ADF_CFG_ALL_DEVICES 0xFE -#define ADF_CFG_NO_DEVICE 0xFF -#define ADF_CFG_AFFINITY_WHATEVER 0xFF -#define MAX_DEVICE_NAME_SIZE 32#define ADF_MAX_DEVICES (32 * 32)#define ADF_DEVS_ARRAY_SIZE BITS_TO_LONGS(ADF_MAX_DEVICES)
@@ -35,29 +28,4 @@ enum adf_device_type {DEV_C3XXXVF , DEV_4XXX, }; - -struct adf_dev_status_info { -enum adf_device_type type; -__u32 accel_id; -__u32 instance_id; -__u8 num_ae; -__u8 num_accel; -__u8 num_logical_accel; -__u8 banks_per_accel; -__u8 state; -__u8 bus; -__u8 dev; -__u8 fun; -char name[MAX_DEVICE_NAME_SIZE ]; -}; - -#define ADF_CTL_IOC_MAGIC 'a' -#define IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS _IOW(ADF_CTL_IOC_MAGIC, 0, \ - struct adf_user_cfg_ctl_data) -#define IOCTL_STOP_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 1, \ - struct adf_user_cfg_ctl_data) -#define IOCTL_START_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 2, \ - struct adf_user_cfg_ctl_data) -#define IOCTL_STATUS_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 3, __u32) -#define IOCTL_GET_NUM_DEVICES _IOW(ADF_CTL_IOC_MAGIC, 4, __s32)#endif
drivers/crypto/qat/qat_common/adf_cfg_user.h deleted +0 -38
@@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */ -/* Copyright(c) 2014 - 2020 Intel Corporation */ -#ifndef ADF_CFG_USER_H_ -#define ADF_CFG_USER_H_ - -#include "adf_cfg_common.h" -#include "adf_cfg_strings.h" - -struct adf_user_cfg_key_val { -char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES ]; -char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES ]; -union { -struct adf_user_cfg_key_val *next; -__u64 padding3; - }; -enum adf_cfg_val_type type; -} __packed; - -struct adf_user_cfg_section { -char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES ]; -union { -struct adf_user_cfg_key_val *params; -__u64 padding1; - }; -union { -struct adf_user_cfg_section *next; -__u64 padding3; - }; -} __packed; - -struct adf_user_cfg_ctl_data { -union { -struct adf_user_cfg_section *config_section; -__u64 padding; - }; -__u8 device_id; -} __packed; -#endif
drivers/crypto/qat/qat_common/adf_common_drv.h +0 -3
@@ -74,11 +74,8 @@ int adf_devmgr_add_dev(struct adf_accel_void adf_devmgr_rm_dev (struct adf_accel_dev *accel_dev,struct adf_accel_dev *pf);struct list_head *adf_devmgr_get_head (void ); -struct adf_accel_dev *adf_devmgr_get_dev_by_id (u32 id);struct adf_accel_dev *adf_devmgr_get_first (void );struct adf_accel_dev *adf_devmgr_pci_to_accel_dev (struct pci_dev *pci_dev); -int adf_devmgr_verify_id (u32 id); -void adf_devmgr_get_num_dev (u32 *num);int adf_devmgr_in_reset (struct adf_accel_dev *accel_dev);int adf_dev_started (struct adf_accel_dev *accel_dev);int adf_dev_restarting_notify (struct adf_accel_dev *accel_dev);
drivers/crypto/qat/qat_common/adf_ctl_drv.c +3 -406
436 lines not on this page · raw message
drivers/crypto/qat/qat_common/adf_dev_mgr.c +0 -70
82 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 95/95 dlm: prevent NPD when writing a positive value to event_done
In reply to Greg Kroah-Hartman5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo <[email protected]>
commit 8e2bad543eca5c25cd02cbc63d72557934d45f13 upstream.
do_uevent returns the value written to event_done. In case it is a positive value, new_lockspace would undo all the work, and lockspace would not be set. __dlm_new_lockspace, however, would treat that positive value as a success due to commit 8511a2728ab8 ("dlm: fix use count with multiple joins").
Down the line, device_create_lockspace would pass that NULL lockspace to dlm_find_lockspace_local, leading to a NULL pointer dereference.
Treating such positive values as successes prevents the problem. Given this has been broken for so long, this is unlikely to break userspace expectations.
--- fs/dlm/lockspace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/dlm/lockspace.c +1 -1
@@ -638,7 +638,7 @@ static int new_lockspace(const char *namlockspace to start running (via sysfs) in dlm_ls_start(). */ error =do_uevent (ls,1 ); -if (error) +if (error <0 ) goto out_recoverd;wait_for_completion (&ls->ls_members_done);
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 5.15.211-rc1-00096-g75990a9e5252 #1 SMP Thu Jul 2 19:22:26 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.211 release. There are 95 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 Sat, 04 Jul 2026 15:50:58 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.211-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Hi!
Quoted 4 lines
This is the start of the stable review cycle for the 5.15.211 release. There are 95 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.
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.15.y
Best regards,
Pavel
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.211 release. There are 95 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.15.211 release. There are 95 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 Sat, 04 Jul 2026 15:50:58 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.15.211-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.15.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian