Bug 150969

Summary: setuid causes unexpected interrupted system call
Product: Red Hat Enterprise Linux 4 Reporter: Rick Stern <rick.stern>
Component: kernelAssignee: Roland McGrath <roland>
Status: CLOSED WONTFIX QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 4.0CC: drepper, mingo, suzanne.pherigo
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-07-21 16:28:54 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
see rest of bug description on how to use this to recreate problem none

Description Rick Stern 2005-03-13 03:30:22 UTC
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:

Comment 1 Rick Stern 2005-03-13 03:30:23 UTC
Created attachment 111931 [details]
see rest of bug description on how to use this to recreate problem

Comment 4 Ray Strode [halfline] 2005-06-15 17:36:54 UTC
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

Comment 12 Roland McGrath 2006-03-02 10:00:42 UTC
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.

Comment 13 Ulrich Drepper 2006-03-02 15:22:59 UTC
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).

Comment 14 Roland McGrath 2006-03-03 03:57:27 UTC
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).

Comment 15 RHEL Program Management 2006-07-21 16:28:54 UTC
Development Management has reviewed and declined this request.  You may appeal this decision by reopening this request.