libvirt/tests/commanddata
Eric Blake 858c2476d9 command: avoid deadlock on EPIPE situation
It is possible to deadlock libvirt by having a domain with XML
longer than PIPE_BUF, and by writing a hook script that closes
stdin early.  This is because libvirt was keeping a copy of the
child's stdin read fd open, which means the write fd in the
parent will never see EPIPE (remember, libvirt should always be
run with SIGPIPE ignored, so we should never get a SIGPIPE signal).
Since there is no error, libvirt blocks waiting for a write to
complete, even though the only reader is also libvirt.  The
solution is to ensure that only the child can act as a reader
before the parent does any writes; and then dealing with the
fallout of dealing with EPIPE.

Thankfully, this is not a security hole - since the only way to
trigger the deadlock is to install a custom hook script, anyone
that already has privileges to install a hook script already has
privileges to do any number of other equally disruptive things
to libvirt; it would only be a security hole if an unprivileged
user could install a hook script to DoS a privileged user.

* src/util/command.c (virCommandRun): Close parent's copy of child
read fd earlier.
(virCommandProcessIO): Don't let EPIPE be fatal; the child may
be done parsing input.
* tests/commandhelper.c (main): Set up a SIGPIPE situation.
* tests/commandtest.c (test20): Trigger it.
* tests/commanddata/test20.log: New file.
2012-06-04 13:06:07 -06:00
..
test2.log
test3.log
test4.log
test5.log
test6.log
test7.log
test8.log
test9.log command: handle empty buffer argument correctly 2011-12-03 15:55:46 -07:00
test10.log
test11.log
test12.log
test13.log
test14.log
test15.log
test16.log freebsd: Avoid /bin/true in commandtest 2011-07-29 12:12:58 +02:00
test20.log command: avoid deadlock on EPIPE situation 2012-06-04 13:06:07 -06:00