Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 May 2003 22:29:59 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        Enache Adrian <enache@rdslink.ro>
Cc:        Yaroslav Levchenko <yarick@sunbay.com>
Subject:   Re: libc_r: threaded application could stuck in accept(2)
Message-ID:  <20030530192959.GC60607@sunbay.com>
In-Reply-To: <20030530171641.GA60607@sunbay.com>
References:  <20030530143541.GB42349@sunbay.com> <20030530160723.GB872@ratsnest.hole> <20030530171641.GA60607@sunbay.com>

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

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

On Fri, May 30, 2003 at 08:16:41PM +0300, Ruslan Ermilov wrote:
> On Fri, May 30, 2003 at 07:07:23PM +0300, Enache Adrian wrote:
> > On Fri, May 30, 2003 at 05:35:41PM +0300, Ruslan Ermilov wrote:
> > > We had a bug in our threaded application that would mistakenly close
> > > the descriptor 0, and this triggers a bug in libc_r which I will try
> > > to describe below.
> > ...
> > > Some important notes: this bug is only applicable to descriptors
> > > 0 - 2 (stdio set), and might have something to do with the code
> > > in uthread_fd.c.  If you remove two lines that free the descriptor
> > > 0 in the attached test case, the bug won't manifest itself.
> >=20
> > please have a look at
> >=20
> > http://www.freebsd.org/cgi/query-pr.cgi?pr=3D51535
> >=20
> Thanks, I had this same patch in my first version of the fix.
> Yes it works too, but do you have an insight what's going on
> without these fixes so that the 0..2 descriptors are left in
> a blocking mode?  I just can't get it where this happens.
>=20
OK, I now know what's going on here.  Without patches, a
second close(0) calls _FDLOCK(0, ...) which calls
_thread_fd_table_init(0).  In this functions, the
following condition becomes false

                /* Get the flags for the file: */
                if (((fd >=3D 3) || (_pthread_stdio_flags[fd] =3D=3D -1)) &&
                    (entry->flags =3D __sys_fcntl(fd, F_GETFL, 0)) =3D=3D -=
1) {
                        ret =3D -1;
                }

due to _pthread_stdio_flags[0] !=3D -1, and we succeed
to the "else" block which eventually installs the "entry"
as _thread_fd_table[0].

Then, the call to socket() calls _thread_fd_table_init(0)
again, but since it detects that the memory is already
allocated (for non-existing descriptor 0), it doesn't
try to set it to non-blocking mode.

With my patch, we just don't allow the second call to
_thread_fd_table_init(0) when descriptor 0 doesn't exist.

With your patch that resets _pthread_stdio_flags[0] to -1
on close, attempting to close(0) for the second time
evaluates the condition above to true, and then
__sys_fcntl(0, F_GETFL, 0) returns -1 (EBADF), and
then the "entry" is free()'ed.  Then, on the next socket()
call, _thread_fd_table_init(0) allocates the memory
for fd 0, and sets it to non-blocking mode.

> P.S.  I will commit both patches after the freeze is over.
>=20
Your patch also fixes the bug you mentioned, so I will
commit both patches.


Cheers,
--=20
Ruslan Ermilov		Sysadmin and DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer.

--jy6Sn24JjFx/iggw
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (FreeBSD)

iD8DBQE+17E3Ukv4P6juNwoRArebAJ9FoJro+BBMmIYQUdnty9EyJzN3hQCghxKI
bXMG5PL+TctWWWofReoekOU=
=hFtz
-----END PGP SIGNATURE-----

--jy6Sn24JjFx/iggw--



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