U9fs(4) misuses Fcall.afid in its p9any authentication module.

The afid field of Fcall structure is only valid with Tauth or Tattach.
Tread, Twrite, Tclunk should use rx->fid instead.  It's been lucky so
far to get the job done because rx->afid survives from previous
Tauth/Tattach.  The issue pops up when several authentications happen
concurrently.

Test case:
        u9fs = 'host with u9fs on tcp!*!564'
        9fs $u9fs; for(i in 1 2 3 4 5 6 7 8){ 9fs $u9fs & }; wait
Should:
        no errors
Should not:
        mount failed: authentication failed

<patch/diff u9fs-afid
/sys/src/cmd/unix/u9fs/authp9any.c
        authp9any.c.orig:369,375 - 
/n/sources/patch/u9fs-afid/authp9any.c:369,378
                        fprint(2, "p9anyattach: afid %d state %d\n", rx->afid, 
sp->state);
                if (sp->state == Established && strcmp(rx->uname, sp->uname) == 0
                        && strcmp(rx->aname, sp->aname) == 0)
        +       {
        +               rx->uname = sp->t.suid;         /* will be valid until 
afid is clunked */
                        return nil;
        +       }
                return "authentication failed";
          }
          
        authp9any.c.orig:392,398 - 
/n/sources/patch/u9fs-afid/authp9any.c:395,401
                char *ep;
          
                Fid *f;
        -       f = oldauthfid(rx->afid, (void **)&sp, &ep);
        +       f = oldauthfid(rx->fid, (void **)&sp, &ep);
                if (f == nil)
                        return ep;
                if (chatty9p)
        authp9any.c.orig:437,443 - 
/n/sources/patch/u9fs-afid/authp9any.c:440,446
          
                Fid *f;
          
        -       f = oldauthfid(rx->afid, (void **)&sp, &ep);
        +       f = oldauthfid(rx->fid, (void **)&sp, &ep);
                if (f == nil)
                        return ep;
                if (chatty9p)
        authp9any.c.orig:515,521 - 
/n/sources/patch/u9fs-afid/authp9any.c:518,524
                AuthSession *sp;
                char *ep;
          
        -       f = oldauthfid(rx->afid, (void **)&sp, &ep);
        +       f = oldauthfid(rx->fid, (void **)&sp, &ep);
                if (f == nil)
                        return ep;
                if (chatty9p)


Reply via email to