Skip to content

Commit e6322fd

Browse files
Paulo AlcantaraSteve French
authored andcommitted
smb: client: fix potential deadlock when releasing mids
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 anyways. 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: [email protected] Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 72bc63f commit e6322fd

File tree

3 files changed

+8
-12
lines changed

3 files changed

+8
-12
lines changed

fs/smb/client/cifsproto.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
8181
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
8282
char *cifs_build_devname(char *nodename, const char *prepath);
8383
extern void delete_mid(struct mid_q_entry *mid);
84-
extern void release_mid(struct mid_q_entry *mid);
84+
void __release_mid(struct kref *refcount);
8585
extern void cifs_wake_up_task(struct mid_q_entry *mid);
8686
extern int cifs_handle_standard(struct TCP_Server_Info *server,
8787
struct mid_q_entry *mid);
@@ -740,4 +740,9 @@ static inline bool dfs_src_pathname_equal(const char *s1, const char *s2)
740740
return true;
741741
}
742742

743+
static inline void release_mid(struct mid_q_entry *mid)
744+
{
745+
kref_put(&mid->refcount, __release_mid);
746+
}
747+
743748
#endif /* _CIFSPROTO_H */

fs/smb/client/smb2misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
787787
{
788788
struct close_cancelled_open *cancelled;
789789

790-
cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
790+
cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
791791
if (!cancelled)
792792
return -ENOMEM;
793793

fs/smb/client/transport.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ alloc_mid(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
7676
return temp;
7777
}
7878

79-
static void __release_mid(struct kref *refcount)
79+
void __release_mid(struct kref *refcount)
8080
{
8181
struct mid_q_entry *midEntry =
8282
container_of(refcount, struct mid_q_entry, refcount);
@@ -156,15 +156,6 @@ static void __release_mid(struct kref *refcount)
156156
mempool_free(midEntry, cifs_mid_poolp);
157157
}
158158

159-
void release_mid(struct mid_q_entry *mid)
160-
{
161-
struct TCP_Server_Info *server = mid->server;
162-
163-
spin_lock(&server->mid_lock);
164-
kref_put(&mid->refcount, __release_mid);
165-
spin_unlock(&server->mid_lock);
166-
}
167-
168159
void
169160
delete_mid(struct mid_q_entry *mid)
170161
{

0 commit comments

Comments
 (0)