Re: [PATCH 1/2] cifs: during remount, make sure passwords are in sync

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Paulo,

Thanks for the review.

On Fri, Nov 8, 2024 at 12:01 AM Paulo Alcantara <pc@xxxxxxxxxxxxx> wrote:
>
> meetakshisetiyaoss@xxxxxxxxx writes:
>
> > From: Shyam Prasad N <sprasad@xxxxxxxxxxxxx>
> >
> > We recently introduced a password2 field in both ses and ctx structs.
> > This was done so as to allow the client to rotate passwords for a mount
> > without any downtime. However, when the client transparently handles
> > password rotation, it can swap the values of the two password fields
> > in the ses struct, but not in smb3_fs_context struct that hangs off
> > cifs_sb. This can lead to a situation where a remount unintentionally
> > overwrites a working password in the ses struct.
>
> I don't see password rotation being handled for SMB1.  I mounted a share
> with 'vers=1.0,password=foo,password2=bar' and didn't get any warnings
> or errors about it being usupported.  I think users would like to have
> that.

Good point. We could add support for SMB1 or document clearly that
this is only for SMB2+.

>
> What about SMB sessions from cifs_tcon::dfs_ses_list?  I don't see their
> password getting updated over remount.

This is in our to-do list as well.

>
> If you don't plan to support any of the above, then don't allow users to
> mount/remount when password rotation can't be handled.
>
> > In order to fix this, we first get the passwords in ctx struct
> > in-sync with ses struct, before replacing them with what the passwords
> > that could be passed as a part of remount.
> >
> > Also, in order to avoid race condition between smb2_reconnect and
> > smb3_reconfigure, we make sure to lock session_mutex before changing
> > password and password2 fields of the ses structure.
> >
> > Fixes: 35f834265e0d ("smb3: fix broken reconnect when password changing on the server by allowing password rotation")
> > Signed-off-by: Shyam Prasad N <sprasad@xxxxxxxxxxxxx>
> > Signed-off-by: Meetakshi Setiya <msetiya@xxxxxxxxxxxxx>
> > ---
> >  fs/smb/client/fs_context.c | 69 +++++++++++++++++++++++++++++++++-----
> >  1 file changed, 60 insertions(+), 9 deletions(-)
> >
> > diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
> > index 5c5a52019efa..73610e66c8d9 100644
> > --- a/fs/smb/client/fs_context.c
> > +++ b/fs/smb/client/fs_context.c
> > @@ -896,6 +896,7 @@ static int smb3_reconfigure(struct fs_context *fc)
> >       struct dentry *root = fc->root;
> >       struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
> >       struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
> > +     char *new_password = NULL, *new_password2 = NULL;
> >       bool need_recon = false;
> >       int rc;
> >
> > @@ -915,21 +916,71 @@ static int smb3_reconfigure(struct fs_context *fc)
> >       STEAL_STRING(cifs_sb, ctx, UNC);
> >       STEAL_STRING(cifs_sb, ctx, source);
> >       STEAL_STRING(cifs_sb, ctx, username);
> > +
> >       if (need_recon == false)
> >               STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
> >       else  {
> > -             kfree_sensitive(ses->password);
> > -             ses->password = kstrdup(ctx->password, GFP_KERNEL);
> > -             if (!ses->password)
> > -                     return -ENOMEM;
> > -             kfree_sensitive(ses->password2);
> > -             ses->password2 = kstrdup(ctx->password2, GFP_KERNEL);
> > -             if (!ses->password2) {
> > -                     kfree_sensitive(ses->password);
> > -                     ses->password = NULL;
> > +             if (ctx->password) {
> > +                     new_password = kstrdup(ctx->password, GFP_KERNEL);
> > +                     if (!new_password)
> > +                             return -ENOMEM;
> > +             } else
> > +                     STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
> > +     }
> > +
> > +     /*
> > +      * if a new password2 has been specified, then reset it's value
> > +      * inside the ses struct
> > +      */
> > +     if (ctx->password2) {
> > +             new_password2 = kstrdup(ctx->password2, GFP_KERNEL);
> > +             if (!new_password2) {
> > +                     if (new_password)
>
> Useless non-NULL check as kfree_sensitive() already handles it.
>
> > +                             kfree_sensitive(new_password);
> >                       return -ENOMEM;
> >               }
> > +     } else
> > +             STEAL_STRING_SENSITIVE(cifs_sb, ctx, password2);
> > +
> > +     /*
> > +      * we may update the passwords in the ses struct below. Make sure we do
> > +      * not race with smb2_reconnect
> > +      */
> > +     mutex_lock(&ses->session_mutex);
> > +
> > +     /*
> > +      * smb2_reconnect may swap password and password2 in case session setup
> > +      * failed. First get ctx passwords in sync with ses passwords. It should
> > +      * be okay to do this even if this function were to return an error at a
> > +      * later stage
> > +      */
> > +     if (ses->password &&
> > +         cifs_sb->ctx->password &&
> > +         strcmp(ses->password, cifs_sb->ctx->password)) {
> > +             kfree_sensitive(cifs_sb->ctx->password);
> > +             cifs_sb->ctx->password = kstrdup(ses->password, GFP_KERNEL);
>
> Missing allocation failure check.
>
> > +     }
> > +     if (ses->password2 &&
> > +         cifs_sb->ctx->password2 &&
> > +         strcmp(ses->password2, cifs_sb->ctx->password2)) {
> > +             kfree_sensitive(cifs_sb->ctx->password2);
> > +             cifs_sb->ctx->password2 = kstrdup(ses->password2, GFP_KERNEL);
>
> Ditto.
>
> > +     }
> > +
> > +     /*
> > +      * now that allocations for passwords are done, commit them
> > +      */
> > +     if (new_password) {
> > +             kfree_sensitive(ses->password);
> > +             ses->password = new_password;
> > +     }
> > +     if (new_password2) {
> > +             kfree_sensitive(ses->password2);
> > +             ses->password2 = new_password2;
> >       }
> > +
> > +     mutex_unlock(&ses->session_mutex);
> > +
> >       STEAL_STRING(cifs_sb, ctx, domainname);
> >       STEAL_STRING(cifs_sb, ctx, nodename);
> >       STEAL_STRING(cifs_sb, ctx, iocharset);
> > --
> > 2.46.0.46.g406f326d27



-- 
Regards,
Shyam





[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux