* FAILED: patch "[PATCH] smb: client: close handle after create-context parsing" failed to apply to 6.18-stable tree
@ 2026-09-29 11:50 gregkh
2026-09-30 15:13 ` [PATCH 6.18.y 1/4] cifs: on replayable errors back-off before replay, not after Sasha Levin
0 siblings, 1 reply; 5+ messages in thread
From: gregkh @ 2026-09-29 11:50 UTC (permalink / raw)
To: zihanx, pc, root, sorenson, vega; +Cc: stable
The patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 566820af017e81497fb5e9d3ad6e7ffe2828bc8b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026092944-consensus-idealism-4247@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 566820af017e81497fb5e9d3ad6e7ffe2828bc8b Mon Sep 17 00:00:00 2001
From: Zihan Xi <zihanx@nebusec.ai>
Date: Wed, 16 Sep 2026 15:29:26 +0000
Subject: [PATCH] smb: client: close handle after create-context parsing
failure
SMB2_open() accounts a successful CREATE response as a remote open before
parsing its create contexts. If smb2_parse_contexts() rejects malformed
context data, SMB2_open() returns without closing the handle, leaving the
server-side handle open and num_remote_opens elevated.
Close the handle after a post-CREATE context parsing failure so the error
path releases the remote resource and balances the open count.
Fixes: af1689a9b770 ("smb: client: fix potential OOBs in smb2_parse_contexts()")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 538d708b0404..3d7ead36d1a0 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -3416,6 +3416,9 @@ replay_again:
rc = smb2_parse_contexts(server, &rsp_iov, &oparms->fid->epoch,
oparms->fid->lease_key, oplock, file_info, posix);
+ if (rc)
+ SMB2_close(xid, tcon, oparms->fid->persistent_fid,
+ oparms->fid->volatile_fid);
trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid,
oparms->create_options, oparms->desired_access,
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.18.y 1/4] cifs: on replayable errors back-off before replay, not after 2026-09-29 11:50 FAILED: patch "[PATCH] smb: client: close handle after create-context parsing" failed to apply to 6.18-stable tree gregkh @ 2026-09-30 15:13 ` Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 2/4] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() Sasha Levin ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Sasha Levin @ 2026-09-30 15:13 UTC (permalink / raw) To: stable; +Cc: Shyam Prasad N, Steve French, Sasha Levin From: Shyam Prasad N <sprasad@microsoft.com> [ Upstream commit 16d480ed4990ed5aefb99c111dd14131a338e3c9 ] On replayable errors, we call smb2_should_replays that does these things today: 1. decide if we need to replay the command again 2. sleep to back-off the failed request 3. update the next sleep value We will not be able to use this for async requests, when this is processed in callbacks (as this will be called in cifsd threads that should not sleep in response processing). Modify the behaviour by taking the sleep out of smb2_should_replay and performing the sleep for back-off just before actually performing the replay. Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> Stable-dep-of: 566820af017e ("smb: client: close handle after create-context parsing failure") Signed-off-by: Sasha Levin <sashal@kernel.org> --- fs/smb/client/cached_dir.c | 6 +- fs/smb/client/smb2inode.c | 21 +++++-- fs/smb/client/smb2ops.c | 32 ++++++++--- fs/smb/client/smb2pdu.c | 112 +++++++++++++++++++++++++++---------- 4 files changed, 129 insertions(+), 42 deletions(-) diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index cef855456063a..7e6d2607a221f 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -154,7 +154,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, struct cached_fid *cfid; struct cached_fids *cfids; const char *npath; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; __le32 lease_flags = 0; if (cifs_sb->root == NULL) @@ -312,6 +312,10 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[1]); if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); + smb2_set_replay(server, &rqst[0]); smb2_set_replay(server, &rqst[1]); } diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 2e28a965a25d1..22e943bf14611 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -199,7 +199,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, struct reparse_data_buffer *rbuf; struct TCP_Server_Info *server; int resp_buftype[MAX_COMPOUND]; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; __u8 delete_pending[8] = {1,}; struct kvec *rsp_iov, *iov; struct inode *inode = NULL; @@ -649,18 +649,26 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, num_rqst++; if (cfile) { - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); for (i = 1; i < num_rqst - 2; i++) smb2_set_replay(server, &rqst[i]); + } rc = compound_send_recv(xid, ses, server, flags, num_rqst - 2, &rqst[1], &resp_buftype[1], &rsp_iov[1]); } else { - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); for (i = 0; i < num_rqst; i++) smb2_set_replay(server, &rqst[i]); + } rc = compound_send_recv(xid, ses, server, flags, num_rqst, @@ -1208,7 +1216,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, { struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; __le16 *utf16_path __free(kfree) = NULL; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; struct TCP_Server_Info *server; struct cifs_open_parms oparms; struct smb2_create_req *creq; @@ -1272,6 +1280,9 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, smb2_set_related(&rqst[1]); if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); for (int i = 0; i < ARRAY_SIZE(rqst); i++) smb2_set_replay(server, &rqst[i]); } @@ -1292,7 +1303,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, if (rc == -EINVAL && dentry) { dentry = NULL; retries = 0; - cur_sleep = 1; + cur_sleep = 0; goto again; } /* diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index dcf0a9b9647c7..0ab41f241181a 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -1210,7 +1210,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, struct smb2_file_full_ea_info *ea; struct smb2_query_info_rsp *rsp; int rc, used_len = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -1341,6 +1341,9 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[2]); if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst[0]); smb2_set_replay(server, &rqst[1]); smb2_set_replay(server, &rqst[2]); @@ -1605,7 +1608,7 @@ smb2_ioctl_query_info(const unsigned int xid, void *data[2]; int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR; void (*free_req1_func)(struct smb_rqst *r); - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -1755,6 +1758,9 @@ smb2_ioctl_query_info(const unsigned int xid, smb2_set_related(&rqst[2]); if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst[0]); smb2_set_replay(server, &rqst[1]); smb2_set_replay(server, &rqst[2]); @@ -2545,7 +2551,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, struct smb2_query_directory_rsp *qd_rsp = NULL; struct smb2_create_rsp *op_rsp = NULL; struct TCP_Server_Info *server; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -2603,6 +2609,9 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[1]); if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst[0]); smb2_set_replay(server, &rqst[1]); } @@ -2879,10 +2888,14 @@ bool smb2_should_replay(struct cifs_tcon *tcon, return false; if (tcon->retry || (*pretries)++ < tcon->ses->server->retrans) { - msleep(*pcur_sleep); - (*pcur_sleep) = ((*pcur_sleep) << 1); - if ((*pcur_sleep) > CIFS_MAX_SLEEP) - (*pcur_sleep) = CIFS_MAX_SLEEP; + /* Update sleep time for exponential backoff */ + if (!(*pcur_sleep)) + (*pcur_sleep) = 1; + else { + (*pcur_sleep) = ((*pcur_sleep) << 1); + if ((*pcur_sleep) > CIFS_MAX_SLEEP) + (*pcur_sleep) = CIFS_MAX_SLEEP; + } return true; } @@ -2913,7 +2926,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, int rc; __le16 *utf16_path; struct cached_fid *cfid; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -3003,6 +3016,9 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, smb2_set_related(&rqst[2]); if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); if (!cfid) { smb2_set_replay(server, &rqst[0]); smb2_set_replay(server, &rqst[2]); diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index c07c5bb321407..200f4e854462c 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -2840,7 +2840,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, unsigned int total_len; __le16 *utf16_path = NULL; struct TCP_Server_Info *server; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -2953,8 +2953,12 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, full_path, CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES); - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } /* resource #4: response buffer */ rc = cifs_send_recv(xid, ses, server, @@ -3202,7 +3206,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, int resp_buftype = CIFS_NO_BUFFER; int rc = 0; int flags = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -3232,8 +3236,12 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->path, oparms->create_options, oparms->desired_access); - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, @@ -3417,7 +3425,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, int resp_buftype = CIFS_NO_BUFFER; int rc = 0; int flags = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; if (!tcon) return -EIO; @@ -3459,8 +3467,12 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (rc) goto ioctl_exit; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, @@ -3614,7 +3626,7 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, int rc = 0; int flags = 0; bool query_attrs = false; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -3648,8 +3660,12 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, if (rc) goto close_exit; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -3819,7 +3835,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, struct TCP_Server_Info *server; int flags = 0; bool allocated = false; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; cifs_dbg(FYI, "Query Info\n"); @@ -3855,8 +3871,12 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid, ses->Suid, info_class, (__u32)info_type); - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -4012,7 +4032,7 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype = CIFS_NO_BUFFER; int flags = 0; int rc = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -4045,8 +4065,12 @@ SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid, (u8)watch_tree, completion_filter); - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -4353,7 +4377,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, int resp_buftype = CIFS_NO_BUFFER; int flags = 0; int rc = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -4381,8 +4405,12 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid); - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -5148,7 +5176,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, int flags = 0; unsigned int total_len; struct TCP_Server_Info *server; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -5199,8 +5227,12 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, iov_iter_kvec(&rqst.rq_iter, ITER_SOURCE, &iov[1], n_vec, io_parms->length); - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, io_parms->tcon->ses, server, &rqst, @@ -5551,7 +5583,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_ses *ses = tcon->ses; struct TCP_Server_Info *server; int flags = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -5576,8 +5608,12 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, if (rc) goto qdir_exit; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -5686,7 +5722,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_ses *ses = tcon->ses; struct TCP_Server_Info *server; int flags = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -5721,8 +5757,12 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, return rc; } - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, @@ -5801,7 +5841,7 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, struct kvec iov[1]; struct kvec rsp_iov; int resp_buf_type; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -5831,8 +5871,12 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 1; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buf_type, flags, &rsp_iov); @@ -5934,7 +5978,7 @@ SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, struct TCP_Server_Info *server; FILE_SYSTEM_POSIX_INFO *info = NULL; int flags = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -5955,8 +5999,12 @@ SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = &iov; rqst.rq_nvec = 1; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -5999,7 +6047,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, struct TCP_Server_Info *server; unsigned int rsp_len, offset; int flags = 0; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -6036,8 +6084,12 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = &iov; rqst.rq_nvec = 1; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -6099,7 +6151,7 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, int flags = CIFS_NO_RSP_BUF; unsigned int total_len; struct TCP_Server_Info *server; - int retries = 0, cur_sleep = 1; + int retries = 0, cur_sleep = 0; replay_again: /* reinitialize for possible replay */ @@ -6135,8 +6187,12 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, rqst.rq_iov = iov; rqst.rq_nvec = 2; - if (retries) + if (retries) { + /* Back-off before retry */ + if (cur_sleep) + msleep(cur_sleep); smb2_set_replay(server, &rqst); + } rc = cifs_send_recv(xid, tcon->ses, server, &rqst, &resp_buf_type, flags, -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 2/4] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() 2026-09-30 15:13 ` [PATCH 6.18.y 1/4] cifs: on replayable errors back-off before replay, not after Sasha Levin @ 2026-09-30 15:13 ` Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 3/4] smb/client: pass cifs_open_info_data to SMB2_open() Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 4/4] smb: client: close handle after create-context parsing failure Sasha Levin 2 siblings, 0 replies; 5+ messages in thread From: Sasha Levin @ 2026-09-30 15:13 UTC (permalink / raw) To: stable; +Cc: ChenXiaoSong, Steve French, Sasha Levin From: ChenXiaoSong <chenxiaosong@kylinos.cn> [ Upstream commit fc8789bb57e625e5f32ac57ca2e7d3e7b7fda225 ] SMB2_open() only fills the fixed fields, so a stack-allocated smb2_file_all_info is sufficient here. Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com> Stable-dep-of: 566820af017e ("smb: client: close handle after create-context parsing failure") Signed-off-by: Sasha Levin <sashal@kernel.org> --- fs/smb/client/link.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c index ac31564ce9265..8654b03637347 100644 --- a/fs/smb/client/link.c +++ b/fs/smb/client/link.c @@ -320,7 +320,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int buf_type = CIFS_NO_BUFFER; __le16 *utf16_path; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; - struct smb2_file_all_info *pfile_info = NULL; + struct smb2_file_all_info file_info = {}; oparms = (struct cifs_open_parms) { .tcon = tcon, @@ -336,20 +336,12 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, if (utf16_path == NULL) return -ENOMEM; - pfile_info = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, - GFP_KERNEL); - - if (pfile_info == NULL) { - kfree(utf16_path); - return -ENOMEM; - } - - rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL, + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, &file_info, NULL, NULL, NULL); if (rc) goto qmf_out_open_fail; - if (pfile_info->EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { + if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { /* it's not a symlink */ rc = -ENOENT; /* Is there a better rc to return? */ goto qmf_out; @@ -367,7 +359,6 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); qmf_out_open_fail: kfree(utf16_path); - kfree(pfile_info); return rc; } -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 3/4] smb/client: pass cifs_open_info_data to SMB2_open() 2026-09-30 15:13 ` [PATCH 6.18.y 1/4] cifs: on replayable errors back-off before replay, not after Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 2/4] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() Sasha Levin @ 2026-09-30 15:13 ` Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 4/4] smb: client: close handle after create-context parsing failure Sasha Levin 2 siblings, 0 replies; 5+ messages in thread From: Sasha Levin @ 2026-09-30 15:13 UTC (permalink / raw) To: stable; +Cc: ChenXiaoSong, Steve French, Sasha Levin From: ChenXiaoSong <chenxiaosong@kylinos.cn> [ Upstream commit 1f551e407bb49dce0bbd34ed6a499dad69e18020 ] Let SMB2_open() fill the smb2_file_all_info embedded in cifs_open_info_data directly. This removes the temporary smb2_file_all_info copy in smb2_open_file(). Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com> For 6.18, retain the existing extern declarations in smb2proto.h and move the existing six-argument open-done trace call after context parsing. This supplies the context needed for 566820af017e without importing the upstream oplock tracepoint extension or adding functions. Stable-dep-of: 566820af017e ("smb: client: close handle after create-context parsing failure") Signed-off-by: Sasha Levin <sashal@kernel.org> --- fs/smb/client/link.c | 6 +++--- fs/smb/client/smb2file.c | 19 ++++++++----------- fs/smb/client/smb2pdu.c | 31 ++++++++++++++++--------------- fs/smb/client/smb2proto.h | 2 +- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c index 8654b03637347..9a6a23e038b65 100644 --- a/fs/smb/client/link.c +++ b/fs/smb/client/link.c @@ -320,7 +320,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int buf_type = CIFS_NO_BUFFER; __le16 *utf16_path; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; - struct smb2_file_all_info file_info = {}; + struct cifs_open_info_data data = {}; oparms = (struct cifs_open_parms) { .tcon = tcon, @@ -336,12 +336,12 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, if (utf16_path == NULL) return -ENOMEM; - rc = SMB2_open(xid, &oparms, utf16_path, &oplock, &file_info, NULL, + rc = SMB2_open(xid, &oparms, utf16_path, &oplock, &data, NULL, NULL, NULL); if (rc) goto qmf_out_open_fail; - if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { + if (data.fi.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) { /* it's not a symlink */ rc = -ENOENT; /* Is there a better rc to return? */ goto qmf_out; diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index 36efebef82e41..865bfd0b07a20 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -170,8 +170,6 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *smb2_path; __u8 smb2_oplock; struct cifs_open_info_data *data = buf; - struct smb2_file_all_info file_info = {}; - struct smb2_file_all_info *smb2_data = data ? &file_info : NULL; struct kvec err_iov = {}; int err_buftype = CIFS_NO_BUFFER; struct cifs_fid *fid = oparms->fid; @@ -198,14 +196,14 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, } smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH; - rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, + rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, data, NULL, &err_iov, &err_buftype); if (rc == -EACCES && retry_without_read_attributes) { free_rsp_buf(err_buftype, err_iov.iov_base); memset(&err_iov, 0, sizeof(err_iov)); err_buftype = CIFS_NO_BUFFER; oparms->desired_access &= ~FILE_READ_ATTRIBUTES; - rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov, + rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, data, NULL, &err_iov, &err_buftype); } if (rc && data) { @@ -226,9 +224,9 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, if (rc == -ENODATA) rc = -EIO; if (!rc) { - memset(smb2_data, 0, sizeof(*smb2_data)); + memset(&data->fi, 0, sizeof(data->fi)); oparms->create_options |= OPEN_REPARSE_POINT; - rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, + rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, data, NULL, NULL, NULL); oparms->create_options &= ~OPEN_REPARSE_POINT; } @@ -262,23 +260,22 @@ int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms, rc = 0; } - if (smb2_data) { + if (data) { /* if open response does not have IndexNumber field - get it */ - if (smb2_data->IndexNumber == 0) { + if (data->fi.IndexNumber == 0) { rc = SMB2_get_srv_num(xid, oparms->tcon, fid->persistent_fid, fid->volatile_fid, - &smb2_data->IndexNumber); + &data->fi.IndexNumber); if (rc) { /* * let get_inode_info disable server inode * numbers */ - smb2_data->IndexNumber = 0; + data->fi.IndexNumber = 0; rc = 0; } } - memcpy(&data->fi, smb2_data, sizeof(data->fi)); } *oplock = smb2_oplock; diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 200f4e854462c..040a10fbe9dd8 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -3192,7 +3192,7 @@ SMB2_open_free(struct smb_rqst *rqst) int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, - __u8 *oplock, struct smb2_file_all_info *buf, + __u8 *oplock, struct cifs_open_info_data *buf, struct create_posix_rsp *posix, struct kvec *err_iov, int *buftype) { @@ -3207,6 +3207,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, int rc = 0; int flags = 0; int retries = 0, cur_sleep = 0; + struct smb2_file_all_info *file_info = buf ? &buf->fi : NULL; replay_again: /* reinitialize for possible replay */ @@ -3266,9 +3267,6 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, goto creat_exit; } else if (rsp == NULL) /* unlikely to happen, but safer to check */ goto creat_exit; - else - trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid, - oparms->create_options, oparms->desired_access); atomic_inc(&tcon->num_remote_opens); oparms->fid->persistent_fid = rsp->PersistentFileId; @@ -3278,21 +3276,24 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, oparms->fid->mid = le64_to_cpu(rsp->hdr.MessageId); #endif /* CIFS_DEBUG2 */ - if (buf) { - buf->CreationTime = rsp->CreationTime; - buf->LastAccessTime = rsp->LastAccessTime; - buf->LastWriteTime = rsp->LastWriteTime; - buf->ChangeTime = rsp->ChangeTime; - buf->AllocationSize = rsp->AllocationSize; - buf->EndOfFile = rsp->EndofFile; - buf->Attributes = rsp->FileAttributes; - buf->NumberOfLinks = cpu_to_le32(1); - buf->DeletePending = 0; /* successful open = not delete pending */ + if (file_info) { + file_info->CreationTime = rsp->CreationTime; + file_info->LastAccessTime = rsp->LastAccessTime; + file_info->LastWriteTime = rsp->LastWriteTime; + file_info->ChangeTime = rsp->ChangeTime; + file_info->AllocationSize = rsp->AllocationSize; + file_info->EndOfFile = rsp->EndofFile; + file_info->Attributes = rsp->FileAttributes; + file_info->NumberOfLinks = cpu_to_le32(1); + file_info->DeletePending = 0; /* successful open = not delete pending */ } rc = smb2_parse_contexts(server, &rsp_iov, &oparms->fid->epoch, - oparms->fid->lease_key, oplock, buf, posix); + oparms->fid->lease_key, oplock, file_info, posix); + + trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid, + oparms->create_options, oparms->desired_access); creat_exit: SMB2_open_free(&rqst); free_rsp_buf(resp_buftype, rsp); diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index 92e6b93d72c49..2dddf655cf1f6 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -147,7 +147,7 @@ extern int SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon); extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, __u8 *oplock, - struct smb2_file_all_info *buf, + struct cifs_open_info_data *buf, struct create_posix_rsp *posix, struct kvec *err_iov, int *resp_buftype); extern int SMB2_open_init(struct cifs_tcon *tcon, -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.18.y 4/4] smb: client: close handle after create-context parsing failure 2026-09-30 15:13 ` [PATCH 6.18.y 1/4] cifs: on replayable errors back-off before replay, not after Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 2/4] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 3/4] smb/client: pass cifs_open_info_data to SMB2_open() Sasha Levin @ 2026-09-30 15:13 ` Sasha Levin 2 siblings, 0 replies; 5+ messages in thread From: Sasha Levin @ 2026-09-30 15:13 UTC (permalink / raw) To: stable Cc: Zihan Xi, Vega, Luxing Yin, Frank Sorenson, Paulo Alcantara, Sasha Levin From: Zihan Xi <zihanx@nebusec.ai> [ Upstream commit 566820af017e81497fb5e9d3ad6e7ffe2828bc8b ] SMB2_open() accounts a successful CREATE response as a remote open before parsing its create contexts. If smb2_parse_contexts() rejects malformed context data, SMB2_open() returns without closing the handle, leaving the server-side handle open and num_remote_opens elevated. Close the handle after a post-CREATE context parsing failure so the error path releases the remote resource and balances the open count. Fixes: af1689a9b770 ("smb: client: fix potential OOBs in smb2_parse_contexts()") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Assisted-by: LLM Co-developed-by: Luxing Yin <root@tr0jan.top> Signed-off-by: Luxing Yin <root@tr0jan.top> Signed-off-by: Zihan Xi <zihanx@nebusec.ai> Tested-by: Frank Sorenson <sorenson@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Signed-off-by: Sasha Levin <sashal@kernel.org> --- fs/smb/client/smb2pdu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 040a10fbe9dd8..aeb9630fa2ce2 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -3291,6 +3291,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, rc = smb2_parse_contexts(server, &rsp_iov, &oparms->fid->epoch, oparms->fid->lease_key, oplock, file_info, posix); + if (rc) + SMB2_close(xid, tcon, oparms->fid->persistent_fid, + oparms->fid->volatile_fid); trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ses->Suid, oparms->create_options, oparms->desired_access); -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-30 15:14 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-29 11:50 FAILED: patch "[PATCH] smb: client: close handle after create-context parsing" failed to apply to 6.18-stable tree gregkh 2026-09-30 15:13 ` [PATCH 6.18.y 1/4] cifs: on replayable errors back-off before replay, not after Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 2/4] smb/client: use stack-allocated smb2_file_all_info in smb3_query_mf_symlink() Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 3/4] smb/client: pass cifs_open_info_data to SMB2_open() Sasha Levin 2026-09-30 15:13 ` [PATCH 6.18.y 4/4] smb: client: close handle after create-context parsing failure Sasha Levin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox