>
> >>>Colin McCormack said:
>
> > Sounds like a fix is needed in pthreads, and I'm the man to hassle 'em
>
> Cool!
>
> > First Q is what behavior would one reasonably expect? This surely can't be
> > happening only in tcl - any thread which changes its uid would break the
> > pthreads lib? Or is it some choice tcl implementation makes (in which case,
>
> > it should suffice to change setuid.so to have the non-cooperative threads
> > setuid at the same time as the child.)
Ok, I've looked into this, and it appears pretty bleak.
Near as I can tell so far, the reason for the problem is that Linux threads
uses signals to synchronise threads with one another (which is a terrible
choice, imho - signals were never designed to carry that kind of
responsibility.)
Nett result is that, having changed UID, a thread can no longer signal another
thread whose UID differs, can no longer communicate with the other threads,
and the whole thing hangs.
> Well, it certainly affected AOLserver, a C server application that embeds Tcl.
> But, all the socket handling is done outside of Tcl in AOLserver, so the
> problems are generic.
>
> > > Its rather complex to fix this, although it has been done for AOLserver
> > > using a separate "binding" thread that listens on privileged ports.
> >
> > Gack. Privileged ports. So it *has* to run as root. Not a good choice, IM
> HO.
>
> The dance goes something like this.
> AOLserver starts with a command line argument specifying a uid.
> It forks a process to wait on its various listening sockets.
> The main process does a setuid.
> Connections are accepted on the listening socket
> and dispatched to connection threads.
>
> You have to do this before initializing Tcl, because it
> starts a thread during initialization
> (when compiled with TCL_THREADS enabled).
>
> I'm not fully clear on how the binding and accepting is done.
> I do know that AOLserver forks a process very early, before
> doing the setuid(), and this "binder" process opens the
> listening socket. Then, either it also accepts connections
> and then passes those sockets to the original server, or
> it passes the listening socket back to the original server.
> The socket passing is done via an ability to pass file descriptors
> over sockets on Unix.
>
> Anyway, its all rather complex. What TclHttpd would simply like to do is:
> 1) run tclsh that doesn't know about setuid.
> 2) open the listening socket
> 3) do the setuid
This is a problem, because (here's the backtrace ...
#0 __pthread_create_2_1 (thread=0x400a91d4, attr=0xbffff188,
start_routine=0x40088434 <NotifierThreadProc>, arg=0x0) at pthread.c:475
#1 0x4008772a in Tcl_CreateThread (idPtr=0x400a91d4, proc=0x40088434
<NotifierThreadProc>, clientData=0x0, stackSize=0, flags=0) at
./../unix/tclUnixThrd.c:119
#2 0x40087c6c in Tcl_InitNotifier () at ./../unix/tclUnixNotfy.c:210
#3 0x4006aa87 in TclInitNotifier () at ./../generic/tclNotify.c:119
#4 0x4004ed5b in TclInitSubsystems (argv0=0xbffffb09
"/home/colin/Desktop/Software/tclwork/tcl8.4/unix/tclshDBG") at
./../generic/tclEvent.c:717
#5 0x4004c2d4 in Tcl_FindExecutable (argv0=0xbffffb09
"/home/colin/Desktop/Software/tclwork/tcl8.4/unix/tclshDBG") at
./../generic/tclEncoding.c:1108
#6 0x40067324 in Tcl_Main (argc=1, argv=0xbffff9d4, appInitProc=0x8048740
<Tcl_AppInit>) at ./../generic/tclMain.c:133
#7 0x8048737 in main (argc=1, argv=0xbffff9d4) at ./../unix/tclAppInit.c:99
)
an initial thread is created before the tcl Notifier is created, and so there's no
possibility (that I can see) of opening a port before the threading starts (no
notifier means, I presume, no accept is possible.)
So the suggestion of letting tcl interpret a -u uid command line option, while not a
bad thing, wouldn't help in solving this problem.
What might help is allowing tcl to start with an already-accepting port, and somehow
connect a script to that after notifier, and after the -u uid processing.
It's all horribly complex, and it's all kludgy work-around for the basic problem:
linuxthreads implementors chose a too-weak interprocess synchronisation primitive
(signal) to support their intended threading model (posix threads.)
I'm currently looking for the person nominally responsible for this decision, to see
what can be done about it.
Colin.