Skip to content

Commit bc593fe

Browse files
Paulo Alcantaravijay-suman
authored andcommitted
smb: client: fix potential deadlock when releasing mids
commit e6322fd upstream. 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]> [cifs_mid_q_entry_release() is renamed to release_mid() and _cifs_mid_q_entry_release() is renamed to __release_mid() by commit 70f08f9 ("cifs: remove useless DeleteMidQEntry()") which is integrated into v6.0, so preserve old names in v5.15.] Signed-off-by: Cliff Liu <[email protected]> Signed-off-by: He Zhe <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit ce49569079a9d4cad26c0f1d4653382fd9a5ca7a) Signed-off-by: Vijayendra Suman <[email protected]>
1 parent 609f79e commit bc593fe

File tree

3 files changed

+8
-10
lines changed

3 files changed

+8
-10
lines changed

fs/cifs/cifsproto.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
8383
struct TCP_Server_Info *server);
8484
extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
8585
extern void cifs_delete_mid(struct mid_q_entry *mid);
86-
extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry);
86+
void _cifs_mid_q_entry_release(struct kref *refcount);
8787
extern void cifs_wake_up_task(struct mid_q_entry *mid);
8888
extern int cifs_handle_standard(struct TCP_Server_Info *server,
8989
struct mid_q_entry *mid);
@@ -637,4 +637,9 @@ static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
637637
struct super_block *cifs_get_tcon_super(struct cifs_tcon *tcon);
638638
void cifs_put_tcon_super(struct super_block *sb);
639639

640+
static inline void cifs_mid_q_entry_release(struct mid_q_entry *midEntry)
641+
{
642+
kref_put(&midEntry->refcount, _cifs_mid_q_entry_release);
643+
}
644+
640645
#endif /* _CIFSPROTO_H */

fs/cifs/smb2misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid,
759759
{
760760
struct close_cancelled_open *cancelled;
761761

762-
cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
762+
cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
763763
if (!cancelled)
764764
return -ENOMEM;
765765

fs/cifs/transport.c

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

78-
static void _cifs_mid_q_entry_release(struct kref *refcount)
78+
void _cifs_mid_q_entry_release(struct kref *refcount)
7979
{
8080
struct mid_q_entry *midEntry =
8181
container_of(refcount, struct mid_q_entry, refcount);
@@ -155,13 +155,6 @@ static void _cifs_mid_q_entry_release(struct kref *refcount)
155155
mempool_free(midEntry, cifs_mid_poolp);
156156
}
157157

158-
void cifs_mid_q_entry_release(struct mid_q_entry *midEntry)
159-
{
160-
spin_lock(&GlobalMid_Lock);
161-
kref_put(&midEntry->refcount, _cifs_mid_q_entry_release);
162-
spin_unlock(&GlobalMid_Lock);
163-
}
164-
165158
void DeleteMidQEntry(struct mid_q_entry *midEntry)
166159
{
167160
cifs_mid_q_entry_release(midEntry);

0 commit comments

Comments
 (0)