cifs: fix panic in smb2_reconnect
diff mbox series

Message ID 20190605001534.28278-1-lsahlber@redhat.com
State New
Headers show
Series
  • cifs: fix panic in smb2_reconnect
Related show

Commit Message

Ronnie Sahlberg June 5, 2019, 12:15 a.m. UTC
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 <aaptel@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/smb2pdu.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

Steve French June 5, 2019, 12:21 a.m. UTC | #1
tentatively merged into cifs-2.6.git for-next (and to the github tree
for next buildbot run)

On Tue, Jun 4, 2019 at 7:15 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> 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 <aaptel@suse.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/smb2pdu.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 565b60b62f4d..ab8dc73d2282 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -3113,9 +3113,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++;
>                 }
>         }
>         /*
> @@ -3134,7 +3139,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");
> --
> 2.13.6
>
Pavel Shilovsky June 11, 2019, 11:52 p.m. UTC | #2
вт, 4 июн. 2019 г. в 17:16, Ronnie Sahlberg <lsahlber@redhat.com>:
>
> 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 <aaptel@suse.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/smb2pdu.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
> index 565b60b62f4d..ab8dc73d2282 100644
> --- a/fs/cifs/smb2pdu.c
> +++ b/fs/cifs/smb2pdu.c
> @@ -3113,9 +3113,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++;
>                 }
>         }
>         /*
> @@ -3134,7 +3139,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");
> --
> 2.13.6
>

Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>

--
Best regards,
Pavel Shilovsky

Patch
diff mbox series

diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 565b60b62f4d..ab8dc73d2282 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -3113,9 +3113,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++;
 		}
 	}
 	/*
@@ -3134,7 +3139,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");