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. It needs testing by someone who actually uses NFS though... - todd 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; - } /*