svn commit: r267760 - head/sys/kern
Konstantin Belousov
kostikbel at gmail.com
Mon Jun 23 07:25:25 UTC 2014
On Mon, Jun 23, 2014 at 09:06:52AM +0200, Mateusz Guzik wrote:
> On Mon, Jun 23, 2014 at 09:40:44AM +0300, Konstantin Belousov wrote:
> > On Mon, Jun 23, 2014 at 01:28:18AM +0000, Mateusz Guzik wrote:
> > > + KASSERT(fdp->fd_refcnt == 1, ("the fdtable should not be shared"));
> > > FILEDESC_XLOCK(fdp);
> > This is at least weird. Not incorrect, but the code now looks strange.
> > The fd_refcnt == 1 assert just states the circumstances of the code which
> > currently calls the functions. Would the functions become incorrect or
> > destructive if there are other references to the filedescriptor table ?
> >
> > In case you argument is that refcnt == 1 must hold to prevent the parallel
> > modifications of the descriptor table, which would invalidate the checks
> > and actions of the functions, then XLOCK is not needed (similar to your
> > earlier commit).
> >
> > Note that kern_execve() is executed with the process single-threaded,
> > which, together with statement fd_refcnt == 1 must prevent the parallel
> > modifications.
>
> The table is modified in these functions and is reachable from the rest
> of the kernel (can be found by e.g. sysctl_kern_proc_filedesc), thus
> XLOCK is needed to ensure consistency for readers. It can also be
> altered by mountcheckdirs, although not in a way which disrupts any of
> these functions.
I would think that such cases should be avoided by testing for P_INEXEC,
but I do not insist on this.
>
> For now I do agree that both the assertion and XLOCK look weird as it is
> and as such deserve a comment.
>
> Actually we can take the lock only if we are going to modify something.
>
> How about the following then (untested):
See below, but I would be completely satisfied even by only
comment addition.
>
> diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
> index 25c3a1e..31f4881 100644
> --- a/sys/kern/kern_descrip.c
> +++ b/sys/kern/kern_descrip.c
> @@ -2082,13 +2082,18 @@ setugidsafety(struct thread *td)
> int i;
>
> fdp = td->td_proc->p_fd;
> + /*
> + * While no other thread can alter filedescriptors in this table,
> + * there may be code trying to read it, thus the lock is required
> + * to provide consistent view if we are going to change it.
> + */
> KASSERT(fdp->fd_refcnt == 1, ("the fdtable should not be shared"));
> - FILEDESC_XLOCK(fdp);
> for (i = 0; i <= fdp->fd_lastfile; i++) {
> if (i > 2)
> break;
> fp = fdp->fd_ofiles[i].fde_file;
> if (fp != NULL && is_unsafe(fp)) {
> + FILEDESC_XLOCK(fdp);
> knote_fdclose(td, i);
> /*
> * NULL-out descriptor prior to close to avoid
> @@ -2097,7 +2102,6 @@ setugidsafety(struct thread *td)
> fdfree(fdp, i);
> FILEDESC_XUNLOCK(fdp);
> (void) closef(fp, td);
> - FILEDESC_XLOCK(fdp);
> }
> }
> FILEDESC_XUNLOCK(fdp);
This unlock should be removed ?
> @@ -2136,16 +2140,16 @@ fdcloseexec(struct thread *td)
>
> fdp = td->td_proc->p_fd;
> KASSERT(fdp->fd_refcnt == 1, ("the fdtable should not be shared"));
> - FILEDESC_XLOCK(fdp);
> for (i = 0; i <= fdp->fd_lastfile; i++) {
> fde = &fdp->fd_ofiles[i];
> fp = fde->fde_file;
> if (fp != NULL && (fp->f_type == DTYPE_MQUEUE ||
> (fde->fde_flags & UF_EXCLOSE))) {
> + /* See the comment in setugidsafety */
> + FILEDESC_XLOCK(fdp);
> fdfree(fdp, i);
> (void) closefp(fdp, i, fp, td, 0);
> /* closefp() drops the FILEDESC lock. */
> - FILEDESC_XLOCK(fdp);
This should be XUNLOCK ?
> }
> }
> FILEDESC_XUNLOCK(fdp);
And this unlock removed ?
>
>
> --
> Mateusz Guzik <mjguzik gmail.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/svn-src-head/attachments/20140623/991f8320/attachment.sig>
More information about the svn-src-head
mailing list