Bug 631

Summary: sudo consumes full CPU while waiting on child process
Product: Sudo Reporter: Dave Reisner <d>
Component: SudoAssignee: Todd C. Miller <Todd.Miller>
Status: RESOLVED FIXED    
Severity: high CC: evangelos
Priority: low    
Version: 1.8.9   
Hardware: PC   
OS: Linux   
Attachments: Remove backchannel event if we get EOF

Description Dave Reisner 2014-01-14 09:51:53 MST
Since sudo 1.8.9, I'm seeing an entire CPU consumed while sudo waits on the child process to exit. Attaching strace shows that sudo is stuck in a fast loop on poll, i.e.:

poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}], 2, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLHUP}]) <0.000008>
recvfrom(3, "", 8, MSG_WAITALL, NULL, NULL) = 0 <0.000006>
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}], 2, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLHUP}]) <0.000008>
recvfrom(3, "", 8, MSG_WAITALL, NULL, NULL) = 0 <0.000007>
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}], 2, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLHUP}]) <0.000008>
recvfrom(3, "", 8, MSG_WAITALL, NULL, NULL) = 0 <0.000006>
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}], 2, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLHUP}]) <0.000008>
recvfrom(3, "", 8, MSG_WAITALL, NULL, NULL) = 0 <0.000007>
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}], 2, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLHUP}]) <0.000007>
recvfrom(3, "", 8, MSG_WAITALL, NULL, NULL) = 0 <0.000006>
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}], 2, 4294967295) = 1 ([{fd=3, revents=POLLIN|POLLHUP}]) <0.000008>
recvfrom(3, "", 8, MSG_WAITALL, NULL, NULL) = 0 <0.000007>
...etc...

On my system, I can reproduce this with ''sudo -i'' or ''sudo sleep 100''. I've verified that the behavior does NOT exist in 1.8.8, and STILL exists at 1.8.9p3 (which seems to coincide with hg tip). My sudo package is provided by Arch Linux and uses the below configure invocation. We do not apply any patches on top of your source.

./configure \
  --prefix=/usr \
  --sbindir=/usr/bin \
  --libexecdir=/usr/lib \
  --with-logfac=auth \
  --with-pam \
  --with-env-editor \
  --with-passprompt="[sudo] password for %p: " \
  --with-all-insults

A local build with the same configure options and no external compiler flags (CPPFLAGS, CFLAGS, LDFLAGS) yields the same broken behavior.

Please let me know if you need me to provide any other debugging info.
Comment 1 Todd C. Miller 2014-01-14 09:58:04 MST
Confirmed.  This only happens when a pty is not used so a temporary workaround is to add:

Defaults use_pty

to sudoers.  I didn't notice this myself as I always have I/O logging enabled (which allocates a pty).
Comment 2 Todd C. Miller 2014-01-14 12:28:24 MST
Created attachment 393 [details]
Remove backchannel event if we get EOF

I've attached a fix for this but I've also run into a weird problem where I see a short read when EOF is expected on ubuntu 13.04.  I'm investigating this now; it seems only to happen when the file descriptor is dup'd.
Comment 3 Dave Reisner 2014-01-14 12:46:37 MST
Great! I can confirm that your patch resolves my reported issue. I do not, however, see any short reads as you describe, even when enabling log_input and log_output (though it's possible I'm not looking in the correct place).
Comment 4 Todd C. Miller 2014-01-14 18:22:24 MST
You'll only see the other bug if debugging is enabled.
Comment 5 Todd C. Miller 2014-01-15 13:50:29 MST
Sudo 1.8.9p4 is now available which fixes both issues.