delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2014/01/17/15:06:31

X-Recipient: archive-cygwin AT delorie DOT com
DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:message-id:date:from:mime-version:to:subject
:references:in-reply-to:content-type; q=dns; s=default; b=Cly5/1
S6IlsLB31DpFog22hvwzepg2OnuLTC76mAPA6/mQkht8TpPcBJfMYwO7MdYUBgaq
Z5rAyKTboGT3Czm7t2/wO1LbgjKIif/jwOvfA4+AXGltW5Owv+b3eVVU4W12sjFY
5FH+4KfqRHhvtA4RntxSfov3FXBStnI7BTBM8=
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id
:list-unsubscribe:list-subscribe:list-archive:list-post
:list-help:sender:message-id:date:from:mime-version:to:subject
:references:in-reply-to:content-type; s=default; bh=zcfkCuhDP4Xn
Kg4bD6nGCIWINlU=; b=g1+gyjMmrzW9I8zby3qs3mjOjm32FZh+ZWh5N5+PaTnr
mzzTBl2cHHGsgZZNB0QfwGOC8NIZZacMvcpxtVW+0N/nb3jDQjv1xQ70PwDQ8ptX
4Xx0b6yAG++UOO6BCxAGtVxg7juTQLi+l8kezBzdSK6cc5I/6DrOzw7BcYQmVU0=
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Authentication-Results: sourceware.org; auth=none
X-Virus-Found: No
X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2
X-HELO: mx1.redhat.com
Message-ID: <52D98D31.6070100@redhat.com>
Date: Fri, 17 Jan 2014 13:06:09 -0700
From: Eric Blake <eblake AT redhat DOT com>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: fork() + file descriptor bug in 1.7.27(0.271/5/3) 2013-12-09 11:54
References: <831845 DOT 98759 DOT bm AT smtp116 DOT sbc DOT mail DOT ne1 DOT yahoo DOT com>
In-Reply-To: <831845.98759.bm@smtp116.sbc.mail.ne1.yahoo.com>
OpenPGP: url=http://people.redhat.com/eblake/eblake.gpg
X-IsSubscribed: yes

--L4QxvNjhSNkFQG77kgV4DlbRxqHD3Xc9m
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On 01/13/2014 09:06 AM, tednolan AT bellsouth DOT net wrote:

> 	while( fgets(buf, sizeof(buf), fp) ) {
> 		++i;
>=20
> 		if(sscanf(buf, "%s %s", infile, outfile) !=3D 2) {

>=20
> 		switch (fork()) {
>=20=09=09=09

> 			case 0:
> 				fprintf(stderr, "child\n"); fflush(stderr);
> 				exit(0);

Your program violates POSIX, and triggers undefined behavior.  Add an
fflush(NULL) prior to the fork(), and that should avoid the infloop.

=3D=3D=3D=3D
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#ta=
g_15_05

> Note that after a fork(), two handles exist where one existed before.
The application shall ensure that, if both handles can ever be accessed,
they are both in a state where the other could become the active handle
first. The application shall prepare for a fork() exactly as if it were
a change of active handle. (If the only action performed by one of the
processes is one of the exec functions or _exit() (not exit()), the
handle is never accessed in that process.)

Let's label our two handles: Handle 1 is the parent's handle, as well as
the lone handle that existed pre-fork.  Handle 2 is the child's handle.

>
> For the first handle, the first applicable condition below applies.
After the actions required below are taken, if the handle is still open,
the application can close it.
>
>     If it is a file descriptor, no action is required.

But the handle is a stream, not a file descriptor, so this is not met.

>
>     If the only further action to be performed on any handle to this
open file descriptor is to close it, no action need be taken.

The code isn't calling close(fileno(fp)), so this is not met.

>
>     If it is a stream which is unbuffered, no action need be taken.
>

fp is buffered, so this is not met.

>     If it is a stream which is line buffered, and the last byte
written to the stream was a <newline> (that is, as if a:
>
>         putc('\n')
>
>     was the most recent operation on that stream), no action need be
taken.

fp is not line buffered, so this is not met.

>
>     If it is a stream which is open for writing or appending (but not
also open for reading), the application shall either perform an
fflush(), or the stream shall be closed.

fp is not open for writing, so this is not met.

>
>     If the stream is open for reading and it is at the end of the file
(feof() is true), no action need be taken.

fp is not at EOF, so this is not met.

>
>     If the stream is open with a mode that allows reading and the
underlying open file description refers to a device that is capable of
seeking, the application shall either perform an fflush(), or the stream
shall be closed.

The application did not call fflush(fp) (or fflush(NULL)), and the
stream was not closed prior to fork, so this is not met.

>
> For the second handle:
>
>     If any previous active handle has been used by a function that
explicitly changed the file offset, except as required above for the
first handle, the application shall perform an lseek() or fseek() (as
appropriate to the type of handle) to an appropriate location.

The previous active handle was used to change offset (by fgets), but
none of the requirements on the first handle were met, and we fail to
fseek() on the second handle.  Therefore, the fact that exit() calls
fflush() and changes the offset of the fd, leading to an infloop in the
parent, is a result of the bug in the program violating the POSIX
constraints on active handle manipulation.

>
> If the active handle ceases to be accessible before the requirements
on the first handle, above, have been met, the state of the open file
description becomes undefined. This might occur during functions such as
a fork() or _exit().

--=20
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


--L4QxvNjhSNkFQG77kgV4DlbRxqHD3Xc9m
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Public key at http://people.redhat.com/eblake/eblake.gpg
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBCAAGBQJS2Y0xAAoJEKeha0olJ0NqaDoH/2E4CJM1Y8MlKcCrlRO+qJe+
RKPQ0rXu1L0I71BxSdxZsGkHCkxTH45h/rWwID0xY5gUvTankWQ38vHPzLXkJAuE
Z+0yoh3u5ew5A2IpmBSp8pjW7YGv2R8lQnBd+JiV428cWgOR+V1oIY9rMCYU0Jd1
xWnmnTmT4Ko6TB5vbdhm9OitIFi+h6yHQ0fQl0HX3OCF1i6D3QVazX8iUlYzn/8v
N3IikW64EAYQHX/QE0ft6yPppaXBVLmvLIcAjwALdDEwV6zh3PwoLYFi76/wNXDP
p/T+85mHlPavmRnC4J95L1DMh517bWP1S8Pn7tUDkpWGHUlmdziI+JEj5UGtGVM=
=GjSA
-----END PGP SIGNATURE-----

--L4QxvNjhSNkFQG77kgV4DlbRxqHD3Xc9m--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019