Stopping ssh with a logged in user causes init to spin at 100%
Bug #926468 reported by
Jason Conti
This bug affects 1 person
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
upstart |
Fix Released
|
High
|
James Hunt | ||
openssh (Ubuntu) |
Fix Released
|
High
|
Colin Watson | ||
Precise |
Fix Released
|
High
|
Colin Watson | ||
upstart (Ubuntu) |
Fix Released
|
High
|
James Hunt | ||
Precise |
Fix Released
|
High
|
James Hunt |
Bug Description
Steps to reproduce:
1) Boot the machine with --log on the kernel command line
2) Log into the machine through ssh
3) Execute: sudo stop ssh;
4) The init process will spin with EAGAIN on one if its file descriptors
5) Exit the remote ssh session and the service will stop
The process appears to be looping in init/log.
CVE References
summary: |
- Stopping ssh with a logged in user causes init to spin at %100 + Stopping ssh with a logged in user causes init to spin at 100% |
Changed in upstart (Ubuntu): | |
status: | New → Triaged |
importance: | Undecided → High |
Changed in upstart (Ubuntu Precise): | |
assignee: | nobody → James Hunt (jamesodhunt) |
Changed in upstart: | |
assignee: | nobody → James Hunt (jamesodhunt) |
importance: | Undecided → High |
status: | New → Fix Committed |
Changed in upstart: | |
status: | Fix Committed → Fix Released |
To post a comment you must log in.
I think the attached source file, along with a simple upstart conf with: exec /path/to/ test-daemon may be a minimal example of the behavior.
sshd is spawned by upstart with -D so the initial process doesn't daemonize. The upstart logging mechanism will setup a pty for stdout/stderr. When receiving a connection, sshd forks and daemonizes, but looking at /proc/pid/fd/ it appears to omit redirecting stderr to /dev/null, so the pty is still opened on fd 2.
So when the ssh service is stopped, the inital sshd instance run with -D is terminated, but the child sshd keeps running and still has the pty open. Then when upstart flushes the log and waits for the fd to error out in log_read_watch, it loops forever with EAGAIN until the child exits.
I think that is what is going on anyway, and the attached code exhibits similar behavior.