diff --git a/Makefile.rhelver b/Makefile.rhelver index 6a9c10d1e9711..e8d32f6025e8b 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 10 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 553.77.1 +RHEL_RELEASE = 553.79.1 # # ZSTREAM diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 33aa34a0bff34..98f5634917702 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -3431,8 +3431,6 @@ static void svm_inject_irq(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - BUG_ON(!(gif_set(svm))); - trace_kvm_inj_virq(vcpu->arch.interrupt.nr); ++vcpu->stat.irq_injections; diff --git a/ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/705c7910.failed b/ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/705c7910.failed new file mode 100644 index 0000000000000..21184a3d578db --- /dev/null +++ b/ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/705c7910.failed @@ -0,0 +1,158 @@ +smb: client: fix use-after-free in cifs_oplock_break + +jira LE-4375 +cve CVE-2025-38527 +Rebuild_History Non-Buildable kernel-4.18.0-553.78.1.el8_10 +commit-author Wang Zhaolong +commit 705c79101ccf9edea5a00d761491a03ced314210 +Empty-Commit: Cherry-Pick Conflicts during history rebuild. +Will be included in final tarball splat. Ref for failed cherry-pick at: +ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/705c7910.failed + +A race condition can occur in cifs_oplock_break() leading to a +use-after-free of the cinode structure when unmounting: + + cifs_oplock_break() + _cifsFileInfo_put(cfile) + cifsFileInfo_put_final() + cifs_sb_deactive() + [last ref, start releasing sb] + kill_sb() + kill_anon_super() + generic_shutdown_super() + evict_inodes() + dispose_list() + evict() + destroy_inode() + call_rcu(&inode->i_rcu, i_callback) + spin_lock(&cinode->open_file_lock) <- OK + [later] i_callback() + cifs_free_inode() + kmem_cache_free(cinode) + spin_unlock(&cinode->open_file_lock) <- UAF + cifs_done_oplock_break(cinode) <- UAF + +The issue occurs when umount has already released its reference to the +superblock. When _cifsFileInfo_put() calls cifs_sb_deactive(), this +releases the last reference, triggering the immediate cleanup of all +inodes under RCU. However, cifs_oplock_break() continues to access the +cinode after this point, resulting in use-after-free. + +Fix this by holding an extra reference to the superblock during the +entire oplock break operation. This ensures that the superblock and +its inodes remain valid until the oplock break completes. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220309 +Fixes: b98749cac4a6 ("CIFS: keep FileInfo handle live during oplock break") + Reviewed-by: Paulo Alcantara (Red Hat) + Signed-off-by: Wang Zhaolong + Signed-off-by: Steve French +(cherry picked from commit 705c79101ccf9edea5a00d761491a03ced314210) + Signed-off-by: Jonathan Maple + +# Conflicts: +# fs/cifs/file.c +diff --cc fs/cifs/file.c +index 6aaac9bc59dc,1421bde045c2..000000000000 +--- a/fs/cifs/file.c ++++ b/fs/cifs/file.c +@@@ -4767,12 -3088,23 +4767,23 @@@ void cifs_oplock_break(struct work_stru + struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, + oplock_break); + struct inode *inode = d_inode(cfile->dentry); +++<<<<<<< HEAD:fs/cifs/file.c +++======= ++ struct super_block *sb = inode->i_sb; ++ struct cifs_sb_info *cifs_sb = CIFS_SB(sb); +++>>>>>>> 705c79101ccf (smb: client: fix use-after-free in cifs_oplock_break):fs/smb/client/file.c + struct cifsInodeInfo *cinode = CIFS_I(inode); + - struct cifs_tcon *tcon; + - struct TCP_Server_Info *server; + - struct tcon_link *tlink; + + struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + + struct TCP_Server_Info *server = tcon->ses->server; + int rc = 0; + - bool purge_cache = false, oplock_break_cancelled; + - __u64 persistent_fid, volatile_fid; + - __u16 net_fid; + + bool purge_cache = false; + ++ /* ++ * Hold a reference to the superblock to prevent it and its inodes from ++ * being freed while we are accessing cinode. Otherwise, _cifsFileInfo_put() ++ * may release the last reference to the sb and trigger inode eviction. ++ */ ++ cifs_sb_active(sb); + wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, + TASK_UNINTERRUPTIBLE); + +@@@ -4808,39 -3146,40 +4819,40 @@@ + + oplock_break_ack: + /* + - * When oplock break is received and there are no active + - * file handles but cached, then schedule deferred close immediately. + - * So, new open will not use cached handle. + - */ + - + - if (!CIFS_CACHE_HANDLE(cinode) && !list_empty(&cinode->deferred_closes)) + - cifs_close_deferred_file(cinode); + - + - persistent_fid = cfile->fid.persistent_fid; + - volatile_fid = cfile->fid.volatile_fid; + - net_fid = cfile->fid.netfid; + - oplock_break_cancelled = cfile->oplock_break_cancelled; + - + - _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); + - /* + - * MS-SMB2 3.2.5.19.1 and 3.2.5.19.2 (and MS-CIFS 3.2.5.42) do not require + - * an acknowledgment to be sent when the file has already been closed. + + * releasing stale oplock after recent reconnect of smb session using + + * a now incorrect file handle is not a data integrity issue but do + + * not bother sending an oplock release if session to server still is + + * disconnected since oplock already released by the server + */ + - spin_lock(&cinode->open_file_lock); + - /* check list empty since can race with kill_sb calling tree disconnect */ + - if (!oplock_break_cancelled && !list_empty(&cinode->openFileList)) { + - spin_unlock(&cinode->open_file_lock); + - rc = server->ops->oplock_response(tcon, persistent_fid, + - volatile_fid, net_fid, cinode); + + if (!cfile->oplock_break_cancelled) { + + rc = tcon->ses->server->ops->oplock_response(tcon, &cfile->fid, + + cinode); + cifs_dbg(FYI, "Oplock release rc = %d\n", rc); + - } else + - spin_unlock(&cinode->open_file_lock); + - + - cifs_put_tlink(tlink); + -out: + + } + + _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); + cifs_done_oplock_break(cinode); ++ cifs_sb_deactive(sb); + } + + +/* + + * The presence of cifs_direct_io() in the address space ops vector + + * allowes open() O_DIRECT flags which would have failed otherwise. + + * + + * In the non-cached mode (mount with cache=none), we shunt off direct read and write requests + + * so this method should never be called. + + * + + * Direct IO is not yet supported in the cached mode. + + */ + +static ssize_t + +cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter) + +{ + + /* + + * FIXME + + * Eventually need to support direct IO for non forcedirectio mounts + + */ + + return -EINVAL; + +} + + + static int cifs_swap_activate(struct swap_info_struct *sis, + struct file *swap_file, sector_t *span) + { +* Unmerged path fs/cifs/file.c diff --git a/ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/rebuild.details.txt b/ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/rebuild.details.txt new file mode 100644 index 0000000000000..e574d286406c2 --- /dev/null +++ b/ciq/ciq_backports/kernel-4.18.0-553.78.1.el8_10/rebuild.details.txt @@ -0,0 +1,24 @@ +Rebuild_History BUILDABLE +Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% +Number of commits in upstream range v4.18~1..kernel-mainline: 567757 +Number of commits in rpm: 9 +Number of commits matched with upstream: 2 (22.22%) +Number of commits in upstream but not in rpm: 567755 +Number of commits NOT found in upstream: 7 (77.78%) + +Rebuilding Kernel on Branch rocky8_10_rebuild_kernel-4.18.0-553.78.1.el8_10 for kernel-4.18.0-553.78.1.el8_10 +Clean Cherry Picks: 1 (50.00%) +Empty Cherry Picks: 1 (50.00%) +_______________________________ + +__EMPTY COMMITS__________________________ +705c79101ccf9edea5a00d761491a03ced314210 smb: client: fix use-after-free in cifs_oplock_break + +__CHANGES NOT IN UPSTREAM________________ +Adding prod certs and changed cert date to 20210620 +Adding Rocky secure boot certs +Fixing vmlinuz removal +Fixing UEFI CA path +Porting to 8.10, debranding and Rocky branding +Fixing pesign_key_name values +mm/migrate: set swap entry values of THP tail pages properly. diff --git a/ciq/ciq_backports/kernel-4.18.0-553.79.1.el8_10/rebuild.details.txt b/ciq/ciq_backports/kernel-4.18.0-553.79.1.el8_10/rebuild.details.txt new file mode 100644 index 0000000000000..d5cf7f5b7191f --- /dev/null +++ b/ciq/ciq_backports/kernel-4.18.0-553.79.1.el8_10/rebuild.details.txt @@ -0,0 +1,22 @@ +Rebuild_History BUILDABLE +Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% +Number of commits in upstream range v4.18~1..kernel-mainline: 567757 +Number of commits in rpm: 8 +Number of commits matched with upstream: 2 (25.00%) +Number of commits in upstream but not in rpm: 567755 +Number of commits NOT found in upstream: 6 (75.00%) + +Rebuilding Kernel on Branch rocky8_10_rebuild_kernel-4.18.0-553.79.1.el8_10 for kernel-4.18.0-553.79.1.el8_10 +Clean Cherry Picks: 2 (100.00%) +Empty Cherry Picks: 0 (0.00%) +_______________________________ + +__EMPTY COMMITS__________________________ + +__CHANGES NOT IN UPSTREAM________________ +Adding prod certs and changed cert date to 20210620 +Adding Rocky secure boot certs +Fixing vmlinuz removal +Fixing UEFI CA path +Porting to 8.10, debranding and Rocky branding +Fixing pesign_key_name values diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 6aaac9bc59dce..d2f231baa1e47 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -4767,12 +4767,19 @@ void cifs_oplock_break(struct work_struct *work) struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, oplock_break); struct inode *inode = d_inode(cfile->dentry); + struct super_block *sb = inode->i_sb; struct cifsInodeInfo *cinode = CIFS_I(inode); struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); struct TCP_Server_Info *server = tcon->ses->server; int rc = 0; bool purge_cache = false; + /* + * Hold a reference to the superblock to prevent it and its inodes from + * being freed while we are accessing cinode. Otherwise, _cifsFileInfo_put() + * may release the last reference to the sb and trigger inode eviction. + */ + cifs_sb_active(sb); wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, TASK_UNINTERRUPTIBLE); @@ -4820,6 +4827,7 @@ void cifs_oplock_break(struct work_struct *work) } _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false); cifs_done_oplock_break(cinode); + cifs_sb_deactive(sb); } /* diff --git a/fs/nfs/export.c b/fs/nfs/export.c index fd67dc0b13a51..ceeeb0f7bd2da 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -66,14 +66,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, { struct nfs_fattr *fattr = NULL; struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw); - size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size; + size_t fh_size = offsetof(struct nfs_fh, data); const struct nfs_rpc_ops *rpc_ops; struct dentry *dentry; struct inode *inode; - int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size); + int len = EMBED_FH_OFF; u32 *p = fid->raw; int ret; + /* Initial check of bounds */ + if (fh_len < len + XDR_QUADLEN(fh_size) || + fh_len > XDR_QUADLEN(NFS_MAXFHSIZE)) + return NULL; + /* Calculate embedded filehandle size */ + fh_size += server_fh->size; + len += XDR_QUADLEN(fh_size); /* NULL translates to ESTALE */ if (fh_len < len || fh_type != len) return NULL; diff --git a/mm/migrate.c b/mm/migrate.c index f7498769feaba..fe8444fd7b5ba 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -441,8 +441,12 @@ int migrate_page_move_mapping(struct address_space *mapping, if (PageSwapBacked(page)) { __SetPageSwapBacked(newpage); if (PageSwapCache(page)) { + int i; + SetPageSwapCache(newpage); - set_page_private(newpage, page_private(page)); + for (i = 0; i < (1 << compound_order(page)); i++) + set_page_private(newpage + i, + page_private(page + i)); } } else { VM_BUG_ON_PAGE(PageSwapCache(page), page); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d7d636f9eba4b..e5c4730277f85 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -6339,9 +6339,14 @@ static inline int l2cap_le_command_rej(struct l2cap_conn *conn, if (!chan) goto done; + chan = l2cap_chan_hold_unless_zero(chan); + if (!chan) + goto done; + l2cap_chan_lock(chan); l2cap_chan_del(chan, ECONNREFUSED); l2cap_chan_unlock(chan); + l2cap_chan_put(chan); done: mutex_unlock(&conn->chan_lock);