]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Apr 2026 08:07:17 +0000 (10:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Apr 2026 08:07:17 +0000 (10:07 +0200)
added patches:
crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch
crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispatch.patch
ksmbd-fix-use-after-free-in-__ksmbd_close_fd-via-durable-scavenger.patch
ksmbd-validate-owner-of-durable-handle-on-reconnect.patch
scripts-generate_rust_analyzer.py-define-scripts.patch

queue-7.0/crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch [new file with mode: 0644]
queue-7.0/crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispatch.patch [new file with mode: 0644]
queue-7.0/ksmbd-fix-use-after-free-in-__ksmbd_close_fd-via-durable-scavenger.patch [new file with mode: 0644]
queue-7.0/ksmbd-validate-owner-of-durable-handle-on-reconnect.patch [new file with mode: 0644]
queue-7.0/scripts-generate_rust_analyzer.py-define-scripts.patch [new file with mode: 0644]
queue-7.0/series

diff --git a/queue-7.0/crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch b/queue-7.0/crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch
new file mode 100644 (file)
index 0000000..019d584
--- /dev/null
@@ -0,0 +1,159 @@
+From 3bfbf5f0a99c991769ec562721285df7ab69240b Mon Sep 17 00:00:00 2001
+From: Dudu Lu <phx0fer@gmail.com>
+Date: Mon, 20 Apr 2026 12:40:27 +0800
+Subject: crypto: krb5enc - fix async decrypt skipping hash verification
+
+From: Dudu Lu <phx0fer@gmail.com>
+
+commit 3bfbf5f0a99c991769ec562721285df7ab69240b upstream.
+
+krb5enc_dispatch_decrypt() sets req->base.complete as the skcipher
+callback, which is the caller's own completion handler. When the
+skcipher completes asynchronously, this signals "done" to the caller
+without executing krb5enc_dispatch_decrypt_hash(), completely bypassing
+the integrity verification (hash check).
+
+Compare with the encrypt path which correctly uses
+krb5enc_encrypt_done as an intermediate callback to chain into the
+hash computation on async completion.
+
+Fix by adding krb5enc_decrypt_done as an intermediate callback that
+chains into krb5enc_dispatch_decrypt_hash() upon async skcipher
+completion, matching the encrypt path's callback pattern.
+
+Also fix EBUSY/EINPROGRESS handling throughout: remove
+krb5enc_request_complete() which incorrectly swallowed EINPROGRESS
+notifications that must be passed up to callers waiting on backlogged
+requests, and add missing EBUSY checks in krb5enc_encrypt_ahash_done
+for the dispatch_encrypt return value.
+
+Fixes: d1775a177f7f ("crypto: Add 'krb5enc' hash and cipher AEAD algorithm")
+Signed-off-by: Dudu Lu <phx0fer@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+Unset MAY_BACKLOG on the async completion path so the user won't
+see back-to-back EINPROGRESS notifications.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+---
+ crypto/krb5enc.c |   52 +++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 31 insertions(+), 21 deletions(-)
+
+--- a/crypto/krb5enc.c
++++ b/crypto/krb5enc.c
+@@ -39,12 +39,6 @@ struct krb5enc_request_ctx {
+       char tail[];
+ };
+-static void krb5enc_request_complete(struct aead_request *req, int err)
+-{
+-      if (err != -EINPROGRESS)
+-              aead_request_complete(req, err);
+-}
+-
+ /**
+  * crypto_krb5enc_extractkeys - Extract Ke and Ki keys from the key blob.
+  * @keys: Where to put the key sizes and pointers
+@@ -127,7 +121,7 @@ static void krb5enc_encrypt_done(void *d
+ {
+       struct aead_request *req = data;
+-      krb5enc_request_complete(req, err);
++      aead_request_complete(req, err);
+ }
+ /*
+@@ -188,14 +182,16 @@ static void krb5enc_encrypt_ahash_done(v
+       struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
+       if (err)
+-              return krb5enc_request_complete(req, err);
++              goto out;
+       krb5enc_insert_checksum(req, ahreq->result);
+-      err = krb5enc_dispatch_encrypt(req,
+-                                     aead_request_flags(req) & ~CRYPTO_TFM_REQ_MAY_SLEEP);
+-      if (err != -EINPROGRESS)
+-              aead_request_complete(req, err);
++      err = krb5enc_dispatch_encrypt(req, 0);
++      if (err == -EINPROGRESS)
++              return;
++
++out:
++      aead_request_complete(req, err);
+ }
+ /*
+@@ -265,17 +261,16 @@ static void krb5enc_decrypt_hash_done(vo
+ {
+       struct aead_request *req = data;
+-      if (err)
+-              return krb5enc_request_complete(req, err);
+-
+-      err = krb5enc_verify_hash(req);
+-      krb5enc_request_complete(req, err);
++      if (!err)
++              err = krb5enc_verify_hash(req);
++      aead_request_complete(req, err);
+ }
+ /*
+  * Dispatch the hashing of the plaintext after we've done the decryption.
+  */
+-static int krb5enc_dispatch_decrypt_hash(struct aead_request *req)
++static int krb5enc_dispatch_decrypt_hash(struct aead_request *req,
++                                       unsigned int flags)
+ {
+       struct crypto_aead *krb5enc = crypto_aead_reqtfm(req);
+       struct aead_instance *inst = aead_alg_instance(krb5enc);
+@@ -291,7 +286,7 @@ static int krb5enc_dispatch_decrypt_hash
+       ahash_request_set_tfm(ahreq, auth);
+       ahash_request_set_crypt(ahreq, req->dst, hash,
+                               req->assoclen + req->cryptlen - authsize);
+-      ahash_request_set_callback(ahreq, aead_request_flags(req),
++      ahash_request_set_callback(ahreq, flags,
+                                  krb5enc_decrypt_hash_done, req);
+       err = crypto_ahash_digest(ahreq);
+@@ -301,6 +296,21 @@ static int krb5enc_dispatch_decrypt_hash
+       return krb5enc_verify_hash(req);
+ }
++static void krb5enc_decrypt_done(void *data, int err)
++{
++      struct aead_request *req = data;
++
++      if (err)
++              goto out;
++
++      err = krb5enc_dispatch_decrypt_hash(req, 0);
++      if (err == -EINPROGRESS)
++              return;
++
++out:
++      aead_request_complete(req, err);
++}
++
+ /*
+  * Dispatch the decryption of the ciphertext.
+  */
+@@ -324,7 +334,7 @@ static int krb5enc_dispatch_decrypt(stru
+       skcipher_request_set_tfm(skreq, ctx->enc);
+       skcipher_request_set_callback(skreq, aead_request_flags(req),
+-                                    req->base.complete, req->base.data);
++                                    krb5enc_decrypt_done, req);
+       skcipher_request_set_crypt(skreq, src, dst,
+                                  req->cryptlen - authsize, req->iv);
+@@ -339,7 +349,7 @@ static int krb5enc_decrypt(struct aead_r
+       if (err < 0)
+               return err;
+-      return krb5enc_dispatch_decrypt_hash(req);
++      return krb5enc_dispatch_decrypt_hash(req, aead_request_flags(req));
+ }
+ static int krb5enc_init_tfm(struct crypto_aead *tfm)
diff --git a/queue-7.0/crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispatch.patch b/queue-7.0/crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispatch.patch
new file mode 100644 (file)
index 0000000..9cbab0d
--- /dev/null
@@ -0,0 +1,52 @@
+From 2ef3bac16fb5e9eee4fb1d722578a79b751ea58a Mon Sep 17 00:00:00 2001
+From: Wesley Atwell <atwellwea@gmail.com>
+Date: Mon, 9 Mar 2026 00:26:24 -0600
+Subject: crypto: krb5enc - fix sleepable flag handling in encrypt dispatch
+
+From: Wesley Atwell <atwellwea@gmail.com>
+
+commit 2ef3bac16fb5e9eee4fb1d722578a79b751ea58a upstream.
+
+krb5enc_encrypt_ahash_done() continues encryption from an ahash
+completion callback by calling krb5enc_dispatch_encrypt().
+
+That helper takes a flags argument for this continuation path, but it
+ignored that argument and reused aead_request_flags(req) when setting
+up the skcipher subrequest callback. This can incorrectly preserve
+CRYPTO_TFM_REQ_MAY_SLEEP when the encrypt step is started from callback
+context.
+
+Preserve the original request flags but clear
+CRYPTO_TFM_REQ_MAY_SLEEP for the callback continuation path, and use
+the caller-supplied flags when setting up the skcipher subrequest.
+
+Fixes: d1775a177f7f ("crypto: Add 'krb5enc' hash and cipher AEAD algorithm")
+Assisted-by: Codex:GPT-5
+Signed-off-by: Wesley Atwell <atwellwea@gmail.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ crypto/krb5enc.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/crypto/krb5enc.c
++++ b/crypto/krb5enc.c
+@@ -154,7 +154,7 @@ static int krb5enc_dispatch_encrypt(stru
+               dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
+       skcipher_request_set_tfm(skreq, enc);
+-      skcipher_request_set_callback(skreq, aead_request_flags(req),
++      skcipher_request_set_callback(skreq, flags,
+                                     krb5enc_encrypt_done, req);
+       skcipher_request_set_crypt(skreq, src, dst, req->cryptlen, req->iv);
+@@ -192,7 +192,8 @@ static void krb5enc_encrypt_ahash_done(v
+       krb5enc_insert_checksum(req, ahreq->result);
+-      err = krb5enc_dispatch_encrypt(req, 0);
++      err = krb5enc_dispatch_encrypt(req,
++                                     aead_request_flags(req) & ~CRYPTO_TFM_REQ_MAY_SLEEP);
+       if (err != -EINPROGRESS)
+               aead_request_complete(req, err);
+ }
diff --git a/queue-7.0/ksmbd-fix-use-after-free-in-__ksmbd_close_fd-via-durable-scavenger.patch b/queue-7.0/ksmbd-fix-use-after-free-in-__ksmbd_close_fd-via-durable-scavenger.patch
new file mode 100644 (file)
index 0000000..b3d3f5c
--- /dev/null
@@ -0,0 +1,137 @@
+From stable+bounces-239935-greg=kroah.com@vger.kernel.org Mon Apr 20 19:59:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 12:15:30 -0400
+Subject: ksmbd: fix use-after-free in __ksmbd_close_fd() via durable scavenger
+To: stable@vger.kernel.org
+Cc: Namjae Jeon <linkinjeon@kernel.org>, munan Huang <munanevil@gmail.com>, ChenXiaoSong <chenxiaosong@kylinos.cn>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420161531.1241004-1-sashal@kernel.org>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 235e32320a470fcd3998fb3774f2290a0eb302a1 ]
+
+When a durable file handle survives session disconnect (TCP close without
+SMB2_LOGOFF), session_fd_check() sets fp->conn = NULL to preserve the
+handle for later reconnection. However, it did not clean up the byte-range
+locks on fp->lock_list.
+
+Later, when the durable scavenger thread times out and calls
+__ksmbd_close_fd(NULL, fp), the lock cleanup loop did:
+
+    spin_lock(&fp->conn->llist_lock);
+
+This caused a slab use-after-free because fp->conn was NULL and the
+original connection object had already been freed by
+ksmbd_tcp_disconnect().
+
+The root cause is asymmetric cleanup: lock entries (smb_lock->clist) were
+left dangling on the freed conn->lock_list while fp->conn was nulled out.
+
+To fix this issue properly, we need to handle the lifetime of
+smb_lock->clist across three paths:
+ - Safely skip clist deletion when list is empty and fp->conn is NULL.
+ - Remove the lock from the old connection's lock_list in
+   session_fd_check()
+ - Re-add the lock to the new connection's lock_list in
+   ksmbd_reopen_durable_fd().
+
+Fixes: c8efcc786146 ("ksmbd: add support for durable handles v1/v2")
+Co-developed-by: munan Huang <munanevil@gmail.com>
+Signed-off-by: munan Huang <munanevil@gmail.com>
+Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Stable-dep-of: 49110a8ce654 ("ksmbd: validate owner of durable handle on reconnect")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/vfs_cache.c |   41 ++++++++++++++++++++++++++++++-----------
+ 1 file changed, 30 insertions(+), 11 deletions(-)
+
+--- a/fs/smb/server/vfs_cache.c
++++ b/fs/smb/server/vfs_cache.c
+@@ -463,9 +463,11 @@ static void __ksmbd_close_fd(struct ksmb
+        * there are not accesses to fp->lock_list.
+        */
+       list_for_each_entry_safe(smb_lock, tmp_lock, &fp->lock_list, flist) {
+-              spin_lock(&fp->conn->llist_lock);
+-              list_del(&smb_lock->clist);
+-              spin_unlock(&fp->conn->llist_lock);
++              if (!list_empty(&smb_lock->clist) && fp->conn) {
++                      spin_lock(&fp->conn->llist_lock);
++                      list_del(&smb_lock->clist);
++                      spin_unlock(&fp->conn->llist_lock);
++              }
+               list_del(&smb_lock->flist);
+               locks_free_lock(smb_lock->fl);
+@@ -995,6 +997,7 @@ static bool session_fd_check(struct ksmb
+       struct ksmbd_inode *ci;
+       struct oplock_info *op;
+       struct ksmbd_conn *conn;
++      struct ksmbd_lock *smb_lock, *tmp_lock;
+       if (!is_reconnectable(fp))
+               return false;
+@@ -1011,6 +1014,12 @@ static bool session_fd_check(struct ksmb
+       }
+       up_write(&ci->m_lock);
++      list_for_each_entry_safe(smb_lock, tmp_lock, &fp->lock_list, flist) {
++              spin_lock(&fp->conn->llist_lock);
++              list_del_init(&smb_lock->clist);
++              spin_unlock(&fp->conn->llist_lock);
++      }
++
+       fp->conn = NULL;
+       fp->tcon = NULL;
+       fp->volatile_id = KSMBD_NO_FID;
+@@ -1090,6 +1099,9 @@ int ksmbd_reopen_durable_fd(struct ksmbd
+ {
+       struct ksmbd_inode *ci;
+       struct oplock_info *op;
++      struct ksmbd_conn *conn = work->conn;
++      struct ksmbd_lock *smb_lock;
++      unsigned int old_f_state;
+       if (!fp->is_durable || fp->conn || fp->tcon) {
+               pr_err("Invalid durable fd [%p:%p]\n", fp->conn, fp->tcon);
+@@ -1101,9 +1113,23 @@ int ksmbd_reopen_durable_fd(struct ksmbd
+               return -EBADF;
+       }
+-      fp->conn = work->conn;
++      old_f_state = fp->f_state;
++      fp->f_state = FP_NEW;
++      __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
++      if (!has_file_id(fp->volatile_id)) {
++              fp->f_state = old_f_state;
++              return -EBADF;
++      }
++
++      fp->conn = conn;
+       fp->tcon = work->tcon;
++      list_for_each_entry(smb_lock, &fp->lock_list, flist) {
++              spin_lock(&conn->llist_lock);
++              list_add_tail(&smb_lock->clist, &conn->lock_list);
++              spin_unlock(&conn->llist_lock);
++      }
++
+       ci = fp->f_ci;
+       down_write(&ci->m_lock);
+       list_for_each_entry_rcu(op, &ci->m_op_list, op_entry) {
+@@ -1114,13 +1140,6 @@ int ksmbd_reopen_durable_fd(struct ksmbd
+       }
+       up_write(&ci->m_lock);
+-      fp->f_state = FP_NEW;
+-      __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
+-      if (!has_file_id(fp->volatile_id)) {
+-              fp->conn = NULL;
+-              fp->tcon = NULL;
+-              return -EBADF;
+-      }
+       return 0;
+ }
diff --git a/queue-7.0/ksmbd-validate-owner-of-durable-handle-on-reconnect.patch b/queue-7.0/ksmbd-validate-owner-of-durable-handle-on-reconnect.patch
new file mode 100644 (file)
index 0000000..a223b97
--- /dev/null
@@ -0,0 +1,327 @@
+From stable+bounces-239936-greg=kroah.com@vger.kernel.org Mon Apr 20 18:45:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 12:15:31 -0400
+Subject: ksmbd: validate owner of durable handle on reconnect
+To: stable@vger.kernel.org
+Cc: Namjae Jeon <linkinjeon@kernel.org>, Davide Ornaghi <d.ornaghi97@gmail.com>, Navaneeth K <knavaneeth786@gmail.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420161531.1241004-2-sashal@kernel.org>
+
+From: Namjae Jeon <linkinjeon@kernel.org>
+
+[ Upstream commit 49110a8ce654bbe56bef7c5e44cce31f4b102b8a ]
+
+Currently, ksmbd does not verify if the user attempting to reconnect
+to a durable handle is the same user who originally opened the file.
+This allows any authenticated user to hijack an orphaned durable handle
+by predicting or brute-forcing the persistent ID.
+
+According to MS-SMB2, the server MUST verify that the SecurityContext
+of the reconnect request matches the SecurityContext associated with
+the existing open.
+Add a durable_owner structure to ksmbd_file to store the original opener's
+UID, GID, and account name. and catpure the owner information when a file
+handle becomes orphaned. and implementing ksmbd_vfs_compare_durable_owner()
+to validate the identity of the requester during SMB2_CREATE (DHnC).
+
+Fixes: c8efcc786146 ("ksmbd: add support for durable handles v1/v2")
+Reported-by: Davide Ornaghi <d.ornaghi97@gmail.com>
+Reported-by: Navaneeth K <knavaneeth786@gmail.com>
+Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/server/mgmt/user_session.c |    8 +--
+ fs/smb/server/oplock.c            |    7 +++
+ fs/smb/server/oplock.h            |    1 
+ fs/smb/server/smb2pdu.c           |    3 -
+ fs/smb/server/vfs_cache.c         |   87 ++++++++++++++++++++++++++++++++++----
+ fs/smb/server/vfs_cache.h         |   12 ++++-
+ 6 files changed, 102 insertions(+), 16 deletions(-)
+
+--- a/fs/smb/server/mgmt/user_session.c
++++ b/fs/smb/server/mgmt/user_session.c
+@@ -382,12 +382,10 @@ void ksmbd_session_destroy(struct ksmbd_
+               return;
+       delete_proc_session(sess);
+-
++      ksmbd_tree_conn_session_logoff(sess);
++      ksmbd_destroy_file_table(sess);
+       if (sess->user)
+               ksmbd_free_user(sess->user);
+-
+-      ksmbd_tree_conn_session_logoff(sess);
+-      ksmbd_destroy_file_table(&sess->file_table);
+       ksmbd_launch_ksmbd_durable_scavenger();
+       ksmbd_session_rpc_clear_list(sess);
+       free_channel_list(sess);
+@@ -618,7 +616,7 @@ void destroy_previous_session(struct ksm
+               goto out;
+       }
+-      ksmbd_destroy_file_table(&prev_sess->file_table);
++      ksmbd_destroy_file_table(prev_sess);
+       prev_sess->state = SMB2_SESSION_EXPIRED;
+       ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_SETUP);
+       ksmbd_launch_ksmbd_durable_scavenger();
+--- a/fs/smb/server/oplock.c
++++ b/fs/smb/server/oplock.c
+@@ -1841,6 +1841,7 @@ int smb2_check_durable_oplock(struct ksm
+                             struct ksmbd_share_config *share,
+                             struct ksmbd_file *fp,
+                             struct lease_ctx_info *lctx,
++                            struct ksmbd_user *user,
+                             char *name)
+ {
+       struct oplock_info *opinfo = opinfo_get(fp);
+@@ -1849,6 +1850,12 @@ int smb2_check_durable_oplock(struct ksm
+       if (!opinfo)
+               return 0;
++      if (ksmbd_vfs_compare_durable_owner(fp, user) == false) {
++              ksmbd_debug(SMB, "Durable handle reconnect failed: owner mismatch\n");
++              ret = -EBADF;
++              goto out;
++      }
++
+       if (opinfo->is_lease == false) {
+               if (lctx) {
+                       pr_err("create context include lease\n");
+--- a/fs/smb/server/oplock.h
++++ b/fs/smb/server/oplock.h
+@@ -126,5 +126,6 @@ int smb2_check_durable_oplock(struct ksm
+                             struct ksmbd_share_config *share,
+                             struct ksmbd_file *fp,
+                             struct lease_ctx_info *lctx,
++                            struct ksmbd_user *user,
+                             char *name);
+ #endif /* __KSMBD_OPLOCK_H */
+--- a/fs/smb/server/smb2pdu.c
++++ b/fs/smb/server/smb2pdu.c
+@@ -3013,7 +3013,8 @@ int smb2_open(struct ksmbd_work *work)
+               }
+               if (dh_info.reconnected == true) {
+-                      rc = smb2_check_durable_oplock(conn, share, dh_info.fp, lc, name);
++                      rc = smb2_check_durable_oplock(conn, share, dh_info.fp,
++                                      lc, sess->user, name);
+                       if (rc) {
+                               ksmbd_put_durable_fd(dh_info.fp);
+                               goto err_out2;
+--- a/fs/smb/server/vfs_cache.c
++++ b/fs/smb/server/vfs_cache.c
+@@ -19,6 +19,7 @@
+ #include "misc.h"
+ #include "mgmt/tree_connect.h"
+ #include "mgmt/user_session.h"
++#include "mgmt/user_config.h"
+ #include "smb_common.h"
+ #include "server.h"
+ #include "smb2pdu.h"
+@@ -476,6 +477,8 @@ static void __ksmbd_close_fd(struct ksmb
+       if (ksmbd_stream_fd(fp))
+               kfree(fp->stream.name);
++      kfree(fp->owner.name);
++
+       kmem_cache_free(filp_cache, fp);
+ }
+@@ -787,11 +790,13 @@ void ksmbd_update_fstate(struct ksmbd_fi
+ }
+ static int
+-__close_file_table_ids(struct ksmbd_file_table *ft,
++__close_file_table_ids(struct ksmbd_session *sess,
+                      struct ksmbd_tree_connect *tcon,
+                      bool (*skip)(struct ksmbd_tree_connect *tcon,
+-                                  struct ksmbd_file *fp))
++                                  struct ksmbd_file *fp,
++                                  struct ksmbd_user *user))
+ {
++      struct ksmbd_file_table *ft = &sess->file_table;
+       struct ksmbd_file *fp;
+       unsigned int id = 0;
+       int num = 0;
+@@ -804,7 +809,7 @@ __close_file_table_ids(struct ksmbd_file
+                       break;
+               }
+-              if (skip(tcon, fp) ||
++              if (skip(tcon, fp, sess->user) ||
+                   !atomic_dec_and_test(&fp->refcount)) {
+                       id++;
+                       write_unlock(&ft->lock);
+@@ -856,7 +861,8 @@ static inline bool is_reconnectable(stru
+ }
+ static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon,
+-                             struct ksmbd_file *fp)
++                             struct ksmbd_file *fp,
++                             struct ksmbd_user *user)
+ {
+       return fp->tcon != tcon;
+ }
+@@ -991,8 +997,62 @@ void ksmbd_stop_durable_scavenger(void)
+       kthread_stop(server_conf.dh_task);
+ }
++/*
++ * ksmbd_vfs_copy_durable_owner - Copy owner info for durable reconnect
++ * @fp: ksmbd file pointer to store owner info
++ * @user: user pointer to copy from
++ *
++ * This function binds the current user's identity to the file handle
++ * to satisfy MS-SMB2 Step 8 (SecurityContext matching) during reconnect.
++ *
++ * Return: 0 on success, or negative error code on failure
++ */
++static int ksmbd_vfs_copy_durable_owner(struct ksmbd_file *fp,
++              struct ksmbd_user *user)
++{
++      if (!user)
++              return -EINVAL;
++
++      /* Duplicate the user name to ensure identity persistence */
++      fp->owner.name = kstrdup(user->name, GFP_KERNEL);
++      if (!fp->owner.name)
++              return -ENOMEM;
++
++      fp->owner.uid = user->uid;
++      fp->owner.gid = user->gid;
++
++      return 0;
++}
++
++/**
++ * ksmbd_vfs_compare_durable_owner - Verify if the requester is original owner
++ * @fp: existing ksmbd file pointer
++ * @user: user pointer of the reconnect requester
++ *
++ * Compares the UID, GID, and name of the current requester against the
++ * original owner stored in the file handle.
++ *
++ * Return: true if the user matches, false otherwise
++ */
++bool ksmbd_vfs_compare_durable_owner(struct ksmbd_file *fp,
++              struct ksmbd_user *user)
++{
++      if (!user || !fp->owner.name)
++              return false;
++
++      /* Check if the UID and GID match first (fast path) */
++      if (fp->owner.uid != user->uid || fp->owner.gid != user->gid)
++              return false;
++
++      /* Validate the account name to ensure the same SecurityContext */
++      if (strcmp(fp->owner.name, user->name))
++              return false;
++
++      return true;
++}
++
+ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
+-                           struct ksmbd_file *fp)
++                           struct ksmbd_file *fp, struct ksmbd_user *user)
+ {
+       struct ksmbd_inode *ci;
+       struct oplock_info *op;
+@@ -1002,6 +1062,9 @@ static bool session_fd_check(struct ksmb
+       if (!is_reconnectable(fp))
+               return false;
++      if (ksmbd_vfs_copy_durable_owner(fp, user))
++              return false;
++
+       conn = fp->conn;
+       ci = fp->f_ci;
+       down_write(&ci->m_lock);
+@@ -1033,7 +1096,7 @@ static bool session_fd_check(struct ksmb
+ void ksmbd_close_tree_conn_fds(struct ksmbd_work *work)
+ {
+-      int num = __close_file_table_ids(&work->sess->file_table,
++      int num = __close_file_table_ids(work->sess,
+                                        work->tcon,
+                                        tree_conn_fd_check);
+@@ -1042,7 +1105,7 @@ void ksmbd_close_tree_conn_fds(struct ks
+ void ksmbd_close_session_fds(struct ksmbd_work *work)
+ {
+-      int num = __close_file_table_ids(&work->sess->file_table,
++      int num = __close_file_table_ids(work->sess,
+                                        work->tcon,
+                                        session_fd_check);
+@@ -1140,6 +1203,10 @@ int ksmbd_reopen_durable_fd(struct ksmbd
+       }
+       up_write(&ci->m_lock);
++      fp->owner.uid = fp->owner.gid = 0;
++      kfree(fp->owner.name);
++      fp->owner.name = NULL;
++
+       return 0;
+ }
+@@ -1154,12 +1221,14 @@ int ksmbd_init_file_table(struct ksmbd_f
+       return 0;
+ }
+-void ksmbd_destroy_file_table(struct ksmbd_file_table *ft)
++void ksmbd_destroy_file_table(struct ksmbd_session *sess)
+ {
++      struct ksmbd_file_table *ft = &sess->file_table;
++
+       if (!ft->idr)
+               return;
+-      __close_file_table_ids(ft, NULL, session_fd_check);
++      __close_file_table_ids(sess, NULL, session_fd_check);
+       idr_destroy(ft->idr);
+       kfree(ft->idr);
+       ft->idr = NULL;
+--- a/fs/smb/server/vfs_cache.h
++++ b/fs/smb/server/vfs_cache.h
+@@ -68,6 +68,13 @@ enum {
+       FP_CLOSED
+ };
++/* Owner information for durable handle reconnect */
++struct durable_owner {
++      unsigned int uid;
++      unsigned int gid;
++      char *name;
++};
++
+ struct ksmbd_file {
+       struct file                     *filp;
+       u64                             persistent_id;
+@@ -114,6 +121,7 @@ struct ksmbd_file {
+       bool                            is_resilient;
+       bool                            is_posix_ctxt;
++      struct durable_owner            owner;
+ };
+ static inline void set_ctx_actor(struct dir_context *ctx,
+@@ -140,7 +148,7 @@ static inline bool ksmbd_stream_fd(struc
+ }
+ int ksmbd_init_file_table(struct ksmbd_file_table *ft);
+-void ksmbd_destroy_file_table(struct ksmbd_file_table *ft);
++void ksmbd_destroy_file_table(struct ksmbd_session *sess);
+ int ksmbd_close_fd(struct ksmbd_work *work, u64 id);
+ struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id);
+ struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id);
+@@ -166,6 +174,8 @@ void ksmbd_free_global_file_table(void);
+ void ksmbd_set_fd_limit(unsigned long limit);
+ void ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp,
+                        unsigned int state);
++bool ksmbd_vfs_compare_durable_owner(struct ksmbd_file *fp,
++              struct ksmbd_user *user);
+ /*
+  * INODE hash
diff --git a/queue-7.0/scripts-generate_rust_analyzer.py-define-scripts.patch b/queue-7.0/scripts-generate_rust_analyzer.py-define-scripts.patch
new file mode 100644 (file)
index 0000000..2ad8f53
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-239256-greg=kroah.com@vger.kernel.org Mon Apr 20 17:45:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:58:30 -0400
+Subject: scripts: generate_rust_analyzer.py: define scripts
+To: stable@vger.kernel.org
+Cc: Tamir Duberstein <tamird@kernel.org>, Daniel Almeida <daniel.almeida@collabora.com>, Fiona Behrens <me@kloenk.dev>, Trevor Gross <tmgross@umich.edu>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420145830.1151150-1-sashal@kernel.org>
+
+From: Tamir Duberstein <tamird@kernel.org>
+
+[ Upstream commit 36c619f6bd793493294becb10a02fea370b67a91 ]
+
+Add IDE support for host-side scripts written in Rust. This support has
+been missing since these scripts were initially added in commit
+9a8ff24ce584 ("scripts: add `generate_rust_target.rs`"), thus add it.
+
+Change the existing instance of extension stripping to
+`pathlib.Path.stem` to maintain code consistency.
+
+Fixes: 9a8ff24ce584 ("scripts: add `generate_rust_target.rs`")
+Cc: stable@vger.kernel.org
+Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
+Reviewed-by: Fiona Behrens <me@kloenk.dev>
+Reviewed-by: Trevor Gross <tmgross@umich.edu>
+Link: https://patch.msgid.link/20260122-rust-analyzer-scripts-v1-1-ff6ba278170e@kernel.org
+Signed-off-by: Tamir Duberstein <tamird@kernel.org>
+[ changed `[std]` dep to `["std"]` and kept untyped `is_root_crate()` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ scripts/generate_rust_analyzer.py |   14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/scripts/generate_rust_analyzer.py
++++ b/scripts/generate_rust_analyzer.py
+@@ -188,6 +188,18 @@ def generate_crates(srctree, objtree, sy
+     append_crate_with_generated("uapi", ["core", "ffi", "pin_init"])
+     append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "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()
+@@ -204,7 +216,7 @@ def generate_crates(srctree, objtree, sy
+     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 \
index 63d4134e86649dd2420b90d5a599093d0fb85ece..a5a42e82f722073ed09cfed3f5b24633e0b376ef 100644 (file)
@@ -1,3 +1,8 @@
 crypto-authencesn-fix-src-offset-when-decrypting-in-place.patch
 pwm-th1520-fix-clippy-1-warning.patch
 drm-amdgpu-replace-pasid-idr-with-xarray.patch
+crypto-krb5enc-fix-sleepable-flag-handling-in-encrypt-dispatch.patch
+crypto-krb5enc-fix-async-decrypt-skipping-hash-verification.patch
+ksmbd-fix-use-after-free-in-__ksmbd_close_fd-via-durable-scavenger.patch
+ksmbd-validate-owner-of-durable-handle-on-reconnect.patch
+scripts-generate_rust_analyzer.py-define-scripts.patch