From owner-freebsd-bugs@FreeBSD.ORG Mon Apr 28 18:40:15 2003 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4DCB237B404 for ; Mon, 28 Apr 2003 18:40:15 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id CC80D43FD7 for ; Mon, 28 Apr 2003 18:40:13 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.9/8.12.9) with ESMTP id h3T1eDUp099994 for ; Mon, 28 Apr 2003 18:40:13 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.9/8.12.9/Submit) id h3T1eDVo099987; Mon, 28 Apr 2003 18:40:13 -0700 (PDT) Resent-Date: Mon, 28 Apr 2003 18:40:13 -0700 (PDT) Resent-Message-Id: <200304290140.h3T1eDVo099987@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Enache Adrian Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9909E37B404 for ; Mon, 28 Apr 2003 18:35:17 -0700 (PDT) Received: from mail.rdslink.ro (mail.rdslink.ro [193.231.236.20]) by mx1.FreeBSD.org (Postfix) with SMTP id 0C2CE43F85 for ; Mon, 28 Apr 2003 18:35:16 -0700 (PDT) (envelope-from enache@rdslink.ro) Received: (qmail 31430 invoked from network); 29 Apr 2003 01:38:01 -0000 Received: from unknown (HELO ratsnest.hole) (81.196.245.173) by mail.rdslink.ro with SMTP; 29 Apr 2003 01:38:01 -0000 Message-Id: <20030429013718.GA14503@ratsnest.hole> Date: Tue, 29 Apr 2003 04:37:18 +0300 From: Enache Adrian To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/51535: uthreads bug: new opened files may get stale fcntl flags X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Apr 2003 01:40:15 -0000 >Number: 51535 >Category: bin >Synopsis: uthreads bug: new opened files may get stale fcntl flags >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Apr 28 18:40:13 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Enache Adrian >Release: FreeBSD 5.0-CURRENT i386 >Organization: none >Environment: System: FreeBSD ratsnest.hole 5.0-CURRENT FreeBSD 5.0-CURRENT #2: Tue Apr 15 15:15:34 EEST 2003 root@ratsnest.hole:/opt/tmp/CUBATAO i386 >Description: In programs linked against libc_r: - dup2'ing another file to one of the standard file descriptors - doing his job with it and then closing it - opening another file ( which will re-use the same fd ) will cause the latter to "inherit" the closed file's fcntl flags. That defeats anyone trying to play with redirecting stdout to a (write-only opened) file - the only "solution" is to leave it open, if not you he not be able to read from any file after that. Perl for instance does a lot of things like that: this bug seems to be the cause why recent threaded builds on FreeBSD fail miserably. It's probably caused by the code in _thread_fd_table_init() (uthread/uthread_fd.c:127) if ((fd < 3) && (_pthread_stdio_flags[fd] != -1)) /* * Use the stdio flags read by * _pthread_init() to avoid * mistaking the non-blocking * flag that, when set on one * stdio fd, is set on all stdio * fds. */ entry->flags = _pthread_stdio_flags[fd]; I'm using a very recent -CURRENT. There are rumors that this bug is present also in FreeBSD 4.8, NetBSD 1.6 and recent OpenBSD, but I have no possibility to verify it. >How-To-Repeat: compile the following test program with -lc_r or -pthread and run it: ---------------------------------------------------------------------- #include #include int main(int argc,char **argv) { int fd,cnt; char buf[12] = "hallo baby!"; if (!argv[1]) errx(1,"usage: %s file",argv[0]); if ((fd = open(argv[1],O_WRONLY)) == -1) err(1,"open"); if ((cnt = dup2(fd,1)) == -1) err(1,"dup2"); if ((cnt = write(1,buf,12)) == -1) err(1,"write"); if (close(1) == -1) err(1,"close"); if ((fd = open(argv[1],O_RDONLY)) == -1) err(1,"open"); if ((cnt = read(fd,buf,12)) == -1) err(1,"read"); else warnx("read: %s", buf); return 0; } ---------------------------------------------------------------------- $ cc -lc_r test.c -o test $ ./test a test: read: Bad file descriptor >Fix: Applying this patch definitely fixes it on my box: ---------------------------------------------------------------------- diff -rup /arc/freebsd/src/lib/libc_r/uthread/uthread_close.c ./uthread/uthread_close.c --- /arc/freebsd/src/lib/libc_r/uthread/uthread_close.c Sat Oct 26 08:22:30 2002 +++ ./uthread/uthread_close.c Tue Apr 29 01:26:54 2003 @@ -96,6 +96,10 @@ _close(int fd) _thread_fd_table[fd] = NULL; free(entry); + /* drop stale pthread stdio flags */ + if (fd < 3) + _pthread_stdio_flags[fd] = -1; + /* Close the file descriptor: */ ret = __sys_close(fd); } ---------------------------------------------------------------------- >Release-Note: >Audit-Trail: >Unformatted: