Description of problem: setuid causes unexpected interrupted system call application is running as root Have a sample program that demonstrates problem The program is pretty simple. It creates five threads and executes a select in each. It waits for data for 5 seconds then times out. The main program then issue a setuid() to the same uid its running (using getuid() for this). On rh3 the results are what we would expect: RH3: [root@hpq8 tmp]# ./threads Using thread stack size: 131072 Realtime prios: max 94, high 47, low 1 Timeshare prios: max 0, min 0 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Ready to issue a setuid for uid(0) No data within five seconds. No data within five seconds. No data within five seconds. No data within five seconds. No data within five seconds. # On RH4: [root@hpq7 tmp]# ./threads Using thread stack size: 131072 Realtime prios: max 94, high 47, low 1 Timeshare prios: max 0, min 0 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Using thread stack size: 131072 Ready to issue a setuid for uid(0) select(): Interrupted system call select(): Interrupted system call select(): Interrupted system call select(): Interrupted system call select(): Interrupted system call [root@hpq7 tmp]# Program is built the same on each node: cc threads.c -o threads -lpthread Same results on either ipf or ia32 Iie good results on rh3/sles, bad on rh4). I have not tried is on x86_64 yet since I don't have type architeture build system yet but based on all of this I would not expect it to be different. Version-Release number of selected component (if applicable): How reproducible: VERY Steps to Reproduce: 1. run attached program 2. 3. Actual results: Expected results: Additional info:
Created attachment 111931 [details] see rest of bug description on how to use this to recreate problem
Hi Rick, My guess is that you meant to file this bug against glibc, not glib. I'm going to reassign it. I think the behavior change is probably a result of kernel changes and not libc changes, however, so I'm going to reassign to the kernel component
I took a look at current upstream sources, and it looks like select and poll will both return EINTR. In sys_select there is an obscure comment about some application breaking when -ERESTARTSYS was, which makes the SA_RESTART machinery work right. ERESTARTNOHAND should probably be used only for pause and sigsuspend. However, it is not entirely clear what to expect from these functions, that have timeouts. If simple restarting is done, it restarts the full timeout after losing track of how much time passed before the signal, and could potentially restart from more signals and never time out even though the period has long past. This is probably the behavior that gave applications trouble. I cannot find it very clearly stated in the standard what SA_RESTART has to mean for timeouts. Notably, pselect is specified differently such that it's implementation-defined whether SA_RESTART affects it or it always returns EINTR. The nanosleep and clock_nanosleep interfaces are specifically designed to make it easy to restart properly without timeout inflation, but AFAICT the standard is not explicit about select and poll. I think it is worth pursuing a definitive answer about what the SA_RESTART behavior of select and poll should be. If they restarted, then the problem is covered; that needs to be resolved upstream, and even so such a change may be beyond the scope of RHEL4. If it's instead decided that they unavoidably will just fail with EINTR after a signal handler, then the fact that setuid causes signal interruption behavior because of its internal signal, is a WONTFIX for RHEL4.
The interpretations made in the POSIX working group are clear: if a function with a timeout is restarted, the new tiemout value can be any value between the original full timeout value and the correct value with the time which passed already deducted. Therefore restarting the syscall with the full timeout value is correct. See XSH ERN 126 in http://www.opengroup.org/austin/aardvark/latest/xshbug2.txt (the URL will go away over time).
If the wording in ERN 126 is adopted, it seems to say that the behavior is unspecified, as well as saying that if the timeout restarts the duration of the timeout is unspecified. So if the "behavior and" wording is left in, I think it allows the EINTR behavior, which is the current Linux behavior (the complete wording in ERN 126 is quite awkward and unclear, in fact).
Development Management has reviewed and declined this request. You may appeal this decision by reopening this request.