Linux CIFS filesystem development
 help / color / mirror / Atom feed
* [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses()
@ 2023-10-30 20:19 Paulo Alcantara
  2023-10-30 20:19 ` [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show() Paulo Alcantara
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Paulo Alcantara @ 2023-10-30 20:19 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

If @ses->chan_count <= 1, then for-loop body will not be executed so
no need to check it twice.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/connect.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 7b923e36501b..a017ee552256 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1969,9 +1969,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
 
 void __cifs_put_smb_ses(struct cifs_ses *ses)
 {
-	unsigned int rc, xid;
-	unsigned int chan_count;
 	struct TCP_Server_Info *server = ses->server;
+	unsigned int xid;
+	size_t i;
+	int rc;
 
 	spin_lock(&ses->ses_lock);
 	if (ses->ses_status == SES_EXITING) {
@@ -2017,20 +2018,14 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
 	list_del_init(&ses->smb_ses_list);
 	spin_unlock(&cifs_tcp_ses_lock);
 
-	chan_count = ses->chan_count;
-
 	/* close any extra channels */
-	if (chan_count > 1) {
-		int i;
-
-		for (i = 1; i < chan_count; i++) {
-			if (ses->chans[i].iface) {
-				kref_put(&ses->chans[i].iface->refcount, release_iface);
-				ses->chans[i].iface = NULL;
-			}
-			cifs_put_tcp_session(ses->chans[i].server, 0);
-			ses->chans[i].server = NULL;
+	for (i = 1; i < ses->chan_count; i++) {
+		if (ses->chans[i].iface) {
+			kref_put(&ses->chans[i].iface->refcount, release_iface);
+			ses->chans[i].iface = NULL;
 		}
+		cifs_put_tcp_session(ses->chans[i].server, 0);
+		ses->chans[i].server = NULL;
 	}
 
 	sesInfoFree(ses);
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show()
  2023-10-30 20:19 [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Paulo Alcantara
@ 2023-10-30 20:19 ` Paulo Alcantara
  2023-10-31  3:17   ` Steve French
  2024-06-01 11:50   ` Wang Zhaolong
  2023-10-30 20:19 ` [PATCH 3/4] smb: client: fix potential deadlock when releasing mids Paulo Alcantara
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 11+ messages in thread
From: Paulo Alcantara @ 2023-10-30 20:19 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara, Frank Sorenson

Skip SMB sessions that are being teared down
(e.g. @ses->ses_status == SES_EXITING) in cifs_debug_data_proc_show()
to avoid use-after-free in @ses.

This fixes the following GPF when reading from /proc/fs/cifs/DebugData
while mounting and umounting

  [ 816.251274] general protection fault, probably for non-canonical
  address 0x6b6b6b6b6b6b6d81: 0000 [#1] PREEMPT SMP NOPTI
  ...
  [  816.260138] Call Trace:
  [  816.260329]  <TASK>
  [  816.260499]  ? die_addr+0x36/0x90
  [  816.260762]  ? exc_general_protection+0x1b3/0x410
  [  816.261126]  ? asm_exc_general_protection+0x26/0x30
  [  816.261502]  ? cifs_debug_tcon+0xbd/0x240 [cifs]
  [  816.261878]  ? cifs_debug_tcon+0xab/0x240 [cifs]
  [  816.262249]  cifs_debug_data_proc_show+0x516/0xdb0 [cifs]
  [  816.262689]  ? seq_read_iter+0x379/0x470
  [  816.262995]  seq_read_iter+0x118/0x470
  [  816.263291]  proc_reg_read_iter+0x53/0x90
  [  816.263596]  ? srso_alias_return_thunk+0x5/0x7f
  [  816.263945]  vfs_read+0x201/0x350
  [  816.264211]  ksys_read+0x75/0x100
  [  816.264472]  do_syscall_64+0x3f/0x90
  [  816.264750]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
  [  816.265135] RIP: 0033:0x7fd5e669d381

Cc: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/cifs_debug.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 76922fcc4bc6..9a0ccd87468e 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -452,6 +452,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
 		seq_printf(m, "\n\n\tSessions: ");
 		i = 0;
 		list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
+			spin_lock(&ses->ses_lock);
+			if (ses->ses_status == SES_EXITING) {
+				spin_unlock(&ses->ses_lock);
+				continue;
+			}
 			i++;
 			if ((ses->serverDomain == NULL) ||
 				(ses->serverOS == NULL) ||
@@ -472,6 +477,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
 				ses->ses_count, ses->serverOS, ses->serverNOS,
 				ses->capabilities, ses->ses_status);
 			}
+			spin_unlock(&ses->ses_lock);
 
 			seq_printf(m, "\n\tSecurity type: %s ",
 				get_security_type_str(server->ops->select_sectype(server, ses->sectype)));
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/4] smb: client: fix potential deadlock when releasing mids
  2023-10-30 20:19 [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Paulo Alcantara
  2023-10-30 20:19 ` [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show() Paulo Alcantara
@ 2023-10-30 20:19 ` Paulo Alcantara
  2023-10-31  3:23   ` Steve French
  2023-10-30 20:19 ` [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound() Paulo Alcantara
  2023-10-31  3:24 ` [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Steve French
  3 siblings, 1 reply; 11+ messages in thread
From: Paulo Alcantara @ 2023-10-30 20:19 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara, Frank Sorenson

All release_mid() callers seem to hold a reference of @mid so there is
no need to call kref_put(&mid->refcount, __release_mid) under
@server->mid_lock spinlock.  If they don't, then an use-after-free bug
would have occurred anyway.

By getting rid of such spinlock also fixes a potential deadlock as
shown below

CPU 0                                CPU 1
------------------------------------------------------------------
cifs_demultiplex_thread()            cifs_debug_data_proc_show()
 release_mid()
  spin_lock(&server->mid_lock);
                                     spin_lock(&cifs_tcp_ses_lock)
				      spin_lock(&server->mid_lock)
  __release_mid()
   smb2_find_smb_tcon()
    spin_lock(&cifs_tcp_ses_lock) *deadlock*

Cc: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/cifsproto.h |  7 ++++++-
 fs/smb/client/smb2misc.c  |  2 +-
 fs/smb/client/transport.c | 11 +----------
 3 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 0c37eefa18a5..890ceddae07e 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -81,7 +81,7 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 char *cifs_build_devname(char *nodename, const char *prepath);
 extern void delete_mid(struct mid_q_entry *mid);
-extern void release_mid(struct mid_q_entry *mid);
+void __release_mid(struct kref *refcount);
 extern void cifs_wake_up_task(struct mid_q_entry *mid);
 extern int cifs_handle_standard(struct TCP_Server_Info *server,
 				struct mid_q_entry *mid);
@@ -740,4 +740,9 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
 	return true;
 }
 
+static inline void release_mid(struct mid_q_entry *mid)
+{
+	kref_put(&mid->refcount, __release_mid);
+}
+
 #endif			/* _CIFSPROTO_H */
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index 25f7cd6f23d6..32dfa0f7a78c 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -787,7 +787,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
 {
 	struct close_cancelled_open *cancelled;
 
-	cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
+	cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
 	if (!cancelled)
 		return -ENOMEM;
 
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index 14710afdc2a3..d553b7a54621 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -76,7 +76,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
 	return temp;
 }
 
-static void __release_mid(struct kref *refcount)
+void __release_mid(struct kref *refcount)
 {
 	struct mid_q_entry *midEntry =
 			container_of(refcount, struct mid_q_entry, refcount);
@@ -156,15 +156,6 @@ static void __release_mid(struct kref *refcount)
 	mempool_free(midEntry, cifs_mid_poolp);
 }
 
-void release_mid(struct mid_q_entry *mid)
-{
-	struct TCP_Server_Info *server = mid->server;
-
-	spin_lock(&server->mid_lock);
-	kref_put(&mid->refcount, __release_mid);
-	spin_unlock(&server->mid_lock);
-}
-
 void
 delete_mid(struct mid_q_entry *mid)
 {
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound()
  2023-10-30 20:19 [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Paulo Alcantara
  2023-10-30 20:19 ` [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show() Paulo Alcantara
  2023-10-30 20:19 ` [PATCH 3/4] smb: client: fix potential deadlock when releasing mids Paulo Alcantara
@ 2023-10-30 20:19 ` Paulo Alcantara
  2023-10-31  3:09   ` Steve French
  2023-10-31  3:24 ` [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Steve French
  3 siblings, 1 reply; 11+ messages in thread
From: Paulo Alcantara @ 2023-10-30 20:19 UTC (permalink / raw)
  To: smfrench; +Cc: linux-cifs, Paulo Alcantara

The following UAF was triggered when running fstests generic/072 with
KASAN enabled against Windows Server 2022 and mount options
'multichannel,max_channels=2,vers=3.1.1,mfsymlinks,noperm'

  BUG: KASAN: slab-use-after-free in smb2_query_info_compound+0x423/0x6d0 [cifs]
  Read of size 8 at addr ffff888014941048 by task xfs_io/27534

  CPU: 0 PID: 27534 Comm: xfs_io Not tainted 6.6.0-rc7 #1
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
  rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
  Call Trace:
   dump_stack_lvl+0x4a/0x80
   print_report+0xcf/0x650
   ? srso_alias_return_thunk+0x5/0x7f
   ? srso_alias_return_thunk+0x5/0x7f
   ? __phys_addr+0x46/0x90
   kasan_report+0xda/0x110
   ? smb2_query_info_compound+0x423/0x6d0 [cifs]
   ? smb2_query_info_compound+0x423/0x6d0 [cifs]
   smb2_query_info_compound+0x423/0x6d0 [cifs]
   ? __pfx_smb2_query_info_compound+0x10/0x10 [cifs]
   ? srso_alias_return_thunk+0x5/0x7f
   ? __stack_depot_save+0x39/0x480
   ? kasan_save_stack+0x33/0x60
   ? kasan_set_track+0x25/0x30
   ? ____kasan_slab_free+0x126/0x170
   smb2_queryfs+0xc2/0x2c0 [cifs]
   ? __pfx_smb2_queryfs+0x10/0x10 [cifs]
   ? __pfx___lock_acquire+0x10/0x10
   smb311_queryfs+0x210/0x220 [cifs]
   ? __pfx_smb311_queryfs+0x10/0x10 [cifs]
   ? srso_alias_return_thunk+0x5/0x7f
   ? __lock_acquire+0x480/0x26c0
   ? lock_release+0x1ed/0x640
   ? srso_alias_return_thunk+0x5/0x7f
   ? do_raw_spin_unlock+0x9b/0x100
   cifs_statfs+0x18c/0x4b0 [cifs]
   statfs_by_dentry+0x9b/0xf0
   fd_statfs+0x4e/0xb0
   __do_sys_fstatfs+0x7f/0xe0
   ? __pfx___do_sys_fstatfs+0x10/0x10
   ? srso_alias_return_thunk+0x5/0x7f
   ? lockdep_hardirqs_on_prepare+0x136/0x200
   ? srso_alias_return_thunk+0x5/0x7f
   do_syscall_64+0x3f/0x90
   entry_SYSCALL_64_after_hwframe+0x6e/0xd8

  Allocated by task 27534:
   kasan_save_stack+0x33/0x60
   kasan_set_track+0x25/0x30
   __kasan_kmalloc+0x8f/0xa0
   open_cached_dir+0x71b/0x1240 [cifs]
   smb2_query_info_compound+0x5c3/0x6d0 [cifs]
   smb2_queryfs+0xc2/0x2c0 [cifs]
   smb311_queryfs+0x210/0x220 [cifs]
   cifs_statfs+0x18c/0x4b0 [cifs]
   statfs_by_dentry+0x9b/0xf0
   fd_statfs+0x4e/0xb0
   __do_sys_fstatfs+0x7f/0xe0
   do_syscall_64+0x3f/0x90
   entry_SYSCALL_64_after_hwframe+0x6e/0xd8

  Freed by task 27534:
   kasan_save_stack+0x33/0x60
   kasan_set_track+0x25/0x30
   kasan_save_free_info+0x2b/0x50
   ____kasan_slab_free+0x126/0x170
   slab_free_freelist_hook+0xd0/0x1e0
   __kmem_cache_free+0x9d/0x1b0
   open_cached_dir+0xff5/0x1240 [cifs]
   smb2_query_info_compound+0x5c3/0x6d0 [cifs]
   smb2_queryfs+0xc2/0x2c0 [cifs]

This is a race between open_cached_dir() and cached_dir_lease_break()
where the cache entry for the open directory handle receives a lease
break while creating it.  And before returning from open_cached_dir(),
we put the last reference of the new @cfid because of
!@cfid->has_lease.

Besides the UAF, while running xfstests a lot of missed lease breaks
have been noticed in tests that run several concurrent statfs(2) calls
on those cached fids

  CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
  CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
  CIFS: VFS: \\w22-root1.gandalf.test smb buf 00000000715bfe83 len 108
  CIFS: VFS: Dump pending requests:
  CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
  CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
  CIFS: VFS: \\w22-root1.gandalf.test smb buf 000000005aa7316e len 108
  ...

To fix both, in open_cached_dir() ensure that @cfid->has_lease is set
right before sending out compounded request so that any potential
lease break will be get processed by demultiplex thread while we're
still caching @cfid.  And, if open failed for some reason, re-check
@cfid->has_lease to decide whether or not put lease reference.

Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
---
 fs/smb/client/cached_dir.c | 84 ++++++++++++++++++++++----------------
 1 file changed, 49 insertions(+), 35 deletions(-)

diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
index fe1bf5b6e0cb..59f6b8e32cc9 100644
--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -32,7 +32,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
 			 * fully cached or it may be in the process of
 			 * being deleted due to a lease break.
 			 */
-			if (!cfid->has_lease) {
+			if (!cfid->time || !cfid->has_lease) {
 				spin_unlock(&cfids->cfid_list_lock);
 				return NULL;
 			}
@@ -193,10 +193,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	npath = path_no_prefix(cifs_sb, path);
 	if (IS_ERR(npath)) {
 		rc = PTR_ERR(npath);
-		kfree(utf16_path);
-		return rc;
+		goto out;
 	}
 
+	if (!npath[0]) {
+		dentry = dget(cifs_sb->root);
+	} else {
+		dentry = path_to_dentry(cifs_sb, npath);
+		if (IS_ERR(dentry)) {
+			rc = -ENOENT;
+			goto out;
+		}
+	}
+	cfid->dentry = dentry;
+
 	/*
 	 * We do not hold the lock for the open because in case
 	 * SMB2_open needs to reconnect.
@@ -249,6 +259,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 
 	smb2_set_related(&rqst[1]);
 
+	/*
+	 * Set @cfid->has_lease to true before sending out compounded request so
+	 * its lease reference can be put in cached_dir_lease_break() due to a
+	 * potential lease break right after the request is sent or while @cfid
+	 * is still being cached.  Concurrent processes won't be to use it yet
+	 * due to @cfid->time being zero.
+	 */
+	cfid->has_lease = true;
+
 	rc = compound_send_recv(xid, ses, server,
 				flags, 2, rqst,
 				resp_buftype, rsp_iov);
@@ -263,6 +282,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	cfid->tcon = tcon;
 	cfid->is_open = true;
 
+	spin_lock(&cfids->cfid_list_lock);
+
 	o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
 	oparms.fid->persistent_fid = o_rsp->PersistentFileId;
 	oparms.fid->volatile_fid = o_rsp->VolatileFileId;
@@ -270,18 +291,25 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 	oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
 #endif /* CIFS_DEBUG2 */
 
-	if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
+	rc = -EINVAL;
+	if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
+		spin_unlock(&cfids->cfid_list_lock);
 		goto oshr_free;
+	}
 
 	smb2_parse_contexts(server, o_rsp,
 			    &oparms.fid->epoch,
 			    oparms.fid->lease_key, &oplock,
 			    NULL, NULL);
-	if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
+	if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) {
+		spin_unlock(&cfids->cfid_list_lock);
 		goto oshr_free;
+	}
 	qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
-	if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
+	if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) {
+		spin_unlock(&cfids->cfid_list_lock);
 		goto oshr_free;
+	}
 	if (!smb2_validate_and_copy_iov(
 				le16_to_cpu(qi_rsp->OutputBufferOffset),
 				sizeof(struct smb2_file_all_info),
@@ -289,37 +317,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 				(char *)&cfid->file_all_info))
 		cfid->file_all_info_is_valid = true;
 
-	if (!npath[0])
-		dentry = dget(cifs_sb->root);
-	else {
-		dentry = path_to_dentry(cifs_sb, npath);
-		if (IS_ERR(dentry)) {
-			rc = -ENOENT;
-			goto oshr_free;
-		}
-	}
-	spin_lock(&cfids->cfid_list_lock);
-	cfid->dentry = dentry;
 	cfid->time = jiffies;
-	cfid->has_lease = true;
 	spin_unlock(&cfids->cfid_list_lock);
+	/* At this point the directory handle is fully cached */
+	rc = 0;
 
 oshr_free:
-	kfree(utf16_path);
 	SMB2_open_free(&rqst[0]);
 	SMB2_query_info_free(&rqst[1]);
 	free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
 	free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
-	spin_lock(&cfids->cfid_list_lock);
-	if (!cfid->has_lease) {
-		if (rc) {
-			if (cfid->on_list) {
-				list_del(&cfid->entry);
-				cfid->on_list = false;
-				cfids->num_entries--;
-			}
-			rc = -ENOENT;
-		} else {
+	if (rc) {
+		spin_lock(&cfids->cfid_list_lock);
+		if (cfid->on_list) {
+			list_del(&cfid->entry);
+			cfid->on_list = false;
+			cfids->num_entries--;
+		}
+		if (cfid->has_lease) {
 			/*
 			 * We are guaranteed to have two references at this
 			 * point. One for the caller and one for a potential
@@ -327,25 +342,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
 			 * will be closed when the caller closes the cached
 			 * handle.
 			 */
+			cfid->has_lease = false;
 			spin_unlock(&cfids->cfid_list_lock);
 			kref_put(&cfid->refcount, smb2_close_cached_fid);
 			goto out;
 		}
+		spin_unlock(&cfids->cfid_list_lock);
 	}
-	spin_unlock(&cfids->cfid_list_lock);
+out:
 	if (rc) {
 		if (cfid->is_open)
 			SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
 				   cfid->fid.volatile_fid);
 		free_cached_dir(cfid);
-		cfid = NULL;
-	}
-out:
-	if (rc == 0) {
+	} else {
 		*ret_cfid = cfid;
 		atomic_inc(&tcon->num_remote_opens);
 	}
-
+	kfree(utf16_path);
 	return rc;
 }
 
-- 
2.42.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound()
  2023-10-30 20:19 ` [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound() Paulo Alcantara
@ 2023-10-31  3:09   ` Steve French
  2023-11-04 12:23     ` Shyam Prasad N
  0 siblings, 1 reply; 11+ messages in thread
From: Steve French @ 2023-10-31  3:09 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: linux-cifs

added Cc: stable and tentatively merged this to for-next

On Mon, Oct 30, 2023 at 3:20 PM Paulo Alcantara <pc@manguebit.com> wrote:
>
> The following UAF was triggered when running fstests generic/072 with
> KASAN enabled against Windows Server 2022 and mount options
> 'multichannel,max_channels=2,vers=3.1.1,mfsymlinks,noperm'
>
>   BUG: KASAN: slab-use-after-free in smb2_query_info_compound+0x423/0x6d0 [cifs]
>   Read of size 8 at addr ffff888014941048 by task xfs_io/27534
>
>   CPU: 0 PID: 27534 Comm: xfs_io Not tainted 6.6.0-rc7 #1
>   Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
>   rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
>   Call Trace:
>    dump_stack_lvl+0x4a/0x80
>    print_report+0xcf/0x650
>    ? srso_alias_return_thunk+0x5/0x7f
>    ? srso_alias_return_thunk+0x5/0x7f
>    ? __phys_addr+0x46/0x90
>    kasan_report+0xda/0x110
>    ? smb2_query_info_compound+0x423/0x6d0 [cifs]
>    ? smb2_query_info_compound+0x423/0x6d0 [cifs]
>    smb2_query_info_compound+0x423/0x6d0 [cifs]
>    ? __pfx_smb2_query_info_compound+0x10/0x10 [cifs]
>    ? srso_alias_return_thunk+0x5/0x7f
>    ? __stack_depot_save+0x39/0x480
>    ? kasan_save_stack+0x33/0x60
>    ? kasan_set_track+0x25/0x30
>    ? ____kasan_slab_free+0x126/0x170
>    smb2_queryfs+0xc2/0x2c0 [cifs]
>    ? __pfx_smb2_queryfs+0x10/0x10 [cifs]
>    ? __pfx___lock_acquire+0x10/0x10
>    smb311_queryfs+0x210/0x220 [cifs]
>    ? __pfx_smb311_queryfs+0x10/0x10 [cifs]
>    ? srso_alias_return_thunk+0x5/0x7f
>    ? __lock_acquire+0x480/0x26c0
>    ? lock_release+0x1ed/0x640
>    ? srso_alias_return_thunk+0x5/0x7f
>    ? do_raw_spin_unlock+0x9b/0x100
>    cifs_statfs+0x18c/0x4b0 [cifs]
>    statfs_by_dentry+0x9b/0xf0
>    fd_statfs+0x4e/0xb0
>    __do_sys_fstatfs+0x7f/0xe0
>    ? __pfx___do_sys_fstatfs+0x10/0x10
>    ? srso_alias_return_thunk+0x5/0x7f
>    ? lockdep_hardirqs_on_prepare+0x136/0x200
>    ? srso_alias_return_thunk+0x5/0x7f
>    do_syscall_64+0x3f/0x90
>    entry_SYSCALL_64_after_hwframe+0x6e/0xd8
>
>   Allocated by task 27534:
>    kasan_save_stack+0x33/0x60
>    kasan_set_track+0x25/0x30
>    __kasan_kmalloc+0x8f/0xa0
>    open_cached_dir+0x71b/0x1240 [cifs]
>    smb2_query_info_compound+0x5c3/0x6d0 [cifs]
>    smb2_queryfs+0xc2/0x2c0 [cifs]
>    smb311_queryfs+0x210/0x220 [cifs]
>    cifs_statfs+0x18c/0x4b0 [cifs]
>    statfs_by_dentry+0x9b/0xf0
>    fd_statfs+0x4e/0xb0
>    __do_sys_fstatfs+0x7f/0xe0
>    do_syscall_64+0x3f/0x90
>    entry_SYSCALL_64_after_hwframe+0x6e/0xd8
>
>   Freed by task 27534:
>    kasan_save_stack+0x33/0x60
>    kasan_set_track+0x25/0x30
>    kasan_save_free_info+0x2b/0x50
>    ____kasan_slab_free+0x126/0x170
>    slab_free_freelist_hook+0xd0/0x1e0
>    __kmem_cache_free+0x9d/0x1b0
>    open_cached_dir+0xff5/0x1240 [cifs]
>    smb2_query_info_compound+0x5c3/0x6d0 [cifs]
>    smb2_queryfs+0xc2/0x2c0 [cifs]
>
> This is a race between open_cached_dir() and cached_dir_lease_break()
> where the cache entry for the open directory handle receives a lease
> break while creating it.  And before returning from open_cached_dir(),
> we put the last reference of the new @cfid because of
> !@cfid->has_lease.
>
> Besides the UAF, while running xfstests a lot of missed lease breaks
> have been noticed in tests that run several concurrent statfs(2) calls
> on those cached fids
>
>   CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
>   CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
>   CIFS: VFS: \\w22-root1.gandalf.test smb buf 00000000715bfe83 len 108
>   CIFS: VFS: Dump pending requests:
>   CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
>   CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
>   CIFS: VFS: \\w22-root1.gandalf.test smb buf 000000005aa7316e len 108
>   ...
>
> To fix both, in open_cached_dir() ensure that @cfid->has_lease is set
> right before sending out compounded request so that any potential
> lease break will be get processed by demultiplex thread while we're
> still caching @cfid.  And, if open failed for some reason, re-check
> @cfid->has_lease to decide whether or not put lease reference.
>
> Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> ---
>  fs/smb/client/cached_dir.c | 84 ++++++++++++++++++++++----------------
>  1 file changed, 49 insertions(+), 35 deletions(-)
>
> diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
> index fe1bf5b6e0cb..59f6b8e32cc9 100644
> --- a/fs/smb/client/cached_dir.c
> +++ b/fs/smb/client/cached_dir.c
> @@ -32,7 +32,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
>                          * fully cached or it may be in the process of
>                          * being deleted due to a lease break.
>                          */
> -                       if (!cfid->has_lease) {
> +                       if (!cfid->time || !cfid->has_lease) {
>                                 spin_unlock(&cfids->cfid_list_lock);
>                                 return NULL;
>                         }
> @@ -193,10 +193,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>         npath = path_no_prefix(cifs_sb, path);
>         if (IS_ERR(npath)) {
>                 rc = PTR_ERR(npath);
> -               kfree(utf16_path);
> -               return rc;
> +               goto out;
>         }
>
> +       if (!npath[0]) {
> +               dentry = dget(cifs_sb->root);
> +       } else {
> +               dentry = path_to_dentry(cifs_sb, npath);
> +               if (IS_ERR(dentry)) {
> +                       rc = -ENOENT;
> +                       goto out;
> +               }
> +       }
> +       cfid->dentry = dentry;
> +
>         /*
>          * We do not hold the lock for the open because in case
>          * SMB2_open needs to reconnect.
> @@ -249,6 +259,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>
>         smb2_set_related(&rqst[1]);
>
> +       /*
> +        * Set @cfid->has_lease to true before sending out compounded request so
> +        * its lease reference can be put in cached_dir_lease_break() due to a
> +        * potential lease break right after the request is sent or while @cfid
> +        * is still being cached.  Concurrent processes won't be to use it yet
> +        * due to @cfid->time being zero.
> +        */
> +       cfid->has_lease = true;
> +
>         rc = compound_send_recv(xid, ses, server,
>                                 flags, 2, rqst,
>                                 resp_buftype, rsp_iov);
> @@ -263,6 +282,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>         cfid->tcon = tcon;
>         cfid->is_open = true;
>
> +       spin_lock(&cfids->cfid_list_lock);
> +
>         o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
>         oparms.fid->persistent_fid = o_rsp->PersistentFileId;
>         oparms.fid->volatile_fid = o_rsp->VolatileFileId;
> @@ -270,18 +291,25 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>         oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
>  #endif /* CIFS_DEBUG2 */
>
> -       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
> +       rc = -EINVAL;
> +       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
> +               spin_unlock(&cfids->cfid_list_lock);
>                 goto oshr_free;
> +       }
>
>         smb2_parse_contexts(server, o_rsp,
>                             &oparms.fid->epoch,
>                             oparms.fid->lease_key, &oplock,
>                             NULL, NULL);
> -       if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
> +       if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) {
> +               spin_unlock(&cfids->cfid_list_lock);
>                 goto oshr_free;
> +       }
>         qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
> -       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
> +       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) {
> +               spin_unlock(&cfids->cfid_list_lock);
>                 goto oshr_free;
> +       }
>         if (!smb2_validate_and_copy_iov(
>                                 le16_to_cpu(qi_rsp->OutputBufferOffset),
>                                 sizeof(struct smb2_file_all_info),
> @@ -289,37 +317,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>                                 (char *)&cfid->file_all_info))
>                 cfid->file_all_info_is_valid = true;
>
> -       if (!npath[0])
> -               dentry = dget(cifs_sb->root);
> -       else {
> -               dentry = path_to_dentry(cifs_sb, npath);
> -               if (IS_ERR(dentry)) {
> -                       rc = -ENOENT;
> -                       goto oshr_free;
> -               }
> -       }
> -       spin_lock(&cfids->cfid_list_lock);
> -       cfid->dentry = dentry;
>         cfid->time = jiffies;
> -       cfid->has_lease = true;
>         spin_unlock(&cfids->cfid_list_lock);
> +       /* At this point the directory handle is fully cached */
> +       rc = 0;
>
>  oshr_free:
> -       kfree(utf16_path);
>         SMB2_open_free(&rqst[0]);
>         SMB2_query_info_free(&rqst[1]);
>         free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
>         free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
> -       spin_lock(&cfids->cfid_list_lock);
> -       if (!cfid->has_lease) {
> -               if (rc) {
> -                       if (cfid->on_list) {
> -                               list_del(&cfid->entry);
> -                               cfid->on_list = false;
> -                               cfids->num_entries--;
> -                       }
> -                       rc = -ENOENT;
> -               } else {
> +       if (rc) {
> +               spin_lock(&cfids->cfid_list_lock);
> +               if (cfid->on_list) {
> +                       list_del(&cfid->entry);
> +                       cfid->on_list = false;
> +                       cfids->num_entries--;
> +               }
> +               if (cfid->has_lease) {
>                         /*
>                          * We are guaranteed to have two references at this
>                          * point. One for the caller and one for a potential
> @@ -327,25 +342,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
>                          * will be closed when the caller closes the cached
>                          * handle.
>                          */
> +                       cfid->has_lease = false;
>                         spin_unlock(&cfids->cfid_list_lock);
>                         kref_put(&cfid->refcount, smb2_close_cached_fid);
>                         goto out;
>                 }
> +               spin_unlock(&cfids->cfid_list_lock);
>         }
> -       spin_unlock(&cfids->cfid_list_lock);
> +out:
>         if (rc) {
>                 if (cfid->is_open)
>                         SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
>                                    cfid->fid.volatile_fid);
>                 free_cached_dir(cfid);
> -               cfid = NULL;
> -       }
> -out:
> -       if (rc == 0) {
> +       } else {
>                 *ret_cfid = cfid;
>                 atomic_inc(&tcon->num_remote_opens);
>         }
> -
> +       kfree(utf16_path);
>         return rc;
>  }
>
> --
> 2.42.0
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show()
  2023-10-30 20:19 ` [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show() Paulo Alcantara
@ 2023-10-31  3:17   ` Steve French
  2024-06-01 11:50   ` Wang Zhaolong
  1 sibling, 0 replies; 11+ messages in thread
From: Steve French @ 2023-10-31  3:17 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: linux-cifs, Frank Sorenson

fix was already in cifs-2.6.git for-next

Added Cc: stable to it though

Let me know if you see something missing (or if patch changed from the
previous one eg)

On Mon, Oct 30, 2023 at 3:20 PM Paulo Alcantara <pc@manguebit.com> wrote:
>
> Skip SMB sessions that are being teared down
> (e.g. @ses->ses_status == SES_EXITING) in cifs_debug_data_proc_show()
> to avoid use-after-free in @ses.
>
> This fixes the following GPF when reading from /proc/fs/cifs/DebugData
> while mounting and umounting
>
>   [ 816.251274] general protection fault, probably for non-canonical
>   address 0x6b6b6b6b6b6b6d81: 0000 [#1] PREEMPT SMP NOPTI
>   ...
>   [  816.260138] Call Trace:
>   [  816.260329]  <TASK>
>   [  816.260499]  ? die_addr+0x36/0x90
>   [  816.260762]  ? exc_general_protection+0x1b3/0x410
>   [  816.261126]  ? asm_exc_general_protection+0x26/0x30
>   [  816.261502]  ? cifs_debug_tcon+0xbd/0x240 [cifs]
>   [  816.261878]  ? cifs_debug_tcon+0xab/0x240 [cifs]
>   [  816.262249]  cifs_debug_data_proc_show+0x516/0xdb0 [cifs]
>   [  816.262689]  ? seq_read_iter+0x379/0x470
>   [  816.262995]  seq_read_iter+0x118/0x470
>   [  816.263291]  proc_reg_read_iter+0x53/0x90
>   [  816.263596]  ? srso_alias_return_thunk+0x5/0x7f
>   [  816.263945]  vfs_read+0x201/0x350
>   [  816.264211]  ksys_read+0x75/0x100
>   [  816.264472]  do_syscall_64+0x3f/0x90
>   [  816.264750]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
>   [  816.265135] RIP: 0033:0x7fd5e669d381
>
> Cc: Frank Sorenson <sorenson@redhat.com>
> Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> ---
>  fs/smb/client/cifs_debug.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
> index 76922fcc4bc6..9a0ccd87468e 100644
> --- a/fs/smb/client/cifs_debug.c
> +++ b/fs/smb/client/cifs_debug.c
> @@ -452,6 +452,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
>                 seq_printf(m, "\n\n\tSessions: ");
>                 i = 0;
>                 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
> +                       spin_lock(&ses->ses_lock);
> +                       if (ses->ses_status == SES_EXITING) {
> +                               spin_unlock(&ses->ses_lock);
> +                               continue;
> +                       }
>                         i++;
>                         if ((ses->serverDomain == NULL) ||
>                                 (ses->serverOS == NULL) ||
> @@ -472,6 +477,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
>                                 ses->ses_count, ses->serverOS, ses->serverNOS,
>                                 ses->capabilities, ses->ses_status);
>                         }
> +                       spin_unlock(&ses->ses_lock);
>
>                         seq_printf(m, "\n\tSecurity type: %s ",
>                                 get_security_type_str(server->ops->select_sectype(server, ses->sectype)));
> --
> 2.42.0
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/4] smb: client: fix potential deadlock when releasing mids
  2023-10-30 20:19 ` [PATCH 3/4] smb: client: fix potential deadlock when releasing mids Paulo Alcantara
@ 2023-10-31  3:23   ` Steve French
  0 siblings, 0 replies; 11+ messages in thread
From: Steve French @ 2023-10-31  3:23 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: linux-cifs, Frank Sorenson

fix was already in cifs-2.6.git for-next, but added Cc: stable

Let me know if I missed anything

On Mon, Oct 30, 2023 at 3:20 PM Paulo Alcantara <pc@manguebit.com> wrote:
>
> All release_mid() callers seem to hold a reference of @mid so there is
> no need to call kref_put(&mid->refcount, __release_mid) under
> @server->mid_lock spinlock.  If they don't, then an use-after-free bug
> would have occurred anyway.
>
> By getting rid of such spinlock also fixes a potential deadlock as
> shown below
>
> CPU 0                                CPU 1
> ------------------------------------------------------------------
> cifs_demultiplex_thread()            cifs_debug_data_proc_show()
>  release_mid()
>   spin_lock(&server->mid_lock);
>                                      spin_lock(&cifs_tcp_ses_lock)
>                                       spin_lock(&server->mid_lock)
>   __release_mid()
>    smb2_find_smb_tcon()
>     spin_lock(&cifs_tcp_ses_lock) *deadlock*
>
> Cc: Frank Sorenson <sorenson@redhat.com>
> Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> ---
>  fs/smb/client/cifsproto.h |  7 ++++++-
>  fs/smb/client/smb2misc.c  |  2 +-
>  fs/smb/client/transport.c | 11 +----------
>  3 files changed, 8 insertions(+), 12 deletions(-)
>
> diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
> index 0c37eefa18a5..890ceddae07e 100644
> --- a/fs/smb/client/cifsproto.h
> +++ b/fs/smb/client/cifsproto.h
> @@ -81,7 +81,7 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
>  extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
>  char *cifs_build_devname(char *nodename, const char *prepath);
>  extern void delete_mid(struct mid_q_entry *mid);
> -extern void release_mid(struct mid_q_entry *mid);
> +void __release_mid(struct kref *refcount);
>  extern void cifs_wake_up_task(struct mid_q_entry *mid);
>  extern int cifs_handle_standard(struct TCP_Server_Info *server,
>                                 struct mid_q_entry *mid);
> @@ -740,4 +740,9 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
>         return true;
>  }
>
> +static inline void release_mid(struct mid_q_entry *mid)
> +{
> +       kref_put(&mid->refcount, __release_mid);
> +}
> +
>  #endif                 /* _CIFSPROTO_H */
> diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
> index 25f7cd6f23d6..32dfa0f7a78c 100644
> --- a/fs/smb/client/smb2misc.c
> +++ b/fs/smb/client/smb2misc.c
> @@ -787,7 +787,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
>  {
>         struct close_cancelled_open *cancelled;
>
> -       cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
> +       cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
>         if (!cancelled)
>                 return -ENOMEM;
>
> diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
> index 14710afdc2a3..d553b7a54621 100644
> --- a/fs/smb/client/transport.c
> +++ b/fs/smb/client/transport.c
> @@ -76,7 +76,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
>         return temp;
>  }
>
> -static void __release_mid(struct kref *refcount)
> +void __release_mid(struct kref *refcount)
>  {
>         struct mid_q_entry *midEntry =
>                         container_of(refcount, struct mid_q_entry, refcount);
> @@ -156,15 +156,6 @@ static void __release_mid(struct kref *refcount)
>         mempool_free(midEntry, cifs_mid_poolp);
>  }
>
> -void release_mid(struct mid_q_entry *mid)
> -{
> -       struct TCP_Server_Info *server = mid->server;
> -
> -       spin_lock(&server->mid_lock);
> -       kref_put(&mid->refcount, __release_mid);
> -       spin_unlock(&server->mid_lock);
> -}
> -
>  void
>  delete_mid(struct mid_q_entry *mid)
>  {
> --
> 2.42.0
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses()
  2023-10-30 20:19 [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Paulo Alcantara
                   ` (2 preceding siblings ...)
  2023-10-30 20:19 ` [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound() Paulo Alcantara
@ 2023-10-31  3:24 ` Steve French
  2023-11-02 12:30   ` Shyam Prasad N
  3 siblings, 1 reply; 11+ messages in thread
From: Steve French @ 2023-10-31  3:24 UTC (permalink / raw)
  To: Paulo Alcantara; +Cc: linux-cifs

tentatively merged into cifs-2.6.git for-next pending review/testing

On Mon, Oct 30, 2023 at 3:20 PM Paulo Alcantara <pc@manguebit.com> wrote:
>
> If @ses->chan_count <= 1, then for-loop body will not be executed so
> no need to check it twice.
>
> Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> ---
>  fs/smb/client/connect.c | 23 +++++++++--------------
>  1 file changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
> index 7b923e36501b..a017ee552256 100644
> --- a/fs/smb/client/connect.c
> +++ b/fs/smb/client/connect.c
> @@ -1969,9 +1969,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
>
>  void __cifs_put_smb_ses(struct cifs_ses *ses)
>  {
> -       unsigned int rc, xid;
> -       unsigned int chan_count;
>         struct TCP_Server_Info *server = ses->server;
> +       unsigned int xid;
> +       size_t i;
> +       int rc;
>
>         spin_lock(&ses->ses_lock);
>         if (ses->ses_status == SES_EXITING) {
> @@ -2017,20 +2018,14 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
>         list_del_init(&ses->smb_ses_list);
>         spin_unlock(&cifs_tcp_ses_lock);
>
> -       chan_count = ses->chan_count;
> -
>         /* close any extra channels */
> -       if (chan_count > 1) {
> -               int i;
> -
> -               for (i = 1; i < chan_count; i++) {
> -                       if (ses->chans[i].iface) {
> -                               kref_put(&ses->chans[i].iface->refcount, release_iface);
> -                               ses->chans[i].iface = NULL;
> -                       }
> -                       cifs_put_tcp_session(ses->chans[i].server, 0);
> -                       ses->chans[i].server = NULL;
> +       for (i = 1; i < ses->chan_count; i++) {
> +               if (ses->chans[i].iface) {
> +                       kref_put(&ses->chans[i].iface->refcount, release_iface);
> +                       ses->chans[i].iface = NULL;
>                 }
> +               cifs_put_tcp_session(ses->chans[i].server, 0);
> +               ses->chans[i].server = NULL;
>         }
>
>         sesInfoFree(ses);
> --
> 2.42.0
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses()
  2023-10-31  3:24 ` [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Steve French
@ 2023-11-02 12:30   ` Shyam Prasad N
  0 siblings, 0 replies; 11+ messages in thread
From: Shyam Prasad N @ 2023-11-02 12:30 UTC (permalink / raw)
  To: Steve French; +Cc: Paulo Alcantara, linux-cifs

On Tue, Oct 31, 2023 at 8:54 AM Steve French <smfrench@gmail.com> wrote:
>
> tentatively merged into cifs-2.6.git for-next pending review/testing
>
> On Mon, Oct 30, 2023 at 3:20 PM Paulo Alcantara <pc@manguebit.com> wrote:
> >
> > If @ses->chan_count <= 1, then for-loop body will not be executed so
> > no need to check it twice.
> >
> > Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> > ---
> >  fs/smb/client/connect.c | 23 +++++++++--------------
> >  1 file changed, 9 insertions(+), 14 deletions(-)
> >
> > diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
> > index 7b923e36501b..a017ee552256 100644
> > --- a/fs/smb/client/connect.c
> > +++ b/fs/smb/client/connect.c
> > @@ -1969,9 +1969,10 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
> >
> >  void __cifs_put_smb_ses(struct cifs_ses *ses)
> >  {
> > -       unsigned int rc, xid;
> > -       unsigned int chan_count;
> >         struct TCP_Server_Info *server = ses->server;
> > +       unsigned int xid;
> > +       size_t i;
> > +       int rc;
> >
> >         spin_lock(&ses->ses_lock);
> >         if (ses->ses_status == SES_EXITING) {
> > @@ -2017,20 +2018,14 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
> >         list_del_init(&ses->smb_ses_list);
> >         spin_unlock(&cifs_tcp_ses_lock);
> >
> > -       chan_count = ses->chan_count;
> > -
> >         /* close any extra channels */
> > -       if (chan_count > 1) {
> > -               int i;
> > -
> > -               for (i = 1; i < chan_count; i++) {
> > -                       if (ses->chans[i].iface) {
> > -                               kref_put(&ses->chans[i].iface->refcount, release_iface);
> > -                               ses->chans[i].iface = NULL;
> > -                       }
> > -                       cifs_put_tcp_session(ses->chans[i].server, 0);
> > -                       ses->chans[i].server = NULL;
> > +       for (i = 1; i < ses->chan_count; i++) {
> > +               if (ses->chans[i].iface) {
> > +                       kref_put(&ses->chans[i].iface->refcount, release_iface);
> > +                       ses->chans[i].iface = NULL;
> >                 }
> > +               cifs_put_tcp_session(ses->chans[i].server, 0);
> > +               ses->chans[i].server = NULL;
> >         }
> >
> >         sesInfoFree(ses);
> > --
> > 2.42.0
> >
>
>
> --
> Thanks,
>
> Steve

Looks good to me.
You can add my RB.

-- 
Regards,
Shyam

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound()
  2023-10-31  3:09   ` Steve French
@ 2023-11-04 12:23     ` Shyam Prasad N
  0 siblings, 0 replies; 11+ messages in thread
From: Shyam Prasad N @ 2023-11-04 12:23 UTC (permalink / raw)
  To: Steve French; +Cc: Paulo Alcantara, linux-cifs

On Tue, Oct 31, 2023 at 8:39 AM Steve French <smfrench@gmail.com> wrote:
>
> added Cc: stable and tentatively merged this to for-next
>
> On Mon, Oct 30, 2023 at 3:20 PM Paulo Alcantara <pc@manguebit.com> wrote:
> >
> > The following UAF was triggered when running fstests generic/072 with
> > KASAN enabled against Windows Server 2022 and mount options
> > 'multichannel,max_channels=2,vers=3.1.1,mfsymlinks,noperm'
> >
> >   BUG: KASAN: slab-use-after-free in smb2_query_info_compound+0x423/0x6d0 [cifs]
> >   Read of size 8 at addr ffff888014941048 by task xfs_io/27534
> >
> >   CPU: 0 PID: 27534 Comm: xfs_io Not tainted 6.6.0-rc7 #1
> >   Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
> >   rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
> >   Call Trace:
> >    dump_stack_lvl+0x4a/0x80
> >    print_report+0xcf/0x650
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    ? __phys_addr+0x46/0x90
> >    kasan_report+0xda/0x110
> >    ? smb2_query_info_compound+0x423/0x6d0 [cifs]
> >    ? smb2_query_info_compound+0x423/0x6d0 [cifs]
> >    smb2_query_info_compound+0x423/0x6d0 [cifs]
> >    ? __pfx_smb2_query_info_compound+0x10/0x10 [cifs]
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    ? __stack_depot_save+0x39/0x480
> >    ? kasan_save_stack+0x33/0x60
> >    ? kasan_set_track+0x25/0x30
> >    ? ____kasan_slab_free+0x126/0x170
> >    smb2_queryfs+0xc2/0x2c0 [cifs]
> >    ? __pfx_smb2_queryfs+0x10/0x10 [cifs]
> >    ? __pfx___lock_acquire+0x10/0x10
> >    smb311_queryfs+0x210/0x220 [cifs]
> >    ? __pfx_smb311_queryfs+0x10/0x10 [cifs]
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    ? __lock_acquire+0x480/0x26c0
> >    ? lock_release+0x1ed/0x640
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    ? do_raw_spin_unlock+0x9b/0x100
> >    cifs_statfs+0x18c/0x4b0 [cifs]
> >    statfs_by_dentry+0x9b/0xf0
> >    fd_statfs+0x4e/0xb0
> >    __do_sys_fstatfs+0x7f/0xe0
> >    ? __pfx___do_sys_fstatfs+0x10/0x10
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    ? lockdep_hardirqs_on_prepare+0x136/0x200
> >    ? srso_alias_return_thunk+0x5/0x7f
> >    do_syscall_64+0x3f/0x90
> >    entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> >
> >   Allocated by task 27534:
> >    kasan_save_stack+0x33/0x60
> >    kasan_set_track+0x25/0x30
> >    __kasan_kmalloc+0x8f/0xa0
> >    open_cached_dir+0x71b/0x1240 [cifs]
> >    smb2_query_info_compound+0x5c3/0x6d0 [cifs]
> >    smb2_queryfs+0xc2/0x2c0 [cifs]
> >    smb311_queryfs+0x210/0x220 [cifs]
> >    cifs_statfs+0x18c/0x4b0 [cifs]
> >    statfs_by_dentry+0x9b/0xf0
> >    fd_statfs+0x4e/0xb0
> >    __do_sys_fstatfs+0x7f/0xe0
> >    do_syscall_64+0x3f/0x90
> >    entry_SYSCALL_64_after_hwframe+0x6e/0xd8
> >
> >   Freed by task 27534:
> >    kasan_save_stack+0x33/0x60
> >    kasan_set_track+0x25/0x30
> >    kasan_save_free_info+0x2b/0x50
> >    ____kasan_slab_free+0x126/0x170
> >    slab_free_freelist_hook+0xd0/0x1e0
> >    __kmem_cache_free+0x9d/0x1b0
> >    open_cached_dir+0xff5/0x1240 [cifs]
> >    smb2_query_info_compound+0x5c3/0x6d0 [cifs]
> >    smb2_queryfs+0xc2/0x2c0 [cifs]
> >
> > This is a race between open_cached_dir() and cached_dir_lease_break()
> > where the cache entry for the open directory handle receives a lease
> > break while creating it.  And before returning from open_cached_dir(),
> > we put the last reference of the new @cfid because of
> > !@cfid->has_lease.
> >
> > Besides the UAF, while running xfstests a lot of missed lease breaks
> > have been noticed in tests that run several concurrent statfs(2) calls
> > on those cached fids
> >
> >   CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
> >   CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
> >   CIFS: VFS: \\w22-root1.gandalf.test smb buf 00000000715bfe83 len 108
> >   CIFS: VFS: Dump pending requests:
> >   CIFS: VFS: \\w22-root1.gandalf.test No task to wake, unknown frame...
> >   CIFS: VFS: \\w22-root1.gandalf.test Cmd: 18 Err: 0x0 Flags: 0x1...
> >   CIFS: VFS: \\w22-root1.gandalf.test smb buf 000000005aa7316e len 108
> >   ...
> >
> > To fix both, in open_cached_dir() ensure that @cfid->has_lease is set
> > right before sending out compounded request so that any potential
> > lease break will be get processed by demultiplex thread while we're
> > still caching @cfid.  And, if open failed for some reason, re-check
> > @cfid->has_lease to decide whether or not put lease reference.
> >
> > Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
> > ---
> >  fs/smb/client/cached_dir.c | 84 ++++++++++++++++++++++----------------
> >  1 file changed, 49 insertions(+), 35 deletions(-)
> >
> > diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c
> > index fe1bf5b6e0cb..59f6b8e32cc9 100644
> > --- a/fs/smb/client/cached_dir.c
> > +++ b/fs/smb/client/cached_dir.c
> > @@ -32,7 +32,7 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
> >                          * fully cached or it may be in the process of
> >                          * being deleted due to a lease break.
> >                          */
> > -                       if (!cfid->has_lease) {
> > +                       if (!cfid->time || !cfid->has_lease) {
> >                                 spin_unlock(&cfids->cfid_list_lock);
> >                                 return NULL;
> >                         }
> > @@ -193,10 +193,20 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> >         npath = path_no_prefix(cifs_sb, path);
> >         if (IS_ERR(npath)) {
> >                 rc = PTR_ERR(npath);
> > -               kfree(utf16_path);
> > -               return rc;
> > +               goto out;
> >         }
> >
> > +       if (!npath[0]) {
> > +               dentry = dget(cifs_sb->root);
> > +       } else {
> > +               dentry = path_to_dentry(cifs_sb, npath);
> > +               if (IS_ERR(dentry)) {
> > +                       rc = -ENOENT;
> > +                       goto out;
> > +               }
> > +       }
> > +       cfid->dentry = dentry;
> > +
> >         /*
> >          * We do not hold the lock for the open because in case
> >          * SMB2_open needs to reconnect.
> > @@ -249,6 +259,15 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> >
> >         smb2_set_related(&rqst[1]);
> >
> > +       /*
> > +        * Set @cfid->has_lease to true before sending out compounded request so
> > +        * its lease reference can be put in cached_dir_lease_break() due to a
> > +        * potential lease break right after the request is sent or while @cfid
> > +        * is still being cached.  Concurrent processes won't be to use it yet
> > +        * due to @cfid->time being zero.
> > +        */
> > +       cfid->has_lease = true;
> > +
> >         rc = compound_send_recv(xid, ses, server,
> >                                 flags, 2, rqst,
> >                                 resp_buftype, rsp_iov);
> > @@ -263,6 +282,8 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> >         cfid->tcon = tcon;
> >         cfid->is_open = true;
> >
> > +       spin_lock(&cfids->cfid_list_lock);
> > +
> >         o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
> >         oparms.fid->persistent_fid = o_rsp->PersistentFileId;
> >         oparms.fid->volatile_fid = o_rsp->VolatileFileId;
> > @@ -270,18 +291,25 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> >         oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
> >  #endif /* CIFS_DEBUG2 */
> >
> > -       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
> > +       rc = -EINVAL;
> > +       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
> > +               spin_unlock(&cfids->cfid_list_lock);
> >                 goto oshr_free;
> > +       }
> >
> >         smb2_parse_contexts(server, o_rsp,
> >                             &oparms.fid->epoch,
> >                             oparms.fid->lease_key, &oplock,
> >                             NULL, NULL);
> > -       if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
> > +       if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) {
> > +               spin_unlock(&cfids->cfid_list_lock);
> >                 goto oshr_free;
> > +       }
> >         qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
> > -       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
> > +       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) {
> > +               spin_unlock(&cfids->cfid_list_lock);
> >                 goto oshr_free;
> > +       }
> >         if (!smb2_validate_and_copy_iov(
> >                                 le16_to_cpu(qi_rsp->OutputBufferOffset),
> >                                 sizeof(struct smb2_file_all_info),
> > @@ -289,37 +317,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> >                                 (char *)&cfid->file_all_info))
> >                 cfid->file_all_info_is_valid = true;
> >
> > -       if (!npath[0])
> > -               dentry = dget(cifs_sb->root);
> > -       else {
> > -               dentry = path_to_dentry(cifs_sb, npath);
> > -               if (IS_ERR(dentry)) {
> > -                       rc = -ENOENT;
> > -                       goto oshr_free;
> > -               }
> > -       }
> > -       spin_lock(&cfids->cfid_list_lock);
> > -       cfid->dentry = dentry;
> >         cfid->time = jiffies;
> > -       cfid->has_lease = true;
> >         spin_unlock(&cfids->cfid_list_lock);
> > +       /* At this point the directory handle is fully cached */
> > +       rc = 0;
> >
> >  oshr_free:
> > -       kfree(utf16_path);
> >         SMB2_open_free(&rqst[0]);
> >         SMB2_query_info_free(&rqst[1]);
> >         free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
> >         free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
> > -       spin_lock(&cfids->cfid_list_lock);
> > -       if (!cfid->has_lease) {
> > -               if (rc) {
> > -                       if (cfid->on_list) {
> > -                               list_del(&cfid->entry);
> > -                               cfid->on_list = false;
> > -                               cfids->num_entries--;
> > -                       }
> > -                       rc = -ENOENT;
> > -               } else {
> > +       if (rc) {
> > +               spin_lock(&cfids->cfid_list_lock);
> > +               if (cfid->on_list) {
> > +                       list_del(&cfid->entry);
> > +                       cfid->on_list = false;
> > +                       cfids->num_entries--;
> > +               }
> > +               if (cfid->has_lease) {
> >                         /*
> >                          * We are guaranteed to have two references at this
> >                          * point. One for the caller and one for a potential
> > @@ -327,25 +342,24 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
> >                          * will be closed when the caller closes the cached
> >                          * handle.
> >                          */
> > +                       cfid->has_lease = false;
> >                         spin_unlock(&cfids->cfid_list_lock);
> >                         kref_put(&cfid->refcount, smb2_close_cached_fid);
> >                         goto out;
> >                 }
> > +               spin_unlock(&cfids->cfid_list_lock);
> >         }
> > -       spin_unlock(&cfids->cfid_list_lock);
> > +out:
> >         if (rc) {
> >                 if (cfid->is_open)
> >                         SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
> >                                    cfid->fid.volatile_fid);
> >                 free_cached_dir(cfid);
> > -               cfid = NULL;
> > -       }
> > -out:
> > -       if (rc == 0) {
> > +       } else {
> >                 *ret_cfid = cfid;
> >                 atomic_inc(&tcon->num_remote_opens);
> >         }
> > -
> > +       kfree(utf16_path);
> >         return rc;
> >  }
> >
> > --
> > 2.42.0
> >
>
>
> --
> Thanks,
>
> Steve

Don't know if I'm too late for the review.
If not, you can add my RB.

-- 
Regards,
Shyam

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show()
  2023-10-30 20:19 ` [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show() Paulo Alcantara
  2023-10-31  3:17   ` Steve French
@ 2024-06-01 11:50   ` Wang Zhaolong
  1 sibling, 0 replies; 11+ messages in thread
From: Wang Zhaolong @ 2024-06-01 11:50 UTC (permalink / raw)
  To: Paulo Alcantara, smfrench; +Cc: linux-cifs, Frank Sorenson


Hello,

I encountered some confusion while reviewing the source code related to
CVE-2023-52752.

I was able to reproduce the issue, and the original problem seems to be:

---
process 1                   process 2(read /proc/fs/cifs/DebugData)

cifs_umount
cifs_put_tlink
cifs_put_tcon
cifs_put_smb_ses                cifs_debug_data_proc_show
   spin_unlock(&cifs_tcp_ses_lock)
                                   spin_lock(&cifs_tcp_ses_lock);
                                   list_for_each...(ses,server->smb_ses_list,...)
   cifs_free_ipc
     tconInfoFree(tcon)
                                   if (ses->tcon_ipc)
                                    cifs_debug_tcon(m,ses->tcon_ipc)
                                      // UAF
     ses->tcon_ipc = NULLl
                                   spin_unlock(&cifs_tcp_ses_lock);

   spin_lock(&cifs_tcp_ses_lock)
   list_del_init(&ses->smb_ses_list)
   spin_unlock(&cifs_tcp_ses_lock)
---

In commit ff7d80a9f271 ("cifs: fix session state transition to avoid use-after-free
issue"), setting ses_status to SES_EXITING was moved under the protection of
cifs_tcp_ses_lock.

In cifs_debug_data_proc_show(), the logic that checks ses->ses_status == SES_EXITING
already seems sufficient to avoid this issue. Therefore, it appears that ses->ses_lock
might not be necessary. Additionally, I am curious why ses->ses_lock needs to cover
such a large scope.


> diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
> index 76922fcc4bc6..9a0ccd87468e 100644
> --- a/fs/smb/client/cifs_debug.c
> +++ b/fs/smb/client/cifs_debug.c
> @@ -452,6 +452,11 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
>   		seq_printf(m, "\n\n\tSessions: ");
>   		i = 0;
>   		list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
> +			spin_lock(&ses->ses_lock);
> +			if (ses->ses_status == SES_EXITING) {
> +				spin_unlock(&ses->ses_lock);
> +				continue;
> +			}
>   			i++;
>   			if ((ses->serverDomain == NULL) ||
>   				(ses->serverOS == NULL) ||
> @@ -472,6 +477,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
>   				ses->ses_count, ses->serverOS, ses->serverNOS,
>   				ses->capabilities, ses->ses_status);
>   			}
> +			spin_unlock(&ses->ses_lock);
>   
>   			seq_printf(m, "\n\tSecurity type: %s ",
>   				get_security_type_str(server->ops->select_sectype(server, ses->sectype)));

I believe in the latest mainline, this could potentially be modified to:

```
diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index c71ae5c04306..2d9e83b71643 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -485,11 +485,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
  		seq_printf(m, "\n\n\tSessions: ");
  		i = 0;
  		list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
-			spin_lock(&ses->ses_lock);
-			if (ses->ses_status == SES_EXITING) {
-				spin_unlock(&ses->ses_lock);
+			if (cifs_ses_exiting(ses))
  				continue;
-			}
  			i++;
  			if ((ses->serverDomain == NULL) ||
  				(ses->serverOS == NULL) ||
@@ -512,7 +509,6 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
  			}
  			if (ses->expired_pwd)
  				seq_puts(m, "password no longer valid ");
-			spin_unlock(&ses->ses_lock);
  
  			seq_printf(m, "\n\tSecurity type: %s ",
  				get_security_type_str(server->ops->select_sectype(server, ses->sectype)));

```

Best regards,
Wang Zhaolong

^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-06-01 11:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-30 20:19 [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Paulo Alcantara
2023-10-30 20:19 ` [PATCH 2/4] smb: client: fix use-after-free bug in cifs_debug_data_proc_show() Paulo Alcantara
2023-10-31  3:17   ` Steve French
2024-06-01 11:50   ` Wang Zhaolong
2023-10-30 20:19 ` [PATCH 3/4] smb: client: fix potential deadlock when releasing mids Paulo Alcantara
2023-10-31  3:23   ` Steve French
2023-10-30 20:19 ` [PATCH 4/4] smb: client: fix use-after-free in smb2_query_info_compound() Paulo Alcantara
2023-10-31  3:09   ` Steve French
2023-11-04 12:23     ` Shyam Prasad N
2023-10-31  3:24 ` [PATCH 1/4] smb: client: remove extra @chan_count check in __cifs_put_smb_ses() Steve French
2023-11-02 12:30   ` Shyam Prasad N

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox