On Wed, Feb 22, 2023 at 10:19:57AM -0700, Todd C. Miller wrote:
> On Wed, 22 Feb 2023 17:11:47 +0100, Moritz Buhl wrote:
> 
> > The tool finds a path to ex_search where fsb.f_fsid is uninitialized.
> >
> > ex_search compares the potentially uninitialized stack data:
> >
> > ex_search(fsid_t *fsid)
> > {
> >     struct exportlist *ep;
> >
> >     ep = exphead;
> >     while (ep) {
> >             if (ep->ex_fs.val[0] == fsid->val[0] &&
> > ...
> >
> > Is it sufficient to zero fsb?
> > Is this really reachable?
> 
> I believe that it is.  However, I don't know why we wouldn't just
> want to skip ex_search, etc when bad is set.  Also, there is no
> reason to use a critical section now that the SIGHUP handle just
> sets a flag.  Something like this (untested), should be fine.

The code checker still finds an issue.

                if (realpath(rpcpath, dirpath) == NULL) {
                        bad = errno;
                        ...
                }
                if (bad)
                        goto mount_error;

This relys on the fact that after realpath() == NULL, errno != 0.
I have checked libc, this works.  The new report is a false positive.

mbuhl@ mentioned to me that
                strlcpy(dirpath, rpcpath, sizeof(dirpath));
is dead code now.  Before dirpath was used in
                    ((dp = dirp_search(ep->ex_dirl, dirpath)) &&
even in the bad case.

Now bad is set to ENOENT in a case where EACCES was used before.
I doubt that this little change has relevant impact.

OK bluhm@

> It needs testing by someone who actually uses NFS though...

I am running it on my NFS server.

> Index: sbin/mountd/mountd.c
> ===================================================================
> RCS file: /cvs/src/sbin/mountd/mountd.c,v
> retrieving revision 1.89
> diff -u -p -u -r1.89 mountd.c
> --- sbin/mountd/mountd.c      6 Aug 2020 17:57:32 -0000       1.89
> +++ sbin/mountd/mountd.c      22 Feb 2023 17:17:44 -0000
> @@ -736,7 +736,6 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
>       char rpcpath[RPCMNT_PATHLEN+1], dirpath[PATH_MAX];
>       struct hostent *hp = NULL;
>       struct exportlist *ep;
> -     sigset_t sighup_mask;
>       int defset, hostset;
>       struct fhreturn fhr;
>       struct dirlist *dp;
> @@ -746,8 +745,6 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
>       u_short sport;
>       long bad = 0;
>  
> -     sigemptyset(&sighup_mask);
> -     sigaddset(&sighup_mask, SIGHUP);
>       saddr = transp->xp_raddr.sin_addr.s_addr;
>       sport = ntohs(transp->xp_raddr.sin_port);
>       switch (rqstp->rq_proc) {
> @@ -790,9 +787,10 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
>                               fprintf(stderr, "stat failed on %s\n", dirpath);
>                       bad = ENOENT;   /* We will send error reply later */
>               }
> +             if (bad)
> +                     goto mount_error;
>  
>               /* Check in the exports list */
> -             sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
>               ep = ex_search(&fsb.f_fsid);
>               hostset = defset = 0;
>               if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset) ||
> @@ -800,13 +798,6 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
>                   chk_host(dp, saddr, &defset, &hostset)) ||
>                   (defset && scan_tree(ep->ex_defdir, saddr) == 0 &&
>                   scan_tree(ep->ex_dirl, saddr) == 0))) {
> -                     if (bad) {
> -                             if (!svc_sendreply(transp, xdr_long,
> -                                 (caddr_t)&bad))
> -                                     syslog(LOG_ERR, "Can't send reply");
> -                             sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
> -                             return;
> -                     }
>                       if (hostset & DP_HOSTSET)
>                               fhr.fhr_flag = hostset;
>                       else
> @@ -817,11 +808,7 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
>                       if (imsg_getfh(dirpath, (fhandle_t *)&fhr.fhr_fh) < 0) {
>                               bad = errno;
>                               syslog(LOG_ERR, "Can't get fh for %s", dirpath);
> -                             if (!svc_sendreply(transp, xdr_long,
> -                                 (caddr_t)&bad))
> -                                     syslog(LOG_ERR, "Can't send reply");
> -                             sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
> -                             return;
> +                             goto mount_error;
>                       }
>                       if (!svc_sendreply(transp, xdr_fhs, (caddr_t)&fhr))
>                               syslog(LOG_ERR, "Can't send reply");
> @@ -842,9 +829,11 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
>               } else
>                       bad = EACCES;
>  
> -             if (bad && !svc_sendreply(transp, xdr_long, (caddr_t)&bad))
> -                     syslog(LOG_ERR, "Can't send reply");
> -             sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
> +             if (bad) {
> +             mount_error:
> +                     if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad))
> +                             syslog(LOG_ERR, "Can't send reply");
> +             }
>               return;
>       case RPCMNT_DUMP:
>               if (!svc_sendreply(transp, xdr_mlist, NULL))
> @@ -958,11 +947,7 @@ xdr_explist(XDR *xdrsp, caddr_t cp)
>  {
>       struct exportlist *ep;
>       int false = 0, putdef;
> -     sigset_t sighup_mask;
>  
> -     sigemptyset(&sighup_mask);
> -     sigaddset(&sighup_mask, SIGHUP);
> -     sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
>       ep = exphead;
>       while (ep) {
>               putdef = 0;
> @@ -973,12 +958,9 @@ xdr_explist(XDR *xdrsp, caddr_t cp)
>                       goto errout;
>               ep = ep->ex_next;
>       }
> -     sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
> -     if (!xdr_bool(xdrsp, &false))
> -             return (0);
> -     return (1);
> +     if (xdr_bool(xdrsp, &false))
> +             return (1);
>  errout:
> -     sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
>       return (0);
>  }
>  
> @@ -1050,7 +1032,6 @@ void
>  new_exportlist(int signo)
>  {
>       gothup = 1;
> -
>  }
>  
>  /*

Reply via email to