Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Jun 2014 10:25:19 +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:  <20140623072519.GE93733@kib.kiev.ua>
In-Reply-To: <20140623070652.GA27040@dft-labs.eu>
References:  <201406230128.s5N1SIYK097224@svn.freebsd.org> <20140623064044.GD93733@kib.kiev.ua> <20140623070652.GA27040@dft-labs.eu>

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

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

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 =3D=3D 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 =3D=3D 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 ?
> >=20
> > In case you argument is that refcnt =3D=3D 1 must hold to prevent the p=
arallel
> > 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).
> >=20
> > Note that kern_execve() is executed with the process single-threaded,
> > which, together with statement fd_refcnt =3D=3D 1 must prevent the para=
llel
> > modifications.
>=20
> 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.

>=20
> For now I do agree that both the assertion and XLOCK look weird as it is
> and as such deserve a comment.
>=20
> Actually we can take the lock only if we are going to modify something.
>=20
> How about the following then (untested):
See below, but I would be completely satisfied even by only
comment addition.

>=20
> 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;
> =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 shar=
ed"));
> -       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,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)
> =20
>         fdp =3D td->td_proc->p_fd;
>         KASSERT(fdp->fd_refcnt =3D=3D 1, ("the fdtable should not be shar=
ed"));
> -       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);
This should be XUNLOCK ?
>                 }
>         }
>         FILEDESC_XUNLOCK(fdp);
And this unlock removed ?
>=20
>=20
> --=20
> Mateusz Guzik <mjguzik gmail.com>

--ytoMbUMiTKPMT3hY
Content-Type: application/pgp-signature

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

iQIcBAEBAgAGBQJTp9ZeAAoJEJDCuSvBvK1BAcAP/jB9jwxozqXmgeQjWzGyFKjK
TnVv3ueKPh/vsWVnQZa/kaRmVyyTU5e9BlhmRKCgbvklU06KLkO729khGIESp15A
jeNjR+LBxq6Zq5HjV/1Kdy6VMP/apqnYWc53vwxPdy2sjBgdOrYjBtnuQqfblcfK
QtAjIJ7b8aF4iJ/2Ijs2Xq0dDNzS2naoNBGGOlA8fayrw0BPs4h9oTVZUvnq+c8z
/FgMNk7D+0M7ghOhsAlAiNyp1ElG6piVKfVNKaqVwDs8ZGQtYyXaw7XGIkNcRMVx
3uNCCtYSG7+DPQUP8yo4sRusDHZnzUti8EOvhHTS76FUcprjUEe1OsIoyVkM4axD
wKipFm3viuCEe+RFmo97tG8uHiVlMeNN7G1i3AwKRL0wyEGm0A3mrOO8lRbZNeOu
oKtmgZHdgGM8gTAG69bPTpD7wQUgDr5gpSkTYO/9E82LnXmWfHCl68hioAyAC0RD
yzmnpuQ/S4gRQjSBImp3TqQsEmHnZqBWqq+g6q+fC6fCKbe5k+KRptOWERpAWRxG
V8Q/zbxEa/gUcVXphPR4GL6rq5L5KWvNi9B3p7aSoTS4OYPWhy6b3BkM51p8Qqbm
i1OK++xdmJ4/e9fTXkB62BLQV7jwAPn4pk+ziW3qBbRTFZGLfE4KloiQk8U7nGEV
QN9uXb728IYlj9yePGvT
=5RZm
-----END PGP SIGNATURE-----

--ytoMbUMiTKPMT3hY--



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