Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Jun 2014 11:18:23 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Mateusz Guzik <mjguzik@gmail.com>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, Mateusz Guzik <mjg@FreeBSD.org>
Subject:   Re: svn commit: r267760 - head/sys/kern
Message-ID:  <20140623081823.GG93733@kib.kiev.ua>
In-Reply-To: <20140623080501.GB27040@dft-labs.eu>
References:  <201406230128.s5N1SIYK097224@svn.freebsd.org> <20140623064044.GD93733@kib.kiev.ua> <20140623070652.GA27040@dft-labs.eu> <20140623072519.GE93733@kib.kiev.ua> <20140623080501.GB27040@dft-labs.eu>

next in thread | previous in thread | raw e-mail | index | archive | help

--2NLGdgz3UMHa/lqP
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Jun 23, 2014 at 10:05:01AM +0200, Mateusz Guzik wrote:
> On Mon, Jun 23, 2014 at 10:25:19AM +0300, Konstantin Belousov wrote:
> > On Mon, Jun 23, 2014 at 09:06:52AM +0200, Mateusz Guzik wrote:
> > > The table is modified in these functions and is reachable from the re=
st
> > > 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.
> >=20
>=20
> proc lock has to be dropped before filedesc lock is taken and I don't
> see any way to prevent the proc from transitioning to P_INEXEC afterwards.
> Since sysctl_kern_proc_filedesc et al can take a long time it does not
> seem feasible to pursue this.
>=20
> This also makes me realize I screwed up r265247 "Request a non-exiting
> process in sysctl_kern_proc_{o,}filedesc". As it is the code has to hold
> the process and release it later to really close the race and not only
> affect the window. I'll poke around this later, maybe it is better to
> nullify some stuff in exit1 with PROC_LOCK held and access it in a
> similar manner.
>=20
> > > @@ -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 ?
> >=20
>=20
> Ugh, yes.
>=20
> > > +                       /* 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 ?
>=20
> This one is fine as closefp drops the lock.
>=20
> > >                 }
> > >         }
> > >         FILEDESC_XUNLOCK(fdp);
> > And this unlock removed ?
>=20
> Yes.
>=20
> I tested this patch and it works fine:
>=20
> diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
> index 25c3a1e..a900464 100644
> --- a/sys/kern/kern_descrip.c
> +++ b/sys/kern/kern_descrip.c
> @@ -2082,13 +2082,18 @@ setugidsafety(struct thread *td)
>  	int i;
> =20
>  	fdp =3D 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 =3D=3D 1, ("the fdtable should not be shared"));
> -	FILEDESC_XLOCK(fdp);
>  	for (i =3D 0; i <=3D fdp->fd_lastfile; i++) {
>  		if (i > 2)
>  			break;
>  		fp =3D fdp->fd_ofiles[i].fde_file;
>  		if (fp !=3D NULL && is_unsafe(fp)) {
> +			FILEDESC_XLOCK(fdp);
>  			knote_fdclose(td, i);
>  			/*
>  			 * NULL-out descriptor prior to close to avoid
> @@ -2097,10 +2102,8 @@ setugidsafety(struct thread *td)
>  			fdfree(fdp, i);
>  			FILEDESC_XUNLOCK(fdp);
>  			(void) closef(fp, td);
> -			FILEDESC_XLOCK(fdp);
>  		}
>  	}
> -	FILEDESC_XUNLOCK(fdp);
>  }
> =20
>  /*
> @@ -2136,19 +2139,18 @@ fdcloseexec(struct thread *td)
> =20
>  	fdp =3D td->td_proc->p_fd;
>  	KASSERT(fdp->fd_refcnt =3D=3D 1, ("the fdtable should not be shared"));
> -	FILEDESC_XLOCK(fdp);
>  	for (i =3D 0; i <=3D fdp->fd_lastfile; i++) {
>  		fde =3D &fdp->fd_ofiles[i];
>  		fp =3D fde->fde_file;
>  		if (fp !=3D NULL && (fp->f_type =3D=3D 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);
>  		}
>  	}
> -	FILEDESC_XUNLOCK(fdp);
>  }
> =20
>  /*

This looks fine, but please e.g. add a reference to the comment in
etugidsafety(), to fdcloseexec().  Or duplicate it.

--2NLGdgz3UMHa/lqP
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBAgAGBQJTp+LOAAoJEJDCuSvBvK1BLEkQAJ3ujP7+owotKSoZ2ncGvCRD
qKBmQGOSRMPWurCd6aXmk9nUx3RqbUTpWRdKmT2ctA2MeXU87x7rQWnCdXkLhaJQ
TF+QssLu/b+fHGyjF9xbQnpNuq+DQoNDPyx9+LxfANLd4REDi/qS6pVaJEsXjUiO
WRJcZoR4CeJ41Zzw2TnYmiYwkP3AJ4YIYYEVwVk+DJ2HzvG9pRg/0QZdrC2aC+8g
OzBntJV9fxhaK1qOLbt6TZiyIU7GIYLGoL3TPnsKLCyZ5iFEpR+SQOuqe0PIP/yQ
eUlvjEbIsJVHzXh/kYx9gMkvO5GzeOGxUuug7hXOXGX9DldETukSjXqFFPbd8q1G
sGH+g/heGPfwcjTCqj6Vtcp7iw0M5Teeq5JT/1gBJAGNjWAXRP601MeqnydjiI8j
MZw9npwLreQvpTWguhu0rb5Xz/wlHEquX6KQOhQHzfDSMmdtljUSaFm4Z+n7/bIG
DkBMOqWLHO7qVb4B0Y678OYOsqQobbctGpBAZJc493mT/0zZ9Navx4ID+MXFYZbB
1/ziXemoX3l8fByJf9o5UGIZW0P6G4m/IapPqNKkHjn/DKGYT/r0Y61/eNJ5ylWe
V49iaPkn6YRWIg6YQXElqyaz675ZyoKuHYSmmNCE5VJSxtOVTyietJXXZMY78ra+
B04wTy/24occDr3EITMT
=LqI4
-----END PGP SIGNATURE-----

--2NLGdgz3UMHa/lqP--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140623081823.GG93733>