Linux 6.12.84
Greg Kroah-Hartman
maintainerI'm announcing the release of the 6.12.84 kernel.
All users of the 6.12 kernel series must upgrade.
The updated 6.12.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-6.12.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks,
greg k-h
------------
Makefile | 2 drivers/crypto/ccp/sev-dev.c | 19 +++++- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 39 ++++++------ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 22 ++++++- drivers/net/ethernet/mediatek/mtk_ppe.c | 30 +++++++++ drivers/net/ethernet/mediatek/mtk_ppe.h | 1 drivers/net/wireless/ath/ath9k/channel.c | 6 - drivers/net/wireless/virtual/mac80211_hwsim.c | 1 drivers/pci/endpoint/functions/pci-epf-vntb.c | 18 ----- fs/f2fs/compress.c | 14 +++- fs/f2fs/namei.c | 1 fs/fuse/control.c | 4 - fs/fuse/dev.c | 3 fs/fuse/readdir.c | 4 + fs/ntfs3/fslog.c | 12 +++ fs/smb/client/cifsacl.c | 1 fs/smb/client/smb2ops.c | 6 + fs/smb/server/mgmt/user_config.c | 6 - fs/smb/server/smb2pdu.c | 2 fs/smb/server/smbacl.c | 61 +++++++++++++++----- fs/smb/server/transport_ipc.c | 16 ++++- fs/smb/server/transport_tcp.c | 4 - fs/smb/server/vfs_cache.c | 41 +++++++++---- include/linux/hugetlb.h | 17 +++++ include/net/mac80211.h | 4 - mm/pagewalk.c | 24 +++++++ mm/userfaultfd.c | 2 net/mac80211/tx.c | 4 - net/packet/af_packet.c | 21 ++++-- net/rxrpc/conn_event.c | 14 +++- net/rxrpc/key.c | 4 + scripts/dtc/dtc-lexer.l | 3 scripts/generate_rust_analyzer.py | 14 ++++ scripts/rust_is_available.sh | 15 ++++ scripts/rust_is_available_bindgen_libclang_concat.h | 3 scripts/rust_is_available_test.py | 34 ++++++++++- security/integrity/ima/ima_kexec.c | 13 ++++ sound/usb/caiaq/device.c | 4 - sound/usb/mixer.c | 7 ++ 39 files changed, 388 insertions(+), 108 deletions(-)
Anderson Nascimento (1):
rxrpc: Fix missing validation of ticket length in non-XDR key preparsing
Berk Cem Goksel (1):
ALSA: caiaq: take a reference on the USB device in create_card()
Bernd Schubert (1):
fuse: Check for large folio with SPLICE_F_MOVE
Bingquan Chen (1):
net/packet: fix TOCTOU race on mmap'd vnet_hdr in tpacket_snd()
Chao Yu (1):
f2fs: fix to avoid memory leak in f2fs_rename()
Cryolitia PukNgae (1):
ALSA: usb-audio: apply quirk for MOONDROP JU Jiu
DaeMyung Kang (1):
smb: server: fix max_connections off-by-one in tcp accept path
Daniel Golle (1):
net: ethernet: mtk_eth_soc: initialize PPE per-tag-layer MTU registers
Darrick J. Wong (1):
fuse: quiet down complaints in fuse_conn_limit_write
Felix Fietkau (1):
wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
George Saad (1):
f2fs: fix use-after-free of sbi in f2fs_compress_write_end_io()
Greg Kroah-Hartman (2):
fs/ntfs3: validate rec->used in journal-replay file record check
Linux 6.12.84Jianhui Zhou (1):
mm/userfaultfd: fix hugetlb fault mutex hash calculation
Koichiro Den (1):
PCI: endpoint: pci-epf-vntb: Remove duplicate resource teardown
Max Boone (1):
mm/pagewalk: fix race between concurrent split and refault
Michael Bommarito (6):
ksmbd: require minimum ACE size in smb_check_perm_dacl()
smb: server: fix active_num_conn leak on transport allocation failure
smb: client: require a full NFS mode SID before reading mode bits
smb: client: fix OOB read in smb2_ioctl_query_info QUERY_INFO path
ksmbd: validate response sizes in ipc_validate_msg()
ksmbd: validate num_aces and harden ACE walk in smb_inherit_dacl()
Miguel Ojeda (1):
rust: warn on bindgen < 0.69.5 and libclang >= 19.1
Mikhail Gavrilov (1):
drm/amdgpu: replace PASID IDR with XArray
Namjae Jeon (1):
ksmbd: fix use-after-free in __ksmbd_close_fd() via durable scavenger
Nathan Chancellor (1):
scripts/dtc: Remove unused dts_version in dtc-lexer.l
Samuel Page (1):
fuse: reject oversized dirents in page cache
Sean Christopherson (3):
crypto: ccp: Don't attempt to copy CSR to userspace if PSP command failed
crypto: ccp: Don't attempt to copy PDH cert to userspace if PSP command failed
crypto: ccp: Don't attempt to copy ID to userspace if PSP command failed
Steven Chen (2):
ima: verify if the segment size has changed
ima: do not copy measurement list to kdump kernel
Tamir Duberstein (1):
scripts: generate_rust_analyzer.py: define scripts
Tristan Madani (2):
ksmbd: fix out-of-bounds write in smb2_get_ea() EA alignment
ksmbd: use check_add_overflow() to prevent u16 DACL size overflow
Wang Jie (1):
rxrpc: only handle RESPONSE during service challenge
Greg Kroah-Hartman
maintainerMakefile +1 -1
@@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 PATCHLEVEL = 12 -SUBLEVEL = 83 +SUBLEVEL = 84 EXTRAVERSION = NAME = Baby Opossum Posse
drivers/crypto/ccp/sev-dev.c +17 -2
@@ -1541,7 +1541,10 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) ret =__sev_do_cmd_locked (SEV_CMD_PEK_CSR , &data, &argp->error); -/* If we query the CSR length, FW responded with expected data. */ +/* +* Firmware will returns the length of the CSR blob (either the minimum +* required length or the actual length written), return it to the user. +*/ input.length = data.len;if (copy_to_user ((void __user *)argp->data, &input,sizeof (input))) {
@@ -1549,6 +1552,9 @@ static int sev_ioctl_do_pek_csr(struct sev_issue_cmd *argp, bool writable) goto e_free_blob; } +if (ret ||WARN_ON_ONCE (argp->error)) + goto e_free_blob; +if (blob) {if (copy_to_user (input_address, blob, input.length)) ret = -EFAULT ;
@@ -1870,6 +1876,9 @@ static int sev_ioctl_do_get_id2(struct sev_issue_cmd *argp) goto e_free; } +if (ret ||WARN_ON_ONCE (argp->error)) + goto e_free; +if (id_blob) {if (copy_to_user (input_address, id_blob, data.len)) { ret = -EFAULT ;
@@ -1986,7 +1995,10 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) ret =__sev_do_cmd_locked (SEV_CMD_PDH_CERT_EXPORT , &data, &argp->error); -/* If we query the length, FW responded with expected data. */ +/* +* Firmware will return the length of the blobs (either the minimum +* required length or the actual length written), return 'em to the user. +*/ input.cert_chain_len = data.cert_chain_len; input.pdh_cert_len = data.pdh_cert_len;
@@ -1995,6 +2007,9 @@ static int sev_ioctl_do_pdh_export(struct sev_issue_cmd *argp, bool writable) goto e_free_cert; } +if (ret ||WARN_ON_ONCE (argp->error)) + goto e_free_cert; +if (pdh_blob) {if (copy_to_user (input_pdh_cert_address, pdh_blob, input.pdh_cert_len)) {
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +19 -20
@@ -22,7 +22,7 @@*/ #include "amdgpu_ids.h" -#include <linux/idr.h> +#include <linux/xarray.h> #include <linux/dma-fence-array.h>
@@ -40,8 +40,8 @@* VMs are looked up from the PASID per amdgpu_device. */ -static DEFINE_IDR (amdgpu_pasid_idr); -static DEFINE_SPINLOCK (amdgpu_pasid_idr_lock); +static DEFINE_XARRAY_FLAGS(amdgpu_pasid_xa, XA_FLAGS_LOCK_IRQ | XA_FLAGS_ALLOC1); +static u32 amdgpu_pasid_xa_next;/* Helper to free pasid from a fence callback */ struct amdgpu_pasid_cb {
@@ -62,36 +62,37 @@ struct amdgpu_pasid_cb {*/ int amdgpu_pasid_alloc (unsigned int bits) { -int pasid; +u32 pasid; +int r;if (bits ==0 )return -EINVAL ; -spin_lock (&amdgpu_pasid_idr_lock); -/* TODO: Need to replace the idr with an xarry, and then -* handle the internal locking with ATOMIC safe paths. -*/ - pasid =idr_alloc_cyclic (&amdgpu_pasid_idr,NULL ,1 , -1U << bits,GFP_ATOMIC ); -spin_unlock (&amdgpu_pasid_idr_lock); - -if (pasid >=0 ) -trace_amdgpu_pasid_allocated (pasid); + r =xa_alloc_cyclic_irq (&amdgpu_pasid_xa, &pasid,xa_mk_value (0 ), +XA_LIMIT (1 , (1U << bits) -1 ), + &amdgpu_pasid_xa_next,GFP_KERNEL ); +if (r <0 ) +return r; +trace_amdgpu_pasid_allocated (pasid);return pasid; }/** * amdgpu_pasid_free - Free a PASID * @pasid: PASID to free +* +* Called in IRQ context. */ void amdgpu_pasid_free (u32 pasid) { +unsigned long flags; +trace_amdgpu_pasid_freed (pasid); -spin_lock (&amdgpu_pasid_idr_lock); -idr_remove (&amdgpu_pasid_idr, pasid); -spin_unlock (&amdgpu_pasid_idr_lock); +xa_lock_irqsave (&amdgpu_pasid_xa, flags); +__xa_erase (&amdgpu_pasid_xa, pasid); +xa_unlock_irqrestore (&amdgpu_pasid_xa, flags); } static void amdgpu_pasid_free_cb(struct dma_fence *fence,
@@ -653,7 +654,5 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)*/ void amdgpu_pasid_mgr_cleanup (void ) { -spin_lock (&amdgpu_pasid_idr_lock); -idr_destroy (&amdgpu_pasid_idr); -spin_unlock (&amdgpu_pasid_idr_lock); +xa_destroy (&amdgpu_pasid_xa); }
drivers/net/ethernet/mediatek/mtk_eth_soc.c +21 -1
@@ -3384,12 +3384,23 @@ static int mtk_device_event(struct notifier_block *n, unsigned long event, voidreturn NOTIFY_DONE ; } +static int mtk_max_gmac_mtu (struct mtk_eth *eth) +{ +int i, max_mtu =ETH_DATA_LEN ; + +for (i =0 ; i <ARRAY_SIZE (eth->netdev); i++) +if (eth->netdev[i] && eth->netdev[i]->mtu > max_mtu) + max_mtu = eth->netdev[i]->mtu; + +return max_mtu; +} +static int mtk_open (struct net_device *dev) {struct mtk_mac *mac =netdev_priv (dev);struct mtk_eth *eth = mac->hw;struct mtk_mac *target_mac; -int i, err, ppe_num; +int i, err, ppe_num, mtu; ppe_num = eth->soc->ppe_num;
@@ -3436,6 +3447,10 @@ static int mtk_open(struct net_device *dev)mtk_gdm_config (eth, target_mac->id, gdm_config); } + mtu =mtk_max_gmac_mtu (eth); +for (i =0 ; i <ARRAY_SIZE (eth->ppe); i++) +mtk_ppe_update_mtu (eth->ppe[i], mtu); +napi_enable (ð->tx_napi);napi_enable (ð->rx_napi);mtk_tx_irq_enable (eth,MTK_TX_DONE_INT );
@@ -4129,6 +4144,7 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)int length = new_mtu +MTK_RX_ETH_HLEN ;struct mtk_mac *mac =netdev_priv (dev);struct mtk_eth *eth = mac->hw; +int max_mtu, i;if (rcu_access_pointer (eth->prog) && length >MTK_PP_MAX_BUF_SIZE ) {
@@ -4139,6 +4155,10 @@ static int mtk_change_mtu(struct net_device *dev, int new_mtu)mtk_set_mcr_max_rx (mac, length);WRITE_ONCE (dev->mtu, new_mtu); + max_mtu =mtk_max_gmac_mtu (eth); +for (i =0 ; i <ARRAY_SIZE (eth->ppe); i++) +mtk_ppe_update_mtu (eth->ppe[i], max_mtu); +return 0 ; }
drivers/net/ethernet/mediatek/mtk_ppe.c +30 -0
@@ -973,6 +973,36 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) } } +void mtk_ppe_update_mtu (struct mtk_ppe *ppe,int mtu) +{ +int base; +u32 val; + +if (!ppe) +return ; + +/* The PPE checks output frame size against per-tag-layer MTU limits, +* treating PPPoE and DSA tags just like 802.1Q VLAN tags. The Linux +* device MTU already accounts for PPPoE (PPPOE_SES_HLEN) and DSA tag +* overhead, but 802.1Q VLAN tags are handled transparently without +* being reflected by the lower device MTU being increased by 4. +* Use the maximum MTU across all GMAC interfaces so that PPE output +* frame limits are sufficiently high regardless of which port a flow +* egresses through. +*/ + base =ETH_HLEN + mtu; + + val =FIELD_PREP (MTK_PPE_VLAN_MTU0_NONE , base) | +FIELD_PREP (MTK_PPE_VLAN_MTU0_1TAG , base +VLAN_HLEN ); +ppe_w32 (ppe,MTK_PPE_VLAN_MTU0 , val); + + val =FIELD_PREP (MTK_PPE_VLAN_MTU1_2TAG , + base +2 *VLAN_HLEN ) | +FIELD_PREP (MTK_PPE_VLAN_MTU1_3TAG , + base +3 *VLAN_HLEN ); +ppe_w32 (ppe,MTK_PPE_VLAN_MTU1 , val); +} +void mtk_ppe_start (struct mtk_ppe *ppe) {u32 val;
drivers/net/ethernet/mediatek/mtk_ppe.h +1 -0
@@ -346,6 +346,7 @@ struct mtk_ppe {struct mtk_ppe *mtk_ppe_init (struct mtk_eth *eth,void __iomem *base,int index);void mtk_ppe_deinit (struct mtk_eth *eth); +void mtk_ppe_update_mtu (struct mtk_ppe *ppe,int mtu);void mtk_ppe_start (struct mtk_ppe *ppe);int mtk_ppe_stop (struct mtk_ppe *ppe);int mtk_ppe_prepare_reset (struct mtk_ppe *ppe);
drivers/net/wireless/ath/ath9k/channel.c +2 -4
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,skb_set_queue_mapping (skb,IEEE80211_AC_VO );if (!ieee80211_tx_prepare_skb (sc->hw, vif, skb, band,NULL )) - goto error; +return ; txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO ];if (ath_tx_start (sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp, skb->priority =7 ;skb_set_queue_mapping (skb,IEEE80211_AC_VO ); -if (!ieee80211_tx_prepare_skb (sc->hw, vif, skb, band, &sta)) { -dev_kfree_skb_any (skb); +if (!ieee80211_tx_prepare_skb (sc->hw, vif, skb, band, &sta))return false; - }break ;default :return false;
drivers/net/wireless/virtual/mac80211_hwsim.c +0 -1
@@ -2977,7 +2977,6 @@ static void hw_scan_work(struct work_struct *work) hwsim->tmp_chan->band, NULL)) {rcu_read_unlock (); -kfree_skb (probe);continue ; }
drivers/pci/endpoint/functions/pci-epf-vntb.c +1 -17
@@ -662,18 +662,6 @@ static void epf_ntb_mw_bar_clear(struct epf_ntb *ntb, int num_mws) } } -/** -* epf_ntb_epc_destroy() - Cleanup NTB EPC interface -* @ntb: NTB device that facilitates communication between HOST and VHOST -* -* Wrapper for epf_ntb_epc_destroy_interface() to cleanup all the NTB interfaces -*/ -static void epf_ntb_epc_destroy (struct epf_ntb *ntb) -{ -pci_epc_remove_epf (ntb->epf->epc, ntb->epf,0 ); -pci_epc_put (ntb->epf->epc); -} -/** * epf_ntb_init_epc_bar() - Identify BARs to be used for each of the NTB * constructs (scratchpad region, doorbell, memorywindow)
@@ -1315,7 +1303,7 @@ static int epf_ntb_bind(struct pci_epf *epf) ret =epf_ntb_init_epc_bar (ntb);if (ret) {dev_err (dev,"Failed to create NTB EPC\n" ); - goto err_bar_init; +return ret; } ret =epf_ntb_config_spad_bar_alloc (ntb);
@@ -1355,9 +1343,6 @@ static int epf_ntb_bind(struct pci_epf *epf) err_bar_alloc:epf_ntb_config_spad_bar_free (ntb); -err_bar_init: -epf_ntb_epc_destroy (ntb); -return ret; }
@@ -1373,7 +1358,6 @@ static void epf_ntb_unbind(struct pci_epf *epf)epf_ntb_epc_cleanup (ntb);epf_ntb_config_spad_bar_free (ntb); -epf_ntb_epc_destroy (ntb);pci_unregister_driver (&vntb_pci_driver); }
fs/f2fs/compress.c +11 -3
@@ -1472,10 +1472,10 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)f2fs_compress_free_page (page); -dec_page_count (sbi, type); - -if (atomic_dec_return (&cic->pending_pages)) +if (atomic_dec_return (&cic->pending_pages)) { +dec_page_count (sbi, type);return ; + }for (i =0 ; i < cic->nr_rpages; i++) {WARN_ON (!cic->rpages[i]);
@@ -1485,6 +1485,14 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page)page_array_free (sbi, cic->rpages, cic->nr_rpages);kmem_cache_free (cic_entry_slab, cic); + +/* +* Make sure dec_page_count() is the last access to sbi. +* Once it drops the F2FS_WB_CP_DATA counter to zero, the +* unmount thread can proceed to destroy sbi and +* sbi->page_array_slab. +*/ +dec_page_count (sbi, type); } static int f2fs_write_raw_pages(struct compress_ctx *cc,
fs/f2fs/namei.c +1 -0
@@ -940,6 +940,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir,return err; err =f2fs_create_whiteout (idmap, old_dir, &whiteout, &fname); +f2fs_free_filename (&fname);if (err)return err; }
fs/fuse/control.c +2 -2
@@ -120,7 +120,7 @@ static ssize_t fuse_conn_max_background_write(struct file *file,const char __user *buf, size_t count, loff_t *ppos) { - unsigned val; + unsigned int val = 0;ssize_t ret; ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
@@ -162,7 +162,7 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file,const char __user *buf, size_t count, loff_t *ppos) { - unsigned val; + unsigned int val = 0;struct fuse_conn *fc;ssize_t ret;
fs/fuse/dev.c +3 -0
@@ -871,6 +871,9 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)folio_clear_uptodate (newfolio);folio_clear_mappedtodisk (newfolio); +if (folio_test_large (newfolio)) + goto out_fallback_unlock; +if (fuse_check_folio (newfolio) !=0 ) goto out_fallback_unlock;
fs/fuse/readdir.c +4 -0
@@ -41,6 +41,10 @@ static void fuse_add_dirent_to_cache(struct file *file,unsigned int offset;void *addr; +/* Dirent doesn't fit in readdir cache page? Skip caching. */ +if (reclen >PAGE_SIZE ) +return ; +spin_lock (&fi->rdc.lock);/* * Is cache already completed? Or this entry does not go at the end of
fs/ntfs3/fslog.c +11 -1
@@ -2789,13 +2789,14 @@ static inline bool check_file_record(const struct MFT_REC *rec,u16 fn =le16_to_cpu (rec->rhdr.fix_num);u16 ao =le16_to_cpu (rec->attr_off);u32 rs = sbi->record_size; +u32 used =le32_to_cpu (rec->used);/* Check the file record header for consistency. */ if (rec->rhdr.sign !=NTFS_FILE_SIGNATURE || fo > (SECTOR_SIZE - ((rs >>SECTOR_SHIFT ) +1 ) *sizeof (short )) || (fn -1 ) *SECTOR_SIZE != rs || ao <MFTRECORD_FIXUP_OFFSET_1 || ao > sbi->record_size -SIZEOF_RESIDENT || !is_rec_inuse (rec) || -le32_to_cpu (rec->total) != rs) { +le32_to_cpu (rec->total) != rs || used > rs || used < ao) {return false; }
@@ -2807,6 +2808,15 @@ static inline bool check_file_record(const struct MFT_REC *rec,return false; } +/* +* The do_action() handlers compute memmove lengths as +* "rec->used - <offset of validated attr>", which underflows when +* rec->used is smaller than the attribute walk reached. At this +* point attr is the ATTR_END marker; rec->used must cover it. +*/ +if (used <PtrOffset (rec, attr) +sizeof (attr->type)) +return false; +return true; }
fs/smb/client/cifsacl.c +1 -0
@@ -832,6 +832,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,dump_ace (ppace[i], end_of_acl);#endif if (mode_from_special_sid && + ppace[i]->sid.num_subauth >=3 && (compare_sids (&(ppace[i]->sid), &sid_unix_NFS_mode) ==0 )) {/*
fs/smb/client/smb2ops.c +6 -0
@@ -1782,6 +1782,12 @@ smb2_ioctl_query_info(const unsigned int xid, qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1 ].iov_base;if (le32_to_cpu (qi_rsp->OutputBufferLength) < qi.input_buffer_length) qi.input_buffer_length =le32_to_cpu (qi_rsp->OutputBufferLength); +if (qi.input_buffer_length >0 && +struct_size (qi_rsp, Buffer, qi.input_buffer_length) > + rsp_iov[1 ].iov_len) { + rc = -EFAULT ; + goto out; + }if (copy_to_user (&pqi->input_buffer_length, &qi.input_buffer_length,sizeof (qi.input_buffer_length))) {
fs/smb/server/mgmt/user_config.c +0 -6
@@ -56,12 +56,6 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, goto err_free;if (resp_ext) { -if (resp_ext->ngroups >NGROUPS_MAX ) { -pr_err ("ngroups(%u) from login response exceeds max groups(%d)\n" , - resp_ext->ngroups,NGROUPS_MAX ); - goto err_free; - } - user->sgid =kmemdup (resp_ext->____payload, resp_ext->ngroups *sizeof (gid_t),KSMBD_DEFAULT_GFP );
fs/smb/server/smb2pdu.c +2 -0
@@ -4833,6 +4833,8 @@ static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp,/* align next xattr entry at 4 byte bundary */ alignment_bytes = ((next_offset +3 ) & ~3 ) - next_offset;if (alignment_bytes) { +if (buf_free_len < alignment_bytes) +break ;memset (ptr,'\0' , alignment_bytes); ptr += alignment_bytes; next_offset += alignment_bytes;
fs/smb/server/smbacl.c +48 -13
134 lines not on this page · raw message
fs/smb/server/transport_ipc.c +13 -3
@@ -13,6 +13,7 @@#include <net/genetlink.h> #include <linux/socket.h> #include <linux/workqueue.h> +#include <linux/overflow.h> #include "vfs_cache.h" #include "transport_ipc.h"
@@ -497,7 +498,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) {struct ksmbd_rpc_command *resp = entry->response; - msg_sz =sizeof (struct ksmbd_rpc_command ) + resp->payload_sz; +if (check_add_overflow (sizeof (struct ksmbd_rpc_command ), + resp->payload_sz, &msg_sz)) +return -EINVAL ;break ; }case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST :
@@ -516,8 +519,9 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)if (resp->payload_sz < resp->veto_list_sz)return -EINVAL ; - msg_sz =sizeof (struct ksmbd_share_config_response ) + - resp->payload_sz; +if (check_add_overflow (sizeof (struct ksmbd_share_config_response ), + resp->payload_sz, &msg_sz)) +return -EINVAL ; }break ; }
@@ -526,6 +530,12 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)struct ksmbd_login_response_ext *resp = entry->response;if (resp->ngroups) { +if (resp->ngroups <0 || + resp->ngroups >NGROUPS_MAX ) { +pr_err ("ngroups(%d) from login response exceeds max groups(%d)\n" , + resp->ngroups,NGROUPS_MAX ); +return -EINVAL ; + } msg_sz =sizeof (struct ksmbd_login_response_ext ) + resp->ngroups *sizeof (gid_t); }
fs/smb/server/transport_tcp.c +3 -1
@@ -203,6 +203,8 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) t =alloc_transport (client_sk);if (!t) {sock_release (client_sk); +if (server_conf.max_connections) +atomic_dec (&active_num_conn);return -ENOMEM ; }
@@ -295,7 +297,7 @@ static int ksmbd_kthread_fn(void *p) skip_max_ip_conns_limit:if (server_conf.max_connections && -atomic_inc_return (&active_num_conn) >= server_conf.max_connections) { +atomic_inc_return (&active_num_conn) > server_conf.max_connections) {pr_info_ratelimited ("Limit the maximum number of connections(%u)\n" ,atomic_read (&active_num_conn));atomic_dec (&active_num_conn);
fs/smb/server/vfs_cache.c +30 -11
79 lines not on this page · raw message
include/linux/hugetlb.h +17 -0
@@ -783,6 +783,23 @@ static inline unsigned huge_page_shift(struct hstate *h)return h->order +PAGE_SHIFT ; } +/** +* hugetlb_linear_page_index() - linear_page_index() but in hugetlb +* page size granularity. +* @vma: the hugetlb VMA +* @address: the virtual address within the VMA +* +* Return: the page offset within the mapping in huge page units. +*/ +static inline pgoff_t hugetlb_linear_page_index (struct vm_area_struct *vma, +unsigned long address) +{ +struct hstate *h =hstate_vma (vma); + +return ((address - vma->vm_start) >>huge_page_shift (h)) + + (vma->vm_pgoff >>huge_page_order (h)); +} +static inline bool hstate_is_gigantic (struct hstate *h) {return huge_page_order (h) >MAX_PAGE_ORDER ;
include/net/mac80211.h +3 -1
@@ -7208,7 +7208,9 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,* @band: the band to transmit on * @sta: optional pointer to get the station to send the frame to * -* Return: %true if the skb was prepared, %false otherwise +* Return: %true if the skb was prepared, %false otherwise. +* On failure, the skb is freed by this function; callers must not +* free it again. * * Note: must be called under RCU lock */
mm/pagewalk.c +22 -2
@@ -78,12 +78,31 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,static int walk_pmd_range (pud_t *pud,unsigned long addr,unsigned long end,struct mm_walk *walk) { +pud_t pudval =pudp_get (pud);pmd_t *pmd;unsigned long next;const struct mm_walk_ops *ops = walk->ops;int err =0 ;int depth =real_depth (3 ); +/* +* For PTE handling, pte_offset_map_lock() takes care of checking +* whether there actually is a page table. But it also has to be +* very careful about concurrent page table reclaim. +* +* Similarly, we have to be careful here - a PUD entry that points +* to a PMD table cannot go away, so we can just walk it. But if +* it's something else, we need to ensure we didn't race something, +* so need to retry. +* +* A pertinent example of this is a PUD refault after PUD split - +* we will need to split again or risk accessing invalid memory. +*/ +if (!pud_present (pudval) ||pud_leaf (pudval)) { + walk->action =ACTION_AGAIN ; +return 0 ; + } + pmd =pmd_offset (pud, addr); do { again:
@@ -172,12 +191,13 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,if (walk->vma)split_huge_pud (walk->vma, pud, addr); -if (pud_none (*pud)) - goto again; err =walk_pmd_range (pud, addr, next, walk);if (err)break ; + +if (walk->action ==ACTION_AGAIN ) + goto again; }while (pud++, addr = next, addr != end);return err;
mm/userfaultfd.c +1 -1
@@ -573,7 +573,7 @@ static __always_inline ssize_t mfill_atomic_hugetlb(* in the case of shared pmds. fault mutex prevents * races with other faulting threads. */ - idx =linear_page_index (dst_vma, dst_addr); + idx =hugetlb_linear_page_index (dst_vma, dst_addr); mapping = dst_vma->vm_file->f_mapping; hash =hugetlb_fault_mutex_hash (mapping, idx);mutex_lock (&hugetlb_fault_mutex_table[hash]);
net/mac80211/tx.c +3 -1
@@ -1897,8 +1897,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,struct ieee80211_tx_data tx;struct sk_buff *skb2; -if (ieee80211_tx_prepare (sdata, &tx,NULL , skb) ==TX_DROP ) +if (ieee80211_tx_prepare (sdata, &tx,NULL , skb) ==TX_DROP ) { +kfree_skb (skb);return false; + } info->band = band; info->control.vif = vif;
net/packet/af_packet.c +13 -8
@@ -2770,7 +2770,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) {struct sk_buff *skb =NULL ;struct net_device *dev; -struct virtio_net_hdr *vnet_hdr =NULL ; +struct virtio_net_hdr vnet_hdr; +bool has_vnet_hdr = false;struct sockcm_cookie sockc;__be16 proto;int err, reserve =0 ;
@@ -2871,16 +2872,20 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) hlen =LL_RESERVED_SPACE (dev); tlen = dev->needed_tailroom;if (vnet_hdr_sz) { - vnet_hdr = data; data += vnet_hdr_sz; tp_len -= vnet_hdr_sz; -if (tp_len <0 || -__packet_snd_vnet_parse (vnet_hdr, tp_len)) { +if (tp_len <0 ) { + tp_len = -EINVAL ; + goto tpacket_error; + } +memcpy (&vnet_hdr, data - vnet_hdr_sz,sizeof (vnet_hdr)); +if (__packet_snd_vnet_parse (&vnet_hdr, tp_len)) { tp_len = -EINVAL ; goto tpacket_error; } copylen =__virtio16_to_cpu (vio_le (), - vnet_hdr->hdr_len); + vnet_hdr.hdr_len); + has_vnet_hdr = true; } copylen =max_t (int, copylen, dev->hard_header_len); skb = sock_alloc_send_skb(&po->sk,
@@ -2917,12 +2922,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) } } -if (vnet_hdr_sz) { -if (virtio_net_hdr_to_skb (skb, vnet_hdr,vio_le ())) { +if (has_vnet_hdr) { +if (virtio_net_hdr_to_skb (skb, &vnet_hdr,vio_le ())) { tp_len = -EINVAL ; goto tpacket_error; } -virtio_net_hdr_set_proto (skb, vnet_hdr); +virtio_net_hdr_set_proto (skb, &vnet_hdr); } skb->destructor = tpacket_destruct_skb;
net/rxrpc/conn_event.c +12 -2
@@ -233,6 +233,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, struct sk_buff *skb) {struct rxrpc_skb_priv *sp =rxrpc_skb (skb); +bool secured = false;int ret;if (conn->state ==RXRPC_CONN_ABORTED )
@@ -245,6 +246,13 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,return conn->security->respond_to_challenge (conn, skb);case RXRPC_PACKET_TYPE_RESPONSE : +spin_lock (&conn->state_lock); +if (conn->state !=RXRPC_CONN_SERVICE_CHALLENGING ) { +spin_unlock (&conn->state_lock); +return 0 ; + } +spin_unlock (&conn->state_lock); + ret = conn->security->verify_response (conn, skb);if (ret <0 )return ret;
@@ -255,11 +263,13 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,return ret;spin_lock (&conn->state_lock); -if (conn->state ==RXRPC_CONN_SERVICE_CHALLENGING ) +if (conn->state ==RXRPC_CONN_SERVICE_CHALLENGING ) { conn->state =RXRPC_CONN_SERVICE ; + secured = true; + }spin_unlock (&conn->state_lock); -if (conn->state ==RXRPC_CONN_SERVICE ) { +if (secured) {/* Offload call state flipping to the I/O thread. As * we've already received the packet, put it on the * front of the queue.
net/rxrpc/key.c +4 -0
@@ -340,6 +340,10 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep)if (v1->security_index !=RXRPC_SECURITY_RXKAD ) goto error; + ret = -EKEYREJECTED ; +if (v1->ticket_length >AFSTOKEN_RK_TIX_MAX ) + goto error; + plen =sizeof (*token->kad) + v1->ticket_length; prep->quotalen += plen +sizeof (*token);
scripts/dtc/dtc-lexer.l +0 -3
@@ -39,8 +39,6 @@ extern bool treesource_error; #define DPRINT(fmt, ...) do { } while (0) #endif -static int dts_version = 1; - #define BEGIN_DEFAULT() DPRINT("<V1>\n"); \ BEGIN(V1); \
@@ -101,7 +99,6 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...); <*>"/dts-v1/" { DPRINT("Keyword: /dts-v1/\n"); - dts_version = 1; BEGIN_DEFAULT(); return DT_V1; }
scripts/generate_rust_analyzer.py +13 -1
@@ -144,6 +144,18 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit append_crate_with_generated("uapi", ["core", "ffi"]) append_crate_with_generated("kernel", ["core", "macros", "build_error", "ffi", "bindings", "uapi"]) + scripts = srctree / "scripts" + makefile = (scripts / "Makefile").read_text() + for path in scripts.glob("*.rs"): + name = path.stem + if f"{name}-rust" not in makefile: + continue + append_crate( + name, + path, + ["std"], + ) + def is_root_crate(build_file, target): try: contents = build_file.read_text()
@@ -160,7 +172,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit for folder in extra_dirs: for path in folder.rglob("*.rs"): logging.info("Checking %s", path) - name = path.name.replace(".rs", "") + name = path.stem # Skip those that are not crate roots. if not is_root_crate(path.parent / "Makefile", name) and \
scripts/rust_is_available.sh +15 -0
@@ -225,6 +225,21 @@ if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then exit 1 fi +if [ "$bindgen_libclang_cversion" -ge 1900100 ] && + [ "$rust_bindings_generator_cversion" -lt 6905 ]; then + # Distributions may have patched the issue (e.g. Debian did). + if ! "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang_concat.h | grep -q foofoo; then + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' < 0.69.5 together with libclang >= 19.1" + echo >&2 "*** may not work due to a bug (https://github.com/rust-lang/rust-bindgen/pull/2824)," + echo >&2 "*** unless patched (like Debian's)." + echo >&2 "*** Your bindgen version: $rust_bindings_generator_version" + echo >&2 "*** Your libclang version: $bindgen_libclang_version" + echo >&2 "***" + warning=1 + fi +fi + # If the C compiler is Clang, then we can also check whether its version # matches the `libclang` version used by the Rust bindings generator. #
scripts/rust_is_available_bindgen_libclang_concat.h new file +3 -0
@@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#define F (x) int x##x +F (foo);
scripts/rust_is_available_test.py +33 -1
@@ -54,7 +54,7 @@ else: """) @classmethod - def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False): + def generate_bindgen(cls, version_stdout, libclang_stderr, version_0_66_patched=False, libclang_concat_patched=False): if libclang_stderr is None: libclang_case = f"raise SystemExit({cls.bindgen_default_bindgen_libclang_failure_exit_code})" else:
@@ -65,12 +65,19 @@ else: else: version_0_66_case = "raise SystemExit(1)" + if libclang_concat_patched: + libclang_concat_case = "print('pub static mut foofoo: ::std::os::raw::c_int;')" + else: + libclang_concat_case = "pass" + return cls.generate_executable(f"""#!/usr/bin/env python3 import sys if "rust_is_available_bindgen_libclang.h" in " ".join(sys.argv): {libclang_case} elif "rust_is_available_bindgen_0_66.h" in " ".join(sys.argv): {version_0_66_case} +elif "rust_is_available_bindgen_libclang_concat.h" in " ".join(sys.argv): + {libclang_concat_case} else: print({repr(version_stdout)}) """)
@@ -268,6 +275,31 @@ else: result = self.run_script(self.Expected.FAILURE, { "BINDGEN": bindgen }) self.assertIn(f"libclang (used by the Rust bindings generator '{bindgen}') is too old.", result.stderr) + def test_bindgen_bad_libclang_concat(self): + for (bindgen_version, libclang_version, expected_not_patched) in ( + ("0.69.4", "18.0.0", self.Expected.SUCCESS), + ("0.69.4", "19.1.0", self.Expected.SUCCESS_WITH_WARNINGS), + ("0.69.4", "19.2.0", self.Expected.SUCCESS_WITH_WARNINGS), + + ("0.69.5", "18.0.0", self.Expected.SUCCESS), + ("0.69.5", "19.1.0", self.Expected.SUCCESS), + ("0.69.5", "19.2.0", self.Expected.SUCCESS), + + ("0.70.0", "18.0.0", self.Expected.SUCCESS), + ("0.70.0", "19.1.0", self.Expected.SUCCESS), + ("0.70.0", "19.2.0", self.Expected.SUCCESS), + ): + with self.subTest(bindgen_version=bindgen_version, libclang_version=libclang_version): + cc = self.generate_clang(f"clang version {libclang_version}") + libclang_stderr = f"scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version {libclang_version} [-W#pragma-messages], err: false" + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr) + result = self.run_script(expected_not_patched, { "BINDGEN": bindgen, "CC": cc }) + if expected_not_patched == self.Expected.SUCCESS_WITH_WARNINGS: + self.assertIn(f"Rust bindings generator '{bindgen}' < 0.69.5 together with libclang >= 19.1", result.stderr) + + bindgen = self.generate_bindgen(f"bindgen {bindgen_version}", libclang_stderr, libclang_concat_patched=True) + result = self.run_script(self.Expected.SUCCESS, { "BINDGEN": bindgen, "CC": cc }) + def test_clang_matches_bindgen_libclang_different_bindgen(self): bindgen = self.generate_bindgen_libclang("scripts/rust_is_available_bindgen_libclang.h:2:9: warning: clang version 999.0.0 [-W#pragma-messages], err: false") result = self.run_script(self.Expected.SUCCESS_WITH_WARNINGS, { "BINDGEN": bindgen })
security/integrity/ima/ima_kexec.c +13 -0
@@ -34,6 +34,14 @@ static void ima_free_kexec_file_buf(struct seq_file *sf)static int ima_alloc_kexec_file_buf (size_t segment_size) { +/* +* kexec 'load' may be called multiple times. +* Free and realloc the buffer only if the segment_size is +* changed from the previous kexec 'load' call. +*/ +if (ima_kexec_file.buf && ima_kexec_file.size == segment_size) + goto out; +ima_free_kexec_file_buf (&ima_kexec_file);/* segment size can't change between kexec load and execute */
@@ -42,6 +50,8 @@ static int ima_alloc_kexec_file_buf(size_t segment_size)return -ENOMEM ; ima_kexec_file.size = segment_size; + +out: ima_kexec_file.read_pos =0 ; ima_kexec_file.count =sizeof (struct ima_kexec_hdr );/* reserved space */
@@ -119,6 +129,9 @@ void ima_add_kexec_buffer(struct kimage *image)size_t kexec_segment_size;int ret; +if (image->type ==KEXEC_TYPE_CRASH ) +return ; +/* * Reserve an extra half page of memory for additional measurements * added during the kexec load.
sound/usb/caiaq/device.c +2 -2
@@ -384,7 +384,7 @@ static void card_free(struct snd_card *card)snd_usb_caiaq_input_free (cdev);#endif snd_usb_caiaq_audio_free (cdev); -usb_reset_device (cdev->chip.dev); +usb_put_dev (cdev->chip.dev); } static int create_card(struct usb_device *usb_dev,
@@ -410,7 +410,7 @@ static int create_card(struct usb_device *usb_dev,return err; cdev =caiaqdev (card); - cdev->chip.dev = usb_dev; + cdev->chip.dev =usb_get_dev (usb_dev); cdev->chip.card = card; cdev->chip.usb_id =USB_ID (le16_to_cpu (usb_dev->descriptor.idVendor),le16_to_cpu (usb_dev->descriptor.idProduct));
sound/usb/mixer.c +7 -0
@@ -1198,6 +1198,13 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, cval->min =-14208 ;/* Mute under it */ }break ; +case USB_ID (0x31b2 ,0x0111 ):/* MOONDROP JU Jiu */ +if (!strcmp (kctl->id.name,"PCM Playback Volume" )) { +usb_audio_info (chip, +"set volume quirk for MOONDROP JU Jiu\n" ); + cval->min =-10880 ;/* Mute under it */ + } +break ; } }