From c2be1845f393e46dcda5e34644b9779b7d8762ae Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Fri, 20 Mar 2020 12:21:59 +0800 Subject: [PATCH] cifs: fix panic in smb2_reconnect mainline inclusion from mainline-5.2-rc6 commit 0ff2b018b02f category: bugfix bugzilla: 16811 CVE: NA https://gitee.com/src-openeuler/cifs-utils/issues/I1C1QY?from=project-issue ------------------------------------------------- RH Bugzilla: 1702264 We need to protect so that the call to smb2_reconnect() in smb2_reconnect_server() does not end up freeing the session because it can lead to a use after free and crash. Reviewed-by: Aurelien Aptel Cc: Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French Reviewed-by: Pavel Shilovsky Conflicts: fs/cifs/cifsproto.h fs/cifs/connect.c [yyl: make cifs_put_smb_ses() extern] Reviewed-by: Zhang Xiaoxu Signed-off-by: Yang Yingliang --- fs/cifs/cifsproto.h | 2 ++ fs/cifs/connect.c | 3 +-- fs/cifs/smb2pdu.c | 10 +++++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index d7ac75ea881c..bd97f2abeee8 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -526,6 +526,8 @@ extern int E_md4hash(const unsigned char *passwd, unsigned char *p16, extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); +extern void cifs_put_smb_ses(struct cifs_ses *ses); + void cifs_readdata_release(struct kref *refcount); int cifs_async_readv(struct cifs_readdata *rdata); int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 7e85070d010f..2e46a8a79eb2 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2732,8 +2732,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) return NULL; } -static void -cifs_put_smb_ses(struct cifs_ses *ses) +void cifs_put_smb_ses(struct cifs_ses *ses) { unsigned int rc, xid; struct TCP_Server_Info *server = ses->server; diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 30417d457929..97995b2d63ea 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2914,9 +2914,14 @@ void smb2_reconnect_server(struct work_struct *work) tcon_exist = true; } } + /* + * IPC has the same lifetime as its session and uses its + * refcount. + */ if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) { list_add_tail(&ses->tcon_ipc->rlist, &tmp_list); tcon_exist = true; + ses->ses_count++; } } /* @@ -2935,7 +2940,10 @@ void smb2_reconnect_server(struct work_struct *work) else resched = true; list_del_init(&tcon->rlist); - cifs_put_tcon(tcon); + if (tcon->ipc) + cifs_put_smb_ses(tcon->ses); + else + cifs_put_tcon(tcon); } cifs_dbg(FYI, "Reconnecting tcons finished\n"); -- GitLab