<?xml version="1.0" encoding="UTF-8" ?>

<bugzilla version="5.2"
          urlbase="https://bugzilla.altlinux.org/"
          
          maintainer="jenya@basealt.ru"
>

    <bug>
          <bug_id>24657</bug_id>
          
          <creation_ts>2010-11-28 13:33:55 +0300</creation_ts>
          <short_desc>CPU-eating loop when stdin pipe is closed</short_desc>
          <delta_ts>2010-12-09 20:11:45 +0300</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>4</classification_id>
          <classification>Development</classification>
          <product>Sisyphus</product>
          <component>netcat</component>
          <version>unstable</version>
          <rep_platform>all</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P3</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Sergey Vlasov">vsu</reporter>
          <assigned_to name="placeholder@altlinux.org">placeholder</assigned_to>
          <cc>glebfm</cc>
    
    <cc>ldv</cc>
    
    <cc>placeholder</cc>
    
    <cc>rider</cc>
    
    <cc>stanv</cc>
    
    <cc>vt</cc>
          
          <qa_contact>qa-sisyphus</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>115805</commentid>
    <comment_count>0</comment_count>
    <who name="Sergey Vlasov">vsu</who>
    <bug_when>2010-11-28 13:33:55 +0300</bug_when>
    <thetext>netcat-4.0.20100420-alt1

В случае, если в качестве stdin передаётся pipe, и затем все дескрипторы для записи закрываются, netcat зацикливается, пока не будет закрыто сетевое соединение:

17160 poll([{fd=3, events=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLHUP}])
17160 poll([{fd=3, events=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLHUP}])
17160 poll([{fd=3, events=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 1 ([{fd=0, revents=POLLHUP}])
... (при отсутствии активности сетевого соединения продолжается бесконечно)
(после закрытия сокета с другой стороны)
17160 poll([{fd=3, events=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 2 ([{fd=3, revents=POLLIN}, {fd=0, revents=POLLHUP}])
17160 read(3, &quot;&quot;, 2048)                 = 0
17160 shutdown(3, 0 /* receive */)      = 0
17160 close(3)                          = 0
17160 exit_group(0)                     = ?

Наблюдать это можно, например, при использовании ssh $host nc 127.0.0.1 $port; после этого нормальное закрытие входного потока ssh приводит к зацикливанию nc, причём данные в противоположном направлении в этом состоянии продолжают проходить.  Такой вызов nc через ssh используется в libvirt (virt-manager, virt-viewer) для соединения с VNC-сервером qemu при подключении qemu+ssh://, в результате на сервере остаются висеть процессы nc, потребляющие процессорное время. (Для основного соединения с сокетом libvirtd в нормальной ситуации эта проблема не наблюдается из-за наличия в протоколе явной команды закрытия соединения, в результате nc завершает работу при закрытии сокета со стороны libvirtd.)

В Linux для pipe или fifo в случае, если все дескрипторы для записи закрыты, и при этом в буфере нет данных, poll() возвращает для дескриптора чтения флаг POLLHUP без установки флага POLLIN; однако netcat не проверяет флаг POLLHUP - видимо, поведение ядра OpenBSD в такой ситуации отличается от Linux (похоже, там по EOF выставляется и POLLIN|POLLRDNORM).

В Fedora подобная проблема была починена ещё в 2005 году:

https://bugzilla.redhat.com/show_bug.cgi?id=156835

В январе 2010 года была попытка протолкнуть в апстрим патчи, среди которых был и чинящий обработку POLLHUP, но ответа не последовало:

http://kerneltrap.org/mailarchive/openbsd-tech/2010/1/12/6700583
http://jzeleny.fedorapeople.org/patches/nc/01-pollhup.patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>115810</commentid>
    <comment_count>1</comment_count>
    <who name="Andriy Stepanov (stanv)">stanv</who>
    <bug_when>2010-11-28 14:18:06 +0300</bug_when>
    <thetext>PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                              
27097 stanv     20   0  8556  724  596 R 99.7  0.0   0:06.36 nc                                    
27080 stanv     20   0  6324  456  356 R 92.1  0.0   0:05.92 nc</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>115919</commentid>
    <comment_count>2</comment_count>
    <who name="Anton Farygin">rider</who>
    <bug_when>2010-12-02 12:27:29 +0300</bug_when>
    <thetext>Дима, очень нужно исправление этой ошибки.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>116209</commentid>
    <comment_count>3</comment_count>
    <who name="Repository Robot">repository-robot</who>
    <bug_when>2010-12-09 20:11:45 +0300</bug_when>
    <thetext>netcat-4.0.20100725-alt1 -&gt; sisyphus:

* Thu Dec 09 2010 Dmitry V. Levin &lt;ldv@altlinux&gt; 4.0.20100725-alt1
- Updated to 20100725 snapshot.
- Imported a POLLHUP detection patch by Jan Zeleny (closes: #24657).</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>