Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Jun 2002 15:12:57 +0200 (CEST)
From:      cejkar@fit.vutbr.cz
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/39922: [PATCH?] Threaded applications executed with closed std file descr. could not use redirections
Message-ID:  <200206271312.g5RDCvL98013@kazi.fit.vutbr.cz>

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

>Number:         39922
>Category:       bin
>Synopsis:       [PATCH?] Threaded applications executed with closed std file descr. could not use redirections
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jun 27 06:20:03 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Rudolf Cejka
>Release:        FreeBSD 4.6-STABLE i386
>Organization:
FIT, Brno University of Technology, Czech Republic
>Environment:
	Tested on 4.6-STABLE.

>Description:
	When an threaded application (linked with libc_r) is executed
	with closed some of the standard file descriptors (for example
	some daemons, server processes...), initialization code of
	threads opens two internal file descriptors (_thread_kern_pipe[0, 1])
	that are then blocked for use by the threaded application, so if
	one of _thread_kern_pipe[0, 1] gets value 0, 1, or 2, an
	application could not use particular redirections. Similar scenario
	can occur around fork()/close() combination of calls. I have found
	this problem because of use of popen() library call in an
	threaded application, where the situation is even worse, because
	the failure of stdin/stdout redirection is silently ignored
	(another bug???), so everything looked that works, but
	communication between child and parent process was silently broken.

	(I understand that it is possible to disable linking label_tape
	with libc_r in my particular situation and problem should be
	avoided, however I see that this problem can be easily triggered
	by any real threaded applications.)

>How-To-Repeat:
>Fix:
	Here are two patches, which maybe are not very perfect solution
	to this problem, but they enable to run afbackup-3.3.7 with
	media changer and threads enabled successfully on my system
	via cron. The patches redirect descriptors _thread_kern_pipe[0, 1]
	with too small value (< 3) to any bigger value.

--- uthread_init.c.orig	Wed Jun 26 22:04:12 2002
+++ uthread_init.c	Thu Jun 27 13:37:45 2002
@@ -111,6 +111,7 @@
 _thread_init(void)
 {
 	int		fd;
+	int		dupfd;
 	int             flags;
 	int             i;
 	size_t		len;
@@ -207,6 +208,18 @@
 	else if ((_thread_kern_sched_stack = malloc(SCHED_STACK_SIZE)) == NULL)
 		PANIC("Failed to allocate stack for scheduler");
 	else {
+		if (_thread_kern_pipe[0] < 3 &&
+		    (dupfd = _thread_sys_fcntl(_thread_kern_pipe[0],
+		    F_DUPFD, 3)) != -1) {
+			close(_thread_kern_pipe[0]);
+			_thread_kern_pipe[0] = dupfd;
+		}
+		if (_thread_kern_pipe[1] < 3 &&
+		    (dupfd = _thread_sys_fcntl(_thread_kern_pipe[1],
+		    F_DUPFD, 3)) != -1) {
+			close(_thread_kern_pipe[1]);
+			_thread_kern_pipe[1] = dupfd;
+		}
 		/* Zero the global kernel thread structure: */
 		memset(&_thread_kern_thread, 0, sizeof(struct pthread));
 		_thread_kern_thread.flags = PTHREAD_FLAGS_PRIVATE;

--- uthread_fork.c.orig	Wed Jun 26 22:04:09 2002
+++ uthread_fork.c	Thu Jun 27 13:37:45 2002
@@ -43,6 +43,7 @@
 pid_t
 _fork(void)
 {
+	int		dupfd;
 	int             i, flags;
 	pid_t           ret;
 	pthread_t	pthread;
@@ -109,6 +110,18 @@
 			/* Abort this application: */
 			PANIC("Cannot initialize priority ready queue.");
 		} else {
+			if (_thread_kern_pipe[0] < 3 &&
+			    (dupfd = _thread_sys_fcntl(_thread_kern_pipe[0],
+			    F_DUPFD, 3)) != -1) {
+				close(_thread_kern_pipe[0]);
+				_thread_kern_pipe[0] = dupfd;
+			}
+			if (_thread_kern_pipe[1] < 3 &&
+			    (dupfd = _thread_sys_fcntl(_thread_kern_pipe[1],
+			    F_DUPFD, 3)) != -1) {
+				close(_thread_kern_pipe[1]);
+				_thread_kern_pipe[1] = dupfd;
+			}
 			/*
 			 * Enter a loop to remove all threads other than
 			 * the running thread from the thread list:

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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