Bug 28947

Summary: dup2 closing pthread file descriptor
Product: Base System Reporter: sdalu <sdalu>
Component: miscAssignee: Maxim Konovalov <maxim>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.2-RELEASE   
Hardware: Any   
OS: Any   

Description sdalu 2001-07-13 15:00:01 UTC
when using pthread 2 file descriptors are used for pipes (see lsof output),
these file descriptors can't be closed by close(), but dup2() manage to 
duplicate other fd at these positions (fcntl/F_DUPFD cannot)

the real problem occurs when doing an exec, when presumably the
pthread is doing some cleanup and closes its files descriptor,
unfortunatelly these descriptors are not its own anymore but the
copy done but dup2.

would have expected dup2() to fail
(the problem is perhaps more with the pthread librairy than the kernel)

How-To-Repeat: 
-- a ------------------------
#include <pthread.h>

int main() {
    if (close(3) < 0)
	perror("close");
    if (dup2(0, 3) < 0) 
	perror("dup2");
}
-----------------------------

gcc -o a a.c -pthread

a         71332 sdalu    0u  VCHR          5,14     0t4766    8311 /dev/ttype
a         71332 sdalu    1u  VCHR          5,14     0t4766    8311 /dev/ttype
a         71332 sdalu    2u  VCHR          5,14     0t4766    8311 /dev/ttype
a         71332 sdalu    3u  PIPE    0xd734f260      16384         ->0xd734f300
a         71332 sdalu    4u  PIPE    0xd734f300      16384         ->0xd734f260

./a
close: Bad file descriptor
Comment 1 Jason Evans freebsd_committer freebsd_triage 2001-12-17 20:41:01 UTC
Responsible Changed
From-To: freebsd-bugs->jasone

I'll look at this.
Comment 2 Maxim Konovalov 2002-02-13 18:22:34 UTC
Could you please try the patch below:

Index: uthread_dup2.c
===================================================================
RCS file: /home/ncvs/src/lib/libc_r/uthread/uthread_dup2.c,v
retrieving revision 1.11
diff -u -r1.11 uthread_dup2.c
--- uthread_dup2.c	10 Apr 2001 04:19:20 -0000	1.11
+++ uthread_dup2.c	13 Feb 2002 18:12:40 -0000
@@ -45,7 +45,8 @@
 	int		newfd_opened;

 	/* Check if the file descriptor is out of range: */
-	if (newfd < 0 || newfd >= _thread_dtablesize) {
+	if (newfd < 0 || newfd >= _thread_dtablesize ||
+	    newfd == _thread_kern_pipe[0] || newfd == _thread_kern_pipe[1]) {
 		/* Return a bad file descriptor error: */
 		errno = EBADF;
 		ret = -1;

-- 
Maxim Konovalov, MAcomnet, Internet-Intranet Dept., system engineer
phone: +7 (095) 796-9079, mailto:maxim@macomnet.ru
Comment 3 sdalu 2002-02-13 22:43:49 UTC
On Wed, Feb 13, 2002 at 09:22:34PM +0300, Maxim Konovalov wrote:
> 
> Could you please try the patch below:

Tested on FreeBSD 4.4-RELEASE i386.

Works fine.

Would it be reasonable to say that file descriptors internally used
by the thread library should not be visible to programmer, and
move them to other places when there is a clash with legitimate 
"syscall" requests like dup2? Not sure the effort is worth it anyway.

> 
> Index: uthread_dup2.c
> ===================================================================
> RCS file: /home/ncvs/src/lib/libc_r/uthread/uthread_dup2.c,v
> retrieving revision 1.11
> diff -u -r1.11 uthread_dup2.c
> --- uthread_dup2.c	10 Apr 2001 04:19:20 -0000	1.11
> +++ uthread_dup2.c	13 Feb 2002 18:12:40 -0000
> @@ -45,7 +45,8 @@
>  	int		newfd_opened;
> 
>  	/* Check if the file descriptor is out of range: */
> -	if (newfd < 0 || newfd >= _thread_dtablesize) {
> +	if (newfd < 0 || newfd >= _thread_dtablesize ||
> +	    newfd == _thread_kern_pipe[0] || newfd == _thread_kern_pipe[1]) {
>  		/* Return a bad file descriptor error: */
>  		errno = EBADF;
>  		ret = -1;
> 
> -- 
> Maxim Konovalov, MAcomnet, Internet-Intranet Dept., system engineer
> phone: +7 (095) 796-9079, mailto:maxim@macomnet.ru

-- 
Stephane D'Alu
Comment 4 Maxim Konovalov freebsd_committer freebsd_triage 2002-02-14 15:22:08 UTC
Responsible Changed
From-To: jasone->maxim

I have a patch for -current.
Comment 5 Maxim Konovalov freebsd_committer freebsd_triage 2002-02-14 15:27:20 UTC
State Changed
From-To: open->analyzed

The fix is committed to -current.
Comment 6 Maxim Konovalov freebsd_committer freebsd_triage 2002-02-21 11:27:46 UTC
State Changed
From-To: analyzed->closed

The fix committed to -current and -stable.